JQuery:我的'滚动'事件很慢。我究竟做错了什么?

时间:2010-01-28 21:55:12

标签: jquery javascript micro-optimization

我有4个DIV,当你滚动其中一个div时,我希望触发scroll事件。这是下面的代码。

$('#div1, #div2, #div3, #div4').scroll(function() {
    alert('...');
});

在Firefox / Chrome中,运行速度很快;但是,在Internet Explorer中,它运行速度很慢,实际上阻止了我滚动div。

我正在使用最新版本的JQuery(v.1.4.1)。

问题:运行上面的代码有更有效的方法吗?如果是这样,怎么样?

更新:自从被问到以来,我已经在我的整个代码中包含了以下内容:

$('#div1, #div2, #div3, #div4').scroll(function() {
   /* find the closest (hlisting) home listing to the middle of the scrollwindow */ 
    var scrollElemPos = activeHomeDiv.offset();
    var newHighlightDiv = $(document.elementFromPoint(
        scrollElemPos.left + activeHomeDiv.width()  / 2,
        scrollElemPos.top  + activeHomeDiv.height() / 2)
    ).closest('.hlisting');
    if(newHighlightDiv.is(".HighlightRow")) return;
    $('.HighlightRow').removeClass("HighlightRow");
    newHighlightDiv.addClass('HighlightRow');

   /* change the map marker icon to denote the currently focused on home */
   var activeHomeID = newHighlightDiv.attr("id");
   if (activeHomeMarkerID) {
      // unset the old active house marker to a normal icon
      map.markers[activeHomeMarkerID].setIcon('http://example.com/images/house-icon.png');
   }
   activeHomeMarkerID = activeHomeID.substring(4); // set the new active marker id
   map.markers[activeHomeMarkerID].setIcon('http://example.com/images/house-icon-active.png');     
});

更新2:

所以我在下面和IE中实现了计时器选项,它仍然一样慢。还有其他想法吗?

1 个答案:

答案 0 :(得分:6)

在IE中,滚动事件比在Firefox中更频繁地调度。您正在事件处理程序中执行许多DOM操作,使其运行得更慢。

当用户停止或暂时停止滚动时,请考虑执行所有这些操作。这是一篇关于如何实现这种技术的文章 - http://ajaxian.com/archives/delaying-javascript-execution

修改:这是一个实现

var timer = 0,
    delay = 50; //you can tweak this value
var handler = function() {
    timer = 0;
    //all the stuff in your current scroll function
}

$('#div1, #div2, #div3, #div4').scroll(function() {
    if (timer) {
        clearTimeout(timer);
        timer = 0;
    }
    timer = setTimeout(handler, delay);
});

编辑2 : 你可以附上一个探查器(比如IE8探查器),看看运行缓慢吗?你的DOM有多复杂?

以下是一些提高代码性能的建议:

  1. 你真的需要每次都测量activeHomeDiv.offset()吗?你可以测量一次并将其存放在某个地方(如果位置没有变化)吗?测量大小会导致浏览器重绘。
  2. newHighlightDiv.is(".HighlightRow")更改为newHighlightDiv.hasClass("HighlightRow")
  3. $('.HighlightRow').removeClass("HighlightRow") - 添加元素前缀并从id选择器/元素引用中下拉,例如$('div.HighlightRow', '#ancestorDiv')