在 2020 年,我需要在第二次初始化时调用 "removeEventListener" 吗?
In 2020 do i need to call "removeEventListener" on 2nd initialization?
我有连续动画,用 gsap library 制作。我正在使用 mouseover
/mouseout
事件来 pause/resume 这个动画。在 window 调整大小事件中,我正在重新初始化。我的问题是:我需要在第二次初始化时调用 removeEventListener
吗?
这里是 code/scenario:
const scroll = {
create: function (el) {
this.scrollAnimation = gsap.timeline({
repeat: -1
});
// another piece of awesome code here...
this.create__addMouseEvents(el);
},
create__addMouseEvents: function (el) {
// here, on window resize event( when i call update(), during re-initialization ), do i need to call "removeEventListener"?
el.addEventListener('mouseover', () => this.scrollAnimation.pause());
el.addEventListener('mouseout', () => this.scrollAnimation.resume());
},
update: function () {
//
// destroy old "scrollAnimation" if it's already exists
if (this.scrollAnimation) {
this.scrollAnimation.kill();
}
//
// reinit
this.init();
},
init: function () {
// some awesome code here...
this.create(el);
}
}
document.addEventListener('DOMContentLoaded', function () {
scroll.init();
});
let windowResizeTimer;
window.addEventListener('resize', function () {
clearTimeout(windowResizeTimer);
windowResizeTimer = setTimeout(function () {
scroll.update();
}, 150);
});
您目前每次更新都会向浏览器添加一个新事件。一个简单的解决方案如下:
const scroll = {
eventsAlreadyAdded: false,
create: function (el) {
this.scrollAnimation = gsap.timeline({ repeat: -1 });
// another piece of awesome code here...
if (!scroll.eventsAlreadyAdded) {
this.create__addMouseEvents(el);
scroll.eventsAlreadyAdded = true;
}
},
create__addMouseEvents: function (el) { /* .. */ },
update: function () { /* .. */ },
init: function () { /* .. */ }
}
由于您没有实例化滚动对象,因此必须更改全局引用scroll.eventsAlreadyAdded。
或者,您可以稍微重写代码,以便处理实例化变量(未测试):
class Scroll {
/**
* Returns the element
* @type {Node}
*/
static get element() {
return document.querySelector('THE ELEMET SELECTOR');
}
/**
* Initial the scroll event to given element
* @param {Node} el the element that will get an animation
*/
constructor(el) {
this.el = el;
/**
* Remembers whether the events have already been attached to the element
* @type {boolean}
*/
this.eventsAlreadyAdded = false;
/**
* The timeline instanze from gsap
* @type {Timeline}
*/
this.scrollAnimation = null;
this.create();
}
create() {
this.scrollAnimation = gsap.timeline({
repeat: -1
});
// another piece of awesome code here...
this.addMouseEvents();
}
addMouseEvents() {
if (this.eventsAlreadyAdded) return;
this.el.addEventListener('mouseover', () => this.scrollAnimation.pause());
this.el.addEventListener('mouseout', () => this.scrollAnimation.resume());
this.eventsAlreadyAdded = true;
}
update() {
if (this.scrollAnimation) {
this.scrollAnimation.kill();
}
this.create();
}
}
let scroll = null;
let windowResizeTimer = null;
document.addEventListener('DOMContentLoaded', () => {
scroll = new Scroll(Scroll.element)
});
window.addEventListener('resize', () => {
if (!scroll) return;
if (windowResizeTimer) clearTimeout(windowResizeTimer);
windowResizeTimer = setTimeout(() => { scroll.update(); }, 150);
});
我有连续动画,用 gsap library 制作。我正在使用 mouseover
/mouseout
事件来 pause/resume 这个动画。在 window 调整大小事件中,我正在重新初始化。我的问题是:我需要在第二次初始化时调用 removeEventListener
吗?
这里是 code/scenario:
const scroll = {
create: function (el) {
this.scrollAnimation = gsap.timeline({
repeat: -1
});
// another piece of awesome code here...
this.create__addMouseEvents(el);
},
create__addMouseEvents: function (el) {
// here, on window resize event( when i call update(), during re-initialization ), do i need to call "removeEventListener"?
el.addEventListener('mouseover', () => this.scrollAnimation.pause());
el.addEventListener('mouseout', () => this.scrollAnimation.resume());
},
update: function () {
//
// destroy old "scrollAnimation" if it's already exists
if (this.scrollAnimation) {
this.scrollAnimation.kill();
}
//
// reinit
this.init();
},
init: function () {
// some awesome code here...
this.create(el);
}
}
document.addEventListener('DOMContentLoaded', function () {
scroll.init();
});
let windowResizeTimer;
window.addEventListener('resize', function () {
clearTimeout(windowResizeTimer);
windowResizeTimer = setTimeout(function () {
scroll.update();
}, 150);
});
您目前每次更新都会向浏览器添加一个新事件。一个简单的解决方案如下:
const scroll = {
eventsAlreadyAdded: false,
create: function (el) {
this.scrollAnimation = gsap.timeline({ repeat: -1 });
// another piece of awesome code here...
if (!scroll.eventsAlreadyAdded) {
this.create__addMouseEvents(el);
scroll.eventsAlreadyAdded = true;
}
},
create__addMouseEvents: function (el) { /* .. */ },
update: function () { /* .. */ },
init: function () { /* .. */ }
}
由于您没有实例化滚动对象,因此必须更改全局引用scroll.eventsAlreadyAdded。
或者,您可以稍微重写代码,以便处理实例化变量(未测试):
class Scroll {
/**
* Returns the element
* @type {Node}
*/
static get element() {
return document.querySelector('THE ELEMET SELECTOR');
}
/**
* Initial the scroll event to given element
* @param {Node} el the element that will get an animation
*/
constructor(el) {
this.el = el;
/**
* Remembers whether the events have already been attached to the element
* @type {boolean}
*/
this.eventsAlreadyAdded = false;
/**
* The timeline instanze from gsap
* @type {Timeline}
*/
this.scrollAnimation = null;
this.create();
}
create() {
this.scrollAnimation = gsap.timeline({
repeat: -1
});
// another piece of awesome code here...
this.addMouseEvents();
}
addMouseEvents() {
if (this.eventsAlreadyAdded) return;
this.el.addEventListener('mouseover', () => this.scrollAnimation.pause());
this.el.addEventListener('mouseout', () => this.scrollAnimation.resume());
this.eventsAlreadyAdded = true;
}
update() {
if (this.scrollAnimation) {
this.scrollAnimation.kill();
}
this.create();
}
}
let scroll = null;
let windowResizeTimer = null;
document.addEventListener('DOMContentLoaded', () => {
scroll = new Scroll(Scroll.element)
});
window.addEventListener('resize', () => {
if (!scroll) return;
if (windowResizeTimer) clearTimeout(windowResizeTimer);
windowResizeTimer = setTimeout(() => { scroll.update(); }, 150);
});