Livequery 和 each()

Posted

技术标签:

【中文标题】Livequery 和 each()【英文标题】:Livequery and each() 【发布时间】:2011-08-18 20:11:53 【问题描述】:

我有一个 .each() 循环在所有匹配的元素上做一些事情。但我也有办法添加这些元素....我试图让 livequery 意识到已经添加了一个新元素并通过相同的每个循环运行它。

这是一个一般设置: http://jsfiddle.net/CUURF/1/

基本上,我如何将 livequery 和 each 一起使用?

最终我可以在元框中动态添加 tinymce 编辑器文本框,但我相当确定问题是我的 ID 在添加/克隆时不会自动递增,因为新元素不在 DOM 中每个循环。

编辑-我认为最重要的是我需要标准的带有 .each 的索引计数器才能使用 livequery 工作?

edit- 这是 wpalchemy 中用于循环/克隆的代码

/* <![CDATA[ */
        jQuery(function($)
        
            $(document).click(function(e)
                   
                var elem = $(e.target);

                if (elem.attr('class') && elem.filter('[class*=dodelete]').length)
                
                    e.preventDefault();

                    var p = elem.parents('.postbox'); /*wp*/

                    var the_name = elem.attr('class').match(/dodelete-([a-zA-Z0-9_-]*)/i);

                    the_name = (the_name && the_name[1]) ? the_name[1] : null ;

                    /* todo: expose and allow editing of this message */
                    if (confirm('This action can not be undone, are you sure?'))
                    
                        if (the_name)
                        
                            $('.wpa_group-'+ the_name, p).not('.tocopy').remove();
                        
                        else
                        
                            elem.parents('.wpa_group').remove();
                        

                        the_name = elem.parents('.wpa_group').attr('class').match(/wpa_group-([a-zA-Z0-9_-]*)/i)[1];

                        checkLoopLimit(the_name);

                        $.wpalchemy.trigger('wpa_delete');
                    
                
            );

            $('[class*=docopy-]').click(function(e)
            
                e.preventDefault();

                var p = $(this).parents('.postbox'); /*wp*/

                var the_name = $(this).attr('class').match(/docopy-([a-zA-Z0-9_-]*)/i)[1];

                var the_group = $('.wpa_group-'+ the_name +':first.tocopy', p);

                var the_clone = the_group.clone().removeClass('tocopy');

                var the_props = ['name', 'id', 'for'];

                the_group.find('input, textarea, select, button, label').each(function(i,elem)
                
                    for (var j = 0; j < the_props.length; j++)
                    
                        var the_prop = $(elem).attr(the_props[j]);

                        if (the_prop)
                        
                            var the_match = the_prop.match(/\[(\d+)\]/i);

                            if (the_match)
                            
                                the_prop = the_prop.replace(the_match[0],'['+(+the_match[1]+1)+']');

                                $(elem).attr(the_props[j], the_prop);
                            
                        
                    
                );

                if ($(this).hasClass('ontop'))
                
                    $('.wpa_group-'+ the_name +':first', p).before(the_clone);
                
                else
                
                    the_group.before(the_clone);
                

                checkLoopLimit(the_name);

                $.wpalchemy.trigger('wpa_copy', [the_clone]);
            );

            function checkLoopLimit(name)
            
                var elem = $('.docopy-' + name);

                var the_match = $('.wpa_loop-' + name).attr('class').match(/wpa_loop_limit-([0-9]*)/i);

                if (the_match)
                
                    var the_limit = the_match[1];

                    if ($('.wpa_group-' + name).not('.wpa_group.tocopy').length >= the_limit)
                    
                        elem.hide();
                    
                    else
                    
                        elem.show();
                    
                
            

            /* do an initial limit check, show or hide buttons */
            $('[class*=docopy-]').each(function()
            
                var the_name = $(this).attr('class').match(/docopy-([a-zA-Z0-9_-]*)/i)[1];

                checkLoopLimit(the_name);
            );
        );
        /* ]]> */
        </script> 

以及我的元框内的标记:

<div id="testimonials"> 

    <h2>Testimonials</h2> 

    <a style="float:right; margin:0 10px;" href="#" class="dodelete-testimonials button"><span class="icon delete"></span>Remove All</a> 


        <div id="wpa_loop-testimonials" class="wpa_loop wpa_loop-testimonials"><div class="wpa_group wpa_group-testimonials first">   



        <a href="#" class="dodelete button"><span class="icon delete"></span>Remove</a> 

      <div class="slide_preview"> 
                <div class="preview_wrap"> 
        <img class="preview" src=""  /> 
        </div> 
        <input type="hidden" name="_sidebar_meta[testimonials][0][testimonial_image]" value="" class="img_src" /> 


                <input type="hidden" name="_sidebar_meta[testimonials][0][slide_image_alt]" value="" class="img_alt" /> 


        <button class="upload_image_button button" type="button"><span class="icon upload"></span>Change Photo</button> 

      </div> 

      <div class="slide_text"> 

        <label>About Testimonial</label> 
        <div class="customEditor minimal"> 
                <textarea rows="5" cols="50" name="_sidebar_meta[testimonials][0][testimonial_desc]">I realized it was ME causing all the problems</textarea> 
        </div> 
      </div> 


    </div>      <div class="wpa_group wpa_group-testimonials last tocopy">    

    <h3 class="slide">Testimonial Name:     
            <input type="text" name="_sidebar_meta[testimonials][1][testimonial_name]" value=""  /> 
    </h3> 

        <a href="#" class="dodelete button"><span class="icon delete"></span>Remove</a> 

      <div class="slide_preview"> 
                <div class="preview_wrap"> 
        <img class="preview" src="http://localhost/multi/wp-content/themes/callingintheone/functions/WPAlchemy/images/default_preview.png"  /> 
        </div> 
        <input type="hidden" name="_sidebar_meta[testimonials][1][testimonial_image]" value="" class="img_src" /> 


                <input type="hidden" name="_sidebar_meta[testimonials][1][slide_image_alt]" value="" class="img_alt" /> 


        <button class="upload_image_button button" type="button"><span class="icon upload"></span>Upload Photo</button> 

      </div> 

      <div class="slide_text"> 

        <label>About Testimonial</label> 
        <div class="customEditor minimal"> 
                <textarea rows="5" cols="50" name="_sidebar_meta[testimonials][1][testimonial_desc]"></textarea> 
        </div> 
      </div> 


    </div></div>     
    <p style="margin-bottom:15px; padding-top:5px;"><a href="#" class="docopy-testimonials button"><span class="icon add"></span>Add Testimonial</a></p>    

</div>

.tocopy 类被炼金术代码转移到一个新的隐藏(通过 CSS)和最后一个元素

【问题讨论】:

您使用的是哪个版本的 jQuery?我相信从 1.3 开始,现在内置了现场活动:jQuery live() 1.5.我的印象是 live 只绑定到点击、提交等,并且只是新匹配元素的“外观”不会触发它——这就是我去 livequery 的原因。 你这样做的效率不是很高。我很快就会发布一个更有效的方法。 哈哈。从来没有声称我是。 :) 期待你的帖子。 我会在今天某个时候查看更新,伙计。 【参考方案1】:

您的问题是每个都没有通过点击执行。之后就没有什么可以让它运行了。

fixed code

【讨论】:

谢谢,但我还需要在点击之前运行代码... b/c 我需要现有的 textarea 来获得分配的 ID。 在运行时添加 id - $(this).attr('id',i) 但是在他点击之前,现有的 textareas 不会有 id。【参考方案2】:

回答:http://jsfiddle.net/morrison/CUURF/6/

注意事项:

不使用 livequery。 在这种情况下不需要。 跟踪数组中的现有编辑器。这比每次需要编辑器时都在 DOM 中循环要快。 DOM 的东西很慢,数组很快。这也让您可以轻松访问任何或所有编辑器来执行您可能做的其他事情。 在创建新编辑器时不循环。它只是将新编辑器的 id 修改为最后一个加 1。这是一个巨大的性能提升。

【讨论】:

超级整洁!谢谢你,我从没想过你可以在没有 livequery 的情况下做到这一点。绝对解决了我所描述的问题。但是,我在调整它时遇到的问题是我正在使用 WP_alchemy 类来构建元框,并且 IT 处理元素的克隆——所以我不能以同样的方式完全挂钩单击/克隆事件。更不用说最终我需要 tinymce 来加载新的文本区域。 我看不出这有什么问题。也许您可以更新您的原始帖子以包含针对您特定情况的代码?

以上是关于Livequery 和 each()的主要内容,如果未能解决你的问题,请参考以下文章

$.each(selector) 和 $(selector).each() 有啥区别

JQuery中$.each 和$(selector).each()的区别详解

jquery $().each和$.each()

$().each和$.each()的区别

$(selector).each() 和$each() 的区别

$.each和$().each