【问题标题】:JQuery: My 'scroll' event is CRAZY slow. What am I doing wrong?JQuery:我的“滚动”事件非常慢。我究竟做错了什么?
【发布时间】:2010-01-28 21:55:12
【问题描述】:

我有 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 中实现了计时器选项,它仍然很慢。还有其他想法吗?

【问题讨论】:

  • 我可以看到该代码没有任何问题。尝试仅使用这 4 个 div、jquery.js 和您的滚动功能创建一个空白页面,以查看页面中是否有其他内容导致速度变慢。滚动时不要 alert()。
  • 你真的每次滚动都在提醒吗?
  • @petersendidit,不 - 这只是填充代码

标签: jquery javascript micro-optimization


【解决方案1】:

在 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')

【讨论】:

  • 嗨 Chetan,我正在查看链接页面上的代码。有道理,因为上面的代码多次触发;但是,我不知道如何实现这一点。我尝试了几种不同的方法,并且奏效了。你介意试一试吗?
  • _timer 变量在哪里定义?
  • 已更正。它应该是计时器(不带下划线)
  • @Chetan,我已经实现了上面的代码。它仍然一样慢。所以我将延迟提高到 5000(比你原来的延迟多 100 倍),但它仍然很慢。还有其他建议吗?
  • newHighlightDiv.hasClass("HighlightRow") 似乎有了很大的改善。
猜你喜欢
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 2021-07-17
  • 1970-01-01
  • 2019-12-23
相关资源
最近更新 更多