2015-09-28 30 views
5

Ho bisogno di rimuovere un listener di eventi impostato sulla finestra, ma non funziona, il listener continua a sparare. Ho provato a impostare l'ascoltatore con e senza l'accelerazione di lodash, ma non fa alcuna differenza. Ecco il mio codice:listener di eventi nella finestra non rimuove

setupListener() { 
    window.addEventListener('resize', _.throttle(this.handler.bind(this), 750)); 
    window.addEventListener('scroll', _.throttle(this.handler.bind(this), 750)); 
} 

removeListener() { 
    window.removeEventListener('resize', _.throttle(this.handler.bind(this), 750)); 
    window.removeEventListener('scroll', _.throttle(this.handler.bind(this), 750)); 
    window.addEventListener('load', this.handler.bind(this), false); 
} 

static isElementInViewport (el) { 
    let rect = el.getBoundingClientRect(); 
    return (
     rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && 
     rect.right <= (window.innerWidth || document.documentElement.clientWidth) 
    ); 
} 

handler() { 
    if (this.options.url === undefined) {throw new Error('no url specified');} 
    if (InfiniteScroll.isElementInViewport(this.elementToWatch)) { 
     this.removeListener(); 
     this[this.options.transport](); 
    } 
} 

Ho anche cercato di promisify la rimozione:

handler() { 
    if (this.options.url === undefined) {throw new Error('no url specified');} 
    if (InfiniteScroll.isElementInViewport(this.elementToWatch)) { 
     Promise.resolve(this.removeListener()) 
      .then(val => { 
       this[this.options.transport](); 
      }); 
    } 
} 

che non fanno la differenza sia.

Più avanti nel codice, voglio riassegnare gli ascoltatori:

handleResponse(data) { 
     console.log('handleResponse' + data); 
     Promise.resolve(this.addElementsToDOM(data)) 
      .delay(1000) 
      .then(() => { 
       this.page++; 
       this.elementToWatch = document.getElementById(this.element).rows[document.getElementById(this.element).rows.length - this.options.loadTiming]; 
       //this.setupListener(); 
      }); 
    } 

Ho effettuato l'accesso ad ogni passo del e non riesco a trovare il motivo per questo. Qualcuno può aiutare?

Sidenote: esiste un modo migliore di gestire l'evento di scorrimento piuttosto che rimuovere e aggiungere gli ascoltatori tutto il tempo?

+1

Grazie a @Amit, ho visto questa domanda e risposta. Penso che sto già usando una funzione con nome - o mi manca qualcosa lì? –

+0

Sì, ti manca decisamente il punto. Devi 'rimuovere' *** esattamente *** ciò che hai aggiunto, cioè non un valore restituito da un' bind() 'e quindi racchiuso in un'altra chiamata. – Amit

+1

Hai provato la mia risposta, @ J.Doe? – Buzinas

risposta

5

Il fatto è che quando si aggiunge un listener di eventi, il browser salva come "chiave" il riferimento function che si passa come parametro. Quindi, quando vuoi rimuoverlo, devi inviare quel riferimento.

Esistono due modi per risolvere il problema. Il primo è quello di creare funzioni denominate:

setupListener() { 
    this.listener = function() { 
    _.throttle(this.handler.bind(this), 750); 
    }.bind(this); 

    window.addEventListener('resize', this.listener); 
    window.addEventListener('scroll', this.listener); 
} 

removeListener() { 
    window.removeEventListener('resize', this.listener); 
    window.removeEventListener('scroll', this.listener); 
    window.addEventListener('load', this.handler.bind(this), false); 
} 

L'altro, è sovrascrivendo il metodo della finestra addEventListener, ma io non suggerisco di farlo.

+1

Per il downvoter: puoi lasciare un commento per spiegare perché? – Buzinas

+1

Probabilmente perché questa domanda dovrebbe essere chiusa, non risposta. Inoltre, l'ultimo punto con l'override di 'addEventListener', è un buon suggerimento per non farlo, quindi non ti spari in testa, ma è molto meglio non menzionare queste idee in primo luogo. – Amit

+0

Grazie, capito! –

Problemi correlati