我有一个指示指令,用于将固定的类应用于插入的DOM元素,为此,我还将事件侦听器附加到要在用户滚动时运行的window对象。
我的问题是,我的元素被销毁时是否应该删除此事件侦听器?我听说滚动事件会影响性能,并且我不确定每次刷新页面时事件监听器是否会自动销毁(我的应用程序不是SPA,而是带有vue前端的laravel应用程序)。
这是我的指令:
Vue.directive('scroll-apply-class', {
isLiteral: true,
inserted: (el, binding, vnode) => {
let scrolled = false;
let stickyTop = 300;
setTimeout(function(){
stickyTop = el.offsetTop;
checkPosition();
window.addEventListener('scroll', function(e) {
scrolled = true;
});
}, 2500);
let checkPosition = function(){
if (window.pageYOffset > stickyTop && window.innerWidth > 765) {
el.classList.add(binding.value)
}
else {
el.classList.remove(binding.value)
}
};
let timeout = setInterval(function() {
if (scrolled) {
scrolled = false;
checkPosition();
}
}, 2500);
}
});
答案 0 :(得分:0)
如果您关心“正派”,那么可以,做对了,删除该侦听器。但是从实用主义者的角度来看,也许不是。由于您的应用程序不是SPA,因此每次用户单击链接并转到其他页面时,都会自动解决该问题。
但还是要视情况而定。在某些情况下,对您的其中一个页面进行一次长期访问时,是否有可能多次加载此指令?如果出现这种情况,则最好取消注册侦听器。如果否,则伪指令仅被加载一次,那么您可以放心地保留它。
答案 1 :(得分:0)
您可以在unbind
钩中的窗口上删除事件侦听器。但是,为了删除事件侦听器,您将需要存储它们的回调。这可以通过简单地将其存储为el
的属性来完成,例如el.scrollCallback
:
bind: (el) => {
el.scrollCallback = () => {
el.dataset.scrolled = true;
}
},
unbind: (el) => {
window.removeEventListener('scroll', el.scrollCallback);
},
然后,在您的inserted
钩中,只需更新存储scrolled
布尔值的方式即可。您可以将其存储在el
的数据集中,而不用将其封装在钩子中,以便其他钩子可以访问它:
inserted: (el, binding, vnode) => {
// Store data in element directly
el.dataset.scrolled = false;
let stickyTop = 300;
setTimeout(function(){
stickyTop = el.offsetTop;
checkPosition();
window.addEventListener('scroll', el.scrollCallback);
}, 2500);
// REST OF YOUR CODE HERE
// Remember to update all references to `scrolled` to `el.dataset.scrolled`
let timeout = setInterval(function() {
if (el.dataset.scrolled) {
el.dataset.scrolled = false;
checkPosition();
}
}, 2500);
}