JQuery滚动事件冻结了页面

时间:2015-11-18 08:38:42

标签: javascript jquery scroll viewport

我设置了一个触发器,用于检查元素是否在视口中(在屏幕上可见)并将其添加到scroll事件中。这在某些页面上工作正常,但是大页面会冻结页面。在firefox上我根本无法滚动,它完全崩溃了页面并且出现警告告诉我jquery没有响应。继承人:

 $(window).on("scroll", function () {
     $('div').each(function () {
         if ($(this).isOnScreen(true)) {
             $(this).trigger('report.appear');
         }
     });
 });

并且继承了isOnScreen函数(找出视口中的元素):

$.fn.isOnScreen = function () {
     var win = $(window);
     var viewport = {
         top: win.scrollTop(),
         left: win.scrollLeft()
     };
     viewport.right = viewport.left + win.width();
     viewport.bottom = viewport.top + win.height();

     var bounds = this.offset();
     bounds.right = bounds.left + this.outerWidth();
     bounds.bottom = bounds.top + this.outerHeight();

     return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
 };

页面上有多少div元素并不重要,它似乎只是大量崩溃它的任何内容,或者至少是我拥有的大型HTML表格。是否有另一种方法可以检测元素何时出现在屏幕上而不使用滚动事件?或者有没有办法使用滚动而不会崩溃jquery?

更新:

当我发表评论时:

 $(window).on("scroll", function () {
     $('div').each(function () {
         /*
        if ($(this).isOnScreen(true)) {
            $(this).trigger('report.appear');
        }
        */
     });
 });

它工作正常,因此isOnScreen函数导致问题。有没有更好的方法来做这个不会像这样重载浏览器?

2 个答案:

答案 0 :(得分:2)

MDN: scroll

  

由于滚动事件可以以高速率触发,因此事件处理程序不应执行计算上昂贵的操作,例如DOM修改。相反,建议使用requestAnimationFrame,setTimeout或customEvent来限制事件,如下所示:

;(function() {
    var throttle = function(type, name, obj) {
        obj = obj || window;
        var running = false;
        var func = function() {
            if (running) { return; }
            running = true;
            requestAnimationFrame(function() {
                obj.dispatchEvent(new CustomEvent(name));
                running = false;
            });
        };
        obj.addEventListener(type, func);
    };

    /* init - you can init any event */
    throttle ("scroll", "optimizedScroll");
})();

// handle event
window.addEventListener("optimizedScroll", function() {
    console.log("Resource conscious scroll callback!");
});

答案 1 :(得分:0)

我专门为此编写了一个插件:jQuery.isInView。它旨在处理大量元素和大量调用。 (并且它已经过测试。)那应该为你完成工作。

除此之外,你绝对是should throttle the scroll event。即使浏览器没有砖块,你也会在手机上吸干电池。如果您想使用现有的经过验证的解决方案,我建议_.throttle库中的Underscore。 Ben Alman也有一个确定的$.throttle。 {@ 3}}在@ t.niese的回答中发布,肯定也能完成这项工作。