2016-05-13 59 views
1

我需要在调整浏览器大小后删除我的事件侦听器。我试过这样的事情:调整大小后删除eventListeners

window.addEventListener('resize',() => { 
     const bp = this.breakpointInit.getValue(); 

     if (bp === 'mobile') { 
     this.toggleMobile(); 
     } else { 
     this.toggleDesktop(); 
     } 
    }); 
    } 

    toggleMobile() { 
    Array.prototype.forEach.call(this.elements, (el) => { 
     const activeClass = `${el.classList[0]}--active`; 

     el.addEventListener('touchstart', (e) => { 
     this.switchClass(e, el, activeClass); 
     }); 

     el.removeEventListener('mouseenter', (e) => { 
     this.switchClass(e, el, activeClass); 
     }); 

     el.removeEventListener('mouseleave', (e) => { 
     this.switchClass(e, el, activeClass); 
     }); 
    }); 
    } 

    toggleDesktop() { 
    Array.prototype.forEach.call(this.elements, (el) => { 
     const activeClass = `${el.classList[0]}--active`; 

     el.addEventListener('click', (e) => { 
     this.switchClass(e, el, activeClass); 
     }); 

     el.addEventListener('mouseenter', (e) => { 
     this.switchClass(e, el, activeClass); 
     }); 

     el.addEventListener('mouseleave', (e) => { 
     this.switchClass(e, el, activeClass); 
     }); 

     el.removeEventListener('touchstart', (e) => { 
     this.switchClass(e, el, activeClass); 
     }); 
    }); 
    } 

上述功能在需要时触发,但事件侦听器结转。我做错了什么?

回答

1

您正在分配匿名函数,这些函数不能真正删除。

尝试这样:

let me = this; 

//this probably won't work exactly as-is, but you should get the idea 
touchStartHandler(e) { 
    me.switchClass(e, el, activeClass); 
} 

el.addEventListener('touchstart', touchStartHandler); 

//... 

el.removeEventListener('touchstart', touchStartHandler); 

有一个名为功能允许您添加,只要你想删除的东西,因为你原来的处理函数的引用。

+0

另外一个http://stackoverflow.com/questions/4402287/javascript-remove-event-listener的副本 – arthurakay

+1

它实际上并不需要命名。例如,一个匿名函数可以放在一个数组中,并由该引用中的'.addEventListener'和'.removeEventListener'引用。只要你添加和删除完全相同的函数实例,就可以。 –

+0

@JonathanGray你能解释一下更多关于你在说什么,也许作为答案? –

0

每次您声明一个函数时,都会创建一个全新的函数实例。这就是为什么你无法从事件监听器中删除它的原因。该功能的实例不存在开始。只要你引用同一个函数的声明实例,它就可以工作。例如(使用数组):

window.addEventListener('resize',() => { 
     const bp = this.breakpointInit.getValue(); 

     if (bp === 'mobile') { 
     this.toggleMobile(); 
     } else { 
     this.toggleDesktop(); 
     } 
    }); 
    } 

    var handlers = [(e) => { // touchstart 
     const activeClass = `${el.classList[0]}--active`; 
     this.switchClass(e, e.target, activeClass); 
     },(e) => { // click 
     const activeClass = `${el.classList[0]}--active`; 
     this.switchClass(e, e.target, activeClass); 
     },(e) => { // mouseenter 
     const activeClass = `${el.classList[0]}--active`; 
     this.switchClass(e, e.target, activeClass); 
     },(e) => { // mouseleave 
     const activeClass = `${el.classList[0]}--active`; 
     this.switchClass(e, e.target, activeClass); 
     }]; 

    toggleMobile() { 
    Array.prototype.forEach.call(this.elements, (el) => { 
     el.addEventListener('touchstart', handlers[0]); 
     el.removeEventListener('click', handlers[1]); 
     el.removeEventListener('mouseenter', handlers[2]); 
     el.removeEventListener('mouseleave', handlers[3]); 
    }); 
    } 

    toggleDesktop() { 
    Array.prototype.forEach.call(this.elements, (el) => { 
     el.addEventListener('click', handlers[1]); 
     el.addEventListener('mouseenter', handlers[2]); 
     el.addEventListener('mouseleave', handlers[3]); 
     el.removeEventListener('touchstart', handlers[0]); 
    }); 
    } 

这使用一个数组来跟踪函数实例。注意它们都是相同的代码,但技术上不同的实例。如果他们都将保持不变,那么你实际上可以逃避只为所有事件监听器使用单个实例。

+0

我刚刚意识到这个代码不会工作,因为'el'不在范围内了。我认为不是每个元素附加事件监听器,它应该在整个文档上完成。我将修改此代码,以便它按照原样工作。 –

+0

我已经做了修改,以便它现在可以工作。 –

相关问题