2012-05-15 62 views
0

我正在拼凑一个jQuery插件。该插件需要面板,并自动调整其高度。于是,我开始了与这样的:跟踪滚动位置超出元素

<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):

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

就这样,我在跟踪面板指标,他们对:

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

我试图找出一种方法来跟踪他们是否碰巧手动滚动,并传递其中一个元素,然后增加“panelIndex”,以便按钮不会将它们向上移动而不是向下移动因为用户使用滚动条而不是按钮,因此它从不增加。这是我到目前为止:

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

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

该代码过度检查和感觉有点过度。有没有更好的方法来做到这一点?

+0

在'$(窗口).scroll(函数()',而不是** **窗口尝试给面板父DIV – Imdad

回答

1

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

$(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的下一个方法(当视口大小)。如果你将这些值存储在一个数组中,那么你可以很快地循环它们。

下面是一些粗糙的代码来说明这个想法:

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(); 
    } 
}); 

scroll事件可以触发了很多,非常快,所以你要保持计算量尽可能小。解决所有这些问题的一种方法是实现滚动处理程序。这只会在滚动事件似乎停止时触发。

这是一些基本的代码。当滚动事件已经停止超过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); 
+0

的ID非常棒的信息。谢谢Nick! – user577808