跟踪元素之外的滚动位置 [英] Track the scroll position beyond elements

查看:100
本文介绍了跟踪元素之外的滚动位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在整理一个jQuery插件。该插件采用面板,并自动调整其高度。所以我从这样的事情开始:

I'm putting together a jQuery plugin. The plugin takes panels, and auto-sizes their height. So I start off with something like this:

<div class="panel">Test 1</div>
<div class="panel">Test 2</div>
<div class="panel">Test 3</div>

该代码如下所示:

    sizePanels: function(){
      panels.each(function(){
        $(this).height(docHeight);
      });
    },

有一个向下按钮,点击后会将用户带到下一个$(。panel):

There is a down button, that when clicked, will take the user to the next $(".panel):

nextPanel: function(){
  $.scrollTo($(".panel:eq(" + panelIndex + ")"), 250, { easing: "swing" });
}

有了这个,我跟踪他们的面板索引:

With that, I'm keeping track of the panel index that their on:

    if (panelIndex < (panelCount - 1) ) {
      panelIndex += 1;
    }

我试图找出一种方法来跟踪它们是否碰巧手动滚动,并传递其中一个元素,然后增加panelIndex,这样按钮就不会向上移动而不是向下移动因为用户使用滚动条而不是按钮,它从未正确递增。这是我到目前为止所做的:

I'm trying to figure out a way to track if they happen to scroll manually, and pass one of the elements, to then increase the "panelIndex", so that the button doesn't move them up instead of down because it was never incremented properly due to the user using the scroll bar instead of the button. This is what I have so far:

   $(window).scroll(function(){
    panels.each(function(index){
      if ($(window).scrollTop() > $(this).scrollTop()) { 
        panelIndex = index; 
        // console.log(index);
      }
    });

    if (panelIndex < panelCount - 1){
      s.showDownButton();
    }
  });

代码过度检查并感觉有些过分。有更好的方法吗?

The code excessively checks and feels somewhat overboard. is there a better way to do it?

推荐答案

一个简单的优化是只计算一次scrollTop并退出每个循环找到匹配时您可以通过返回false退出$ .each循环。

An easy optimization is to only calculate the scrollTop once and to exit the each loop when a match is found. You can exit a $.each loop by returning false.

$(window).scroll(function(){
    var scrollTop = $(window).scrollTop();
    panels.each(function(index){
        if (scrollTop > $(this).scrollTop()) { 
            panelIndex = index; 
        } else {
            return false;
        }
    });

    if (panelIndex < panelCount - 1){
        s.showDownButton();
    }
});

我建议优化的另一种方法是预先计算页面上每个面板的scrollTop加载(以及调整视口大小时)。如果你将这些值存储在一个数组中,那么你可以很快地遍历它们。

The next way that I would suggest optimizing this is to pre-calculate the scrollTop of each panel on page load (and when the viewport is resized). If you store these values in an array, then you can loop through them very quickly.

这里有一些粗略的代码来说明这个想法:

Here is some rough code to illustrate the idea:

var panelTops = [];

findPanelTops(); // calculate on load
$(window).on("resize", findPanelTops); // calculate on resize

function findPanelTops() {
    panelTops = [];
    panels.each(function(index) {
        panelTops.push($(this).scrollTop());
    });
}

$(window).scroll(function(){
    var scrollTop = $(window).scrollTop();
    for (var i = 0; i < panelTops.length; i++) {
        if (scrollTop > panelTops[i]) { 
            panelIndex = i;
        } else {
            break;
        }
    };

    if (panelIndex < panelCount - 1){
        s.showDownButton();
    }
});

滚动事件可以快速启动,因此您希望将计算量保持为尽量少。解决所有这些问题的一种方法是实现一个scrollend处理程序。这只会在滚动事件似乎停止时触发。

The scroll event can fire a lot and very quickly, so you want to keep the amount of computation as minimal as possible. One way to get around all of this is to implement a scrollend handler. This will only fire when the scroll event has appeared to have stopped.

这是执行此操作的一些基本代码。当滚动事件停止超过500毫秒时将触发:

Here is some basic code for doing that. It will fire when the scroll event has stopped for more than 500ms:

var scrollTimeout = null;

function onScroll() {
    if (scrollTimeout) {
        clearTimeout(scrollTimeout);
    }
    scrollTimeout = setTimeout(onScrollEnd, 500);
}

function onScrollEnd() {
    // Scrolling has stopped
    // Do stuff ...

   scrollTimeout = null;
}

$(window).on("scroll", onScroll);

这篇关于跟踪元素之外的滚动位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆