是否为每个滚动事件在变量内存中重新创建?
Is it recreate in variable memory for each scroll event?
我有一个名为 ".offer" class 的元素,就在页面内页脚的正上方。当我在滚动运动中接近这个元素时,我希望粘性 header 关闭。
我为此在滚动事件中写了一个函数,但我对某些事情感到好奇。
当我创建如下例所示的函数时,函数 re-created 中的变量是否在每次滚动移动时都在内存中?或者在简单的页面滚动事件中性能的真相是什么?
const stickyNearOfferClose = () => {
let scrollPos;
let header = document.querySelector("header");
const documentOffset = document.querySelector(".offer").offsetTop;
header.classList.toggle("sticky", window.scrollY);
scrollPos = window.scrollY;
if (scrollPos >= documentOffset) {
header.classList.add("hide");
} else {
header.classList.remove("hide");
}
};
window.addEventListener("scroll", function () {
stickyNearOfferClose();
});
除了上面的问题
当我想对一个或多个滚动操作使用上述功能时,
为了性能和可用性,我们应该在函数内还是在 object 内定义变量?
我在下面分享了两个不同的例子。你觉得应该是哪一个?
const Obj = {
scrollPos : null,
elHeader: document.querySelector("header"),
documentOffset: document.querySelector(".offer").offsetTop,
// otherfunction (){},
stickyNearOfferClose() {
Obj.elHeader.classList.toggle("sticky", window.scrollY);
if (Obj.scrollPos >= Obj.documentOffset) {
Obj.elHeader.classList.add("hide");
} else {
Obj.elHeader.classList.remove("hide");
}
},
// init(){}
};
window.addEventListener("scroll", function () {
Obj.scrollPos = window.scrollY;
requestAnimationFrame(Obj.stickyNearOfferClose);
});
// OR
const Obj = {
// variables
stickyNearOfferClose() {
let scrollPos;
const elHeader = document.querySelector("header");
const elOffer = document.querySelector(".offer");
const documentOffset = elOffer.offsetTop;
let stickyClose = () => {
elHeader.classList.toggle("sticky", window.scrollY);
if (scrollPos >= documentOffset) {
elHeader.classList.add("hide");
} else {
elHeader.classList.remove("hide");
}
};
window.addEventListener("scroll", () => {
scrollPos = window.scrollY;
requestAnimationFrame(stickyClose);
});
},
spyScrolling() {
let scrollPos;
const sections = document.querySelectorAll(".hero");
let scrollActiveUrl = () => {
for (let s in sections) {
if (
sections.hasOwnProperty(s) &&
sections[s].offsetTop <= scrollPos + 150
) {
const id = sections[s].id;
document.querySelector(".active").classList.remove("active");
document.querySelector(`a[href*=${id}]`).classList.add("active");
}
}
};
window.addEventListener("scroll", () => {
scrollPos = document.documentElement.scrollTop || document.body.scrollTop;
requestAnimationFrame(scrollActiveUrl);
});
}
init(){
this.stickyNearOfferClose();
this.spyScrolling()
}
};
是的,函数中的变量将在每次滚动事件时重新创建。但在你的情况下,你可以将一些变量放在函数之外以节省一点。
根据 MDN,您不应直接在函数中调用昂贵的 DOM 操作。相反,建议使用 requestAnimationFrame()
、setTimeout()
或 CustomEvent
来限制事件。您可以在 here.
了解更多信息
以下是您的代码的改进示例:
let scrollPos;
const elHeader = document.querySelector("header");
const elOffer = document.querySelector(".offer");
// Note: I'm assuming that `documentOffset` don't need to be updated on every scroll events.
// Update it as `scrollPos` if it need to be updated on every scroll events.
const documentOffset = elOffter.offsetTop;;
const stickyNearOfferClose = () => {
// Note: Please move the following line in the scroll event
// if it's also needed to be called on every scroll events.
elHeader.classList.toggle("sticky", window.scrollY);
if (scrollPos >= documentOffset) {
elHeader.classList.add("hide");
} else {
elHeader.classList.remove("hide");
}
};
window.addEventListener("scroll", function () {
scrollPos = window.scrollY;
requestAnimationFrame(stickyNearOfferClose);
});
我有一个名为 ".offer" class 的元素,就在页面内页脚的正上方。当我在滚动运动中接近这个元素时,我希望粘性 header 关闭。
我为此在滚动事件中写了一个函数,但我对某些事情感到好奇。
当我创建如下例所示的函数时,函数 re-created 中的变量是否在每次滚动移动时都在内存中?或者在简单的页面滚动事件中性能的真相是什么?
const stickyNearOfferClose = () => {
let scrollPos;
let header = document.querySelector("header");
const documentOffset = document.querySelector(".offer").offsetTop;
header.classList.toggle("sticky", window.scrollY);
scrollPos = window.scrollY;
if (scrollPos >= documentOffset) {
header.classList.add("hide");
} else {
header.classList.remove("hide");
}
};
window.addEventListener("scroll", function () {
stickyNearOfferClose();
});
除了上面的问题
当我想对一个或多个滚动操作使用上述功能时,
为了性能和可用性,我们应该在函数内还是在 object 内定义变量?
我在下面分享了两个不同的例子。你觉得应该是哪一个?
const Obj = {
scrollPos : null,
elHeader: document.querySelector("header"),
documentOffset: document.querySelector(".offer").offsetTop,
// otherfunction (){},
stickyNearOfferClose() {
Obj.elHeader.classList.toggle("sticky", window.scrollY);
if (Obj.scrollPos >= Obj.documentOffset) {
Obj.elHeader.classList.add("hide");
} else {
Obj.elHeader.classList.remove("hide");
}
},
// init(){}
};
window.addEventListener("scroll", function () {
Obj.scrollPos = window.scrollY;
requestAnimationFrame(Obj.stickyNearOfferClose);
});
// OR
const Obj = {
// variables
stickyNearOfferClose() {
let scrollPos;
const elHeader = document.querySelector("header");
const elOffer = document.querySelector(".offer");
const documentOffset = elOffer.offsetTop;
let stickyClose = () => {
elHeader.classList.toggle("sticky", window.scrollY);
if (scrollPos >= documentOffset) {
elHeader.classList.add("hide");
} else {
elHeader.classList.remove("hide");
}
};
window.addEventListener("scroll", () => {
scrollPos = window.scrollY;
requestAnimationFrame(stickyClose);
});
},
spyScrolling() {
let scrollPos;
const sections = document.querySelectorAll(".hero");
let scrollActiveUrl = () => {
for (let s in sections) {
if (
sections.hasOwnProperty(s) &&
sections[s].offsetTop <= scrollPos + 150
) {
const id = sections[s].id;
document.querySelector(".active").classList.remove("active");
document.querySelector(`a[href*=${id}]`).classList.add("active");
}
}
};
window.addEventListener("scroll", () => {
scrollPos = document.documentElement.scrollTop || document.body.scrollTop;
requestAnimationFrame(scrollActiveUrl);
});
}
init(){
this.stickyNearOfferClose();
this.spyScrolling()
}
};
是的,函数中的变量将在每次滚动事件时重新创建。但在你的情况下,你可以将一些变量放在函数之外以节省一点。
根据 MDN,您不应直接在函数中调用昂贵的 DOM 操作。相反,建议使用 requestAnimationFrame()
、setTimeout()
或 CustomEvent
来限制事件。您可以在 here.
以下是您的代码的改进示例:
let scrollPos;
const elHeader = document.querySelector("header");
const elOffer = document.querySelector(".offer");
// Note: I'm assuming that `documentOffset` don't need to be updated on every scroll events.
// Update it as `scrollPos` if it need to be updated on every scroll events.
const documentOffset = elOffter.offsetTop;;
const stickyNearOfferClose = () => {
// Note: Please move the following line in the scroll event
// if it's also needed to be called on every scroll events.
elHeader.classList.toggle("sticky", window.scrollY);
if (scrollPos >= documentOffset) {
elHeader.classList.add("hide");
} else {
elHeader.classList.remove("hide");
}
};
window.addEventListener("scroll", function () {
scrollPos = window.scrollY;
requestAnimationFrame(stickyNearOfferClose);
});