Javascript 垂直滚动功能
Javascript vertical scrolling function
我正在尝试使用 JavaScript 检测我页面上的滚动条。这样我就可以在用户滚动一定数量的页面时更改某些元素的 classes 和属性。这是我的 JS 函数:
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();">
但是,我遇到了这个问题 - 我需要设置一个非常小的间隔,以便调用该函数并立即更改 class。但随后页面冻结,除 JS 功能外的所有内容都运行非常缓慢。
在 JavaScript 中有没有更好的方法来实现这一目标?
感谢任何advice/suggestion。
使用 onscroll
而不是 onload
,因此您不需要使用间隔调用函数。
如果您使用 onscroll
,当任何滚动出现时,您的 dedectScroll
功能将自动触发
<body onscroll="detectScroll();">
您的函数正在递归添加一个间隔,您应该以这种方式向滚动事件添加一个事件侦听器:
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);
你会想要改变一些事情。首先,我们可以使用 onscroll 而不是 interval。但是您也将希望尽可能多地缓存以减少滚动的计算量。更进一步,您应该使用 requestAnimationFrame(或者对于较旧的浏览器通常简单地使用 "debounce"——请参阅 link)。这确保您的工作仅在浏览器计划重新绘制时发生。例如,当用户滚动时,实际的滚动事件可能会触发数十次,但页面只会重绘一次。您只关心那一次重绘,如果我们可以避免为其他 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);
我正在尝试使用 JavaScript 检测我页面上的滚动条。这样我就可以在用户滚动一定数量的页面时更改某些元素的 classes 和属性。这是我的 JS 函数:
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();">
但是,我遇到了这个问题 - 我需要设置一个非常小的间隔,以便调用该函数并立即更改 class。但随后页面冻结,除 JS 功能外的所有内容都运行非常缓慢。 在 JavaScript 中有没有更好的方法来实现这一目标?
感谢任何advice/suggestion。
使用 onscroll
而不是 onload
,因此您不需要使用间隔调用函数。
如果您使用 onscroll
dedectScroll
功能将自动触发
<body onscroll="detectScroll();">
您的函数正在递归添加一个间隔,您应该以这种方式向滚动事件添加一个事件侦听器:
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);
你会想要改变一些事情。首先,我们可以使用 onscroll 而不是 interval。但是您也将希望尽可能多地缓存以减少滚动的计算量。更进一步,您应该使用 requestAnimationFrame(或者对于较旧的浏览器通常简单地使用 "debounce"——请参阅 link)。这确保您的工作仅在浏览器计划重新绘制时发生。例如,当用户滚动时,实际的滚动事件可能会触发数十次,但页面只会重绘一次。您只关心那一次重绘,如果我们可以避免为其他 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);