1

我有以下 jQuery 函数,它应该检测元素何时首次滚动到页面上的视图中:

function isScrolledIntoView(elem) {
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

我今天脑子很乱……我该如何使用这个功能?

假设我想检测何时$('.guardrail360')进入视野。

4

3 回答 3

2

有几种方法可以做到这一点。window.scroll如果您关心用户体验和/或性能,请不要使用幼稚的实现。

将处理程序附加到窗口滚动事件是一个非常非常糟糕的主意。根据浏览器的不同,滚动事件可能会触发很多,并且将代码放入滚动回调中会减慢滚动页面的任何尝试(不是一个好主意)。因此,滚动处理程序中的任何性能下降只会使整体滚动性能更加复杂。相反,最好使用某种形式的计时器每 X 毫秒检查一次,或者附加一个滚动事件,并且只在延迟后(或者甚至在给定数量的执行之后 - 然后延迟)运行您的代码。

-John Resig,jQuery 的创建者,在ejohn.org

方法一:setInterval

首先,有一种使用计时器的简单方法:

var $el = $('.guardrail360');

var timer = setInterval(function() {
    if (isScrolledIntoView($el)) {
        // do stuff

        // to run this block only once, simply uncomment the next line:
        //clearInterval(timer);
    }
}, 150);

方法二:window.scroll 事件

然后是使用滚动事件的琐碎但疯狂的低效方式(取决于浏览器,滚动事件每秒会触发数百次,所以你不想在这里运行很多代码,尤其是不触发的代码浏览器重排/重绘)。

曾经访问过一个向下滚动页面感觉迟缓和紧张的网站?这通常是由如下一段代码引起的:

var $el = $('.guardrail360');

$(window).on('scroll', function() {
    if (isScrolledIntoView($el)) {
        // do stuff
    }
});

方法3:两全其美

正如 John Resig 在上述博客文章中提出的,用于高流量站点的漂亮混合方法:

var $el = $('.guardrail360'),
    didScroll = false;

$(window).scroll(function() {
    didScroll = true;
});

var timer = setInterval(function() {
    if ( didScroll ) {
        didScroll = false;
        if (isScrolledIntoView($el)) {
            // do stuff

            // to run this block only once, simply uncomment the next line:
            //clearInterval(timer);
        }
    }
}, 250);

方法 4:节流/去抖动

节流(调用之间最少 N 毫秒)或去抖动(每个“突发”只有一次调用)模式也可用于有效限制内部代码执行的速率。假设您使用的是Ben Alman 的 jQuery throttle/debounce 插件,代码如下所示:

var $el = $('.guardrail360');

// Throttling
$(window).on('scroll', $.throttle( 250, function(){
    if (isScrolledIntoView($el)) {
        // do stuff
    }
}));

// Debouncing
$(window).on('scroll', $.debounce( 250, function(){
    if (isScrolledIntoView($el)) {
        // do stuff
    }
}));

(请注意,去抖动的行为与其他实现略有不同,但这有时可能是您想要的,具体取决于您的用户体验场景)

于 2012-11-07T21:32:42.553 回答
2

似乎您需要绑定滚动事件并在该事件触发时进行检测。

$(window).scroll(function () { 
  isScrolledIntoView('.guardrail360');
});
于 2012-11-07T21:32:15.907 回答
0
if ( isScrolledIntoView('.guardrail360') ) {

}

正如其他答案所建议的那样,您应该使用 act on $(window).scroll()。此外,为了让 if 语句在元素第一次滚动到视图中时运行,我run_once为您创建了这个函数:

$('window').on('scroll', function() {

    if ( isScrolledIntoView('.guardrail360') ) run_once(function() {
            // ...
    });

});

function run_once( callback ) {

    var done = false;

    return function() {

        if ( !done ) {

            done = true;

            return callback.apply( this, arguments );

        }

    };

}
于 2012-11-07T21:31:01.117 回答