2015-04-20 81 views
0

我正在尝试使用JavaScript在我的页面上检测滚动条。这样,当用户滚动一定数量的页面时,我可以更改某些元素的类和属性。这是我的JS功能:Javascript垂直滚动功能

function detectScroll() { 
    var header = document.querySelector(".headerOrig"), 
     header_height = getComputedStyle(header).height.split('px')[0], 
     fix_class = "changeColor"; 

    if(window.pageYOffset > header_height) {  
     header.classList.add(fix_class); 
    } 
    if(window.pageYOffset < header_height) { 
     header.classList.remove(fix_class); 
    } 
    var change = window.setInterval(detectScroll, 5000); 
} 

,当加载页面时,我称之为:

<body onload="detectScroll();"> 

不过,我有这个问题 - 我需要建立一个非常小的区间,以使函数被调用并且类会立即更改。但是,然后页面冻结,除JS功能以外的所有内容都运行得非常缓慢。 有什么更好的方式在JavaScript中实现这一点?

感谢您的任何意见/建议。

+2

我认为JavaScript中有一个onscroll事件处理程序。你有没有试过? –

+1

有'document.addEventListener(“scroll”,function(){console.log(document.body.scrollTop)})''。它比您的解决方案更容易,响应更快。 – veproza

回答

2

你将要改变一些事情。首先,我们可以使用onscroll而不是间隔。但是,您也希望尽可能缓存以减少滚动上的计算量。更进一步,您应该使用requestAnimationFrame(或者对于旧版浏览器,一般只是“反弹” - 请参阅链接)。这可确保您的工作仅在浏览器计划重新绘制时才会发生。例如,当用户滚动实际的滚动事件时可能触发几十次,但该页面只重绘一次。你只关心那个单一的重绘,如果我们可以避免为其他X次工作,它会更加平滑:

// Get our header and its height and store them once 
// (This assumes height is not changing with the class change). 
var header = document.querySelector(".headerOrig"); 
var header_height = getComputedStyle(header).height.split('px')[0]; 
var fix_class = "changeColor"; 

// This is a simple boolean we will use to determine if we are 
// waiting to check or not (in between animation frames). 
var waitingtoCheck = false; 

function checkHeaderHeight() { 
    if (window.pageYOffset > header_height) {  
    header.classList.add(fix_class); 
    } 
    if (window.pageYOffset < header_height) { 
    header.classList.remove(fix_class); 
    } 
    // Set waitingtoCheck to false so we will request again 
    // on the next scroll event. 
    waitingtoCheck = false; 
} 

function onWindowScroll() { 
    // If we aren't currently waiting to check on the next 
    // animation frame, then let's request it. 
    if (waitingtoCheck === false) { 
    waitingtoCheck = true; 
    window.requestAnimationFrame(checkHeaderHeight); 
    } 
} 

// Add the window scroll listener 
window.addEventListener("scroll", onWindowScroll); 
+0

很好的答案!我没有深入思考过这个问题。谢谢! – puk789

1

使用onscroll而不是onload因此您不需要间隔调用该函数。 你dedectScroll功能时,如果使用onscroll

<body onscroll="detectScroll();"> 
1

你的函数被递归添加间隔任何滚动appers被自动触发,您应该添加一个事件监听器滚动事件是这样的:

function detectScroll() { 
    var header = document.querySelector(".headerOrig"), 
     header_height = getComputedStyle(header).height.split('px')[0], 
     fix_class = "changeColor"; 

    if(window.pageYOffset > header_height) {  
     header.classList.add(fix_class); 
    } 
    if(window.pageYOffset < header_height) { 
     header.classList.remove(fix_class); 
    } 

} 
window.addEventListener("scroll",detectScroll);