【问题标题】:debug SLOW jQuery code调试 SLOW jQuery 代码
【发布时间】:2013-10-04 23:25:57
【问题描述】:

我有以下 jQuery 代码,用于根据选项是否具有 active=F 或 active=T 自定义属性来隐藏/显示选项。 It works great, however when the select contains a lot of options, it takes 10 seconds or more sometimes to finish and causes the page to lock up.有人能指点我如何优化这段代码吗?

        $(document).ready(function() {
        $.fn.toggleOption = function( show ) {
            return this.each(function(){
                $(this).toggle(show);
                if(show){
                    if($(this).parent('span.toggleOption').length) $(this).unwrap();
                    $('#unitsSelector').val(""); 
                } else {
                    $(this).wrap('<span class="toggleOption" style="display: none;" />');
                    $('#unitsSelector').val("");
                }
            });
        };
        var list = $('#unitsSelector option'), buttons = $('.unitToggle');
        list.toggleOption(false);
        buttons.on('click', function () {
            var filter = $(this).hasClass('active') ? "[active=F]" : "[active=T]";
            list.toggleOption(true).filter(filter).toggleOption(false);
        });
        $('.active').click();
    });

谢谢!!!

更新

这里有小提琴

http://jsfiddle.net/L94Bz/

您会注意到,当从活动/非活动切换时,需要几秒钟才能完成。

【问题讨论】:

  • 我对这个问题的答案很感兴趣。我有一个类似的问题,模糊 5 个输入字段,大约需要 3 秒!你试过 e.stopPropagation();顺便一提?会冒泡吗?
  • 我没试过e.stopPropagation(),不熟悉。不过现在正在调查。
  • 您的意思是除了在同一个函数中调用$(this) 4 次,而不是将其存储为局部变量并重新使用它?
  • 你能设置一个可重现的小提琴示例吗?
  • @Phil 试一试...我删除了包装/展开,但选项隐藏和显示,而且速度要快得多。 jsfiddle.net/MTn8p

标签: javascript jquery optimization


【解决方案1】:

首先,您需要将这些 $(...) 调用缓存在变量中。


$(document).ready(function () {

    var list = $('#unitsSelector option'),
        unitsSelector = $('#unitsSelector');

    $.fn.toggleOption = function (show) {
        return this.each(function () {
            var $this = $(this);

            $this.toggle(show);

            if (show && $this.parent('span.toggleOption').length) {
                $this.unwrap();
            } else {
                $this.wrap('<span class="toggleOption" style="display: none;" />');
            }

            unitsSelector.val("");
        });
    };

    list.toggleOption(false);

    $('.unitToggle').on('click', function () {
        var filter = $(this).hasClass('active') ? "[active=F]" : "[active=T]";
        list.toggleOption(true).filter(filter).toggleOption(false);
    });

    $('.active').click();

});

您还应该通过jQuery 使用event delegation

如果我知道你的 html,或者有一个可行的小提琴示例,我可以为你提供更多帮助。

【讨论】:

  • @JoeSimmons,有没有机会举一个简短的例子来说明我如何应用事件委托?我对它完全陌生。
  • 最后的链接中的示例。
【解决方案2】:

一个快速修复:在整个循环中停止重新运行 jQuery 构造函数。每次你说$(#unitsSelector) 之类的东西,都是在幕后进行。

$.fn.toggleOption = function( show ) {
  var $units = $('#unitsSelector'); 

  return this.each(function(){
    var $this = $(this);
    $this.toggle(show);
    if(show){
      if($this.parent('span.toggleOption').length) $this.unwrap();
      $units.val(""); 
    } else {
      $this.wrap('<span class="toggleOption" style="display: none;" />');
      $units.val("");
    }
  });
};

【讨论】:

  • 实际上,jQuery 选择器被大量缓存,足够智能,不会在循环中重新选择。
  • 当(如此处)在循环期间进行 dom 修改时,并不总是如此。
猜你喜欢
  • 2013-07-31
  • 2011-10-29
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多