在循环内附加事件处理程序时浏览器性能有问题

Problematic browser performance when attaching event handler inside loop

我在创建插件时遇到问题。为变量 width.

设置新值时出现问题

width 变量需要重新计算,如果用户调整他的浏览器。 如果我在循环内附加 resize 事件,它会使 性能出现问题 。 我想出了创建 closure 函数来包装所有代码的想法。所以,当用户调整他的浏览器大小时,我再次调用这个函数。

JS :

var self         = this,
    onScrollbarY = function() {
        self.each(function() {  // loop it
            var el           = $(this),
                elLog        = el.find(".scrollbarYLog"),
                width        = $(window).innerWidth(),    // this value will change based on users browser width
                onMouseOver  = function() {
                    elLog.html(width);
                };
            elLog.on("mouseover", onMouseOver);
        });
    };
onScrollbarY(); // call it immediatly

$(window).on("resize", onScrollbarY); // if users resize its browser, call it again for getting new browser width

这是正确的实现方式吗?还是有比重新附加所有代码更有效的其他选项?

您首先遇到性能问题的原因是每次调用 .on('resize', ...) 时,您都注册了一个在该事件上运行的函数。所以在 5 个 resize 事件之后,你每次都会调用 5 个函数,这就是导致速度变慢的原因。

有两种方法可以解决这个问题:

  1. 只将一个处理程序附加到该事件(你最终做了什么);或
  2. 使用 .one('resize', ...) 事件处理程序注册一个函数,该函数只会在第一个下一个 resize 事件上触发。

用例 #1 是大多数开发人员使用和推荐的。您创建一个函数(如您的 onScrollbarY)并使用 .on() 注册该函数,从您注册它的那一刻起,每次 resize 事件发生时都会调用该函数。

情况 #2 非常罕见,您可能不想使用 .one(),除非您只想处理该事件的第一次出现,然后再处理 none。如果您想处理多个,则必须在事件发生后再次调用 .one() 以告诉它再次侦听该事件。

编辑: 您可以将代码简化为以下内容:

var $window  = $(window),
    width    = $window.innerWidth(), // we know the initial width
    $elLog   = $(".scrollbarYLog"),  // we find the scrollbar element
    onResize = function() {
      width = $window.innerWidth();
    },
    onMouseOver = function() {
      $elLog.html(width);
    };

// register the resize function with the "resize" event
$window.on("resize", onResize);
// register the mouseover function with the "mouseover" event on the scrollbar
$elLog.on("mouseover", onMouseOver);

// there is no need to call onResize(), as we've already set the width variable