2016-05-13 60 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

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

相關問題