最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Remove or destroy event listener - Stack Overflow

programmeradmin3浏览0评论

working on angular2 application. I have RxJS timer instance that will push notification to user when used logged in. But it should not push notification if tab is not active then scheduler should pause/stop. It is also done.

But main thing is that I have added that window (focus, blur )event listener to ngOnInit(). I have tried to destroy it on ngOnDestroy() when we change page/component but though also it does not stop. When we came back to same page then second instance also started of that listener and there will be 2 scheduler instance now in my memory/scope.

So anyone have idea that how to remove/destroy window.listener on ngOnDestroy or any other place !

Code:

timerFlag: boolean = true;
private timer;
private sub: Subscription;

ngOnInit() {
    this.sub = null;
    this.timer = null;
    console.log("home-init");
    window.addEventListener('blur', this.disableTimer.bind(this), false);
    window.addEventListener('focus', this.initializeTimer.bind(this), false);
}
disableTimer() {
    if (this.sub !== undefined && this.sub != null) {
        this.sub.unsubscribe();
        this.timer = null;
    }
}
initializeTimer() {
    if (this.timerFlag) {
        if (this.timer == null) {
            this.timer = Observable.timer(2000, 5000);
            this.sub = this.timer.subscribe(t => this.runMe());
        }
    }
}
runMe() {
    console.log("notification called : " + new Date());
}
ngOnDestroy() {
    console.log("Destroy timer");
    this.sub.unsubscribe();
    this.timer = null;
    this.sub = undefined;
    this.timerFlag = false;
    window.removeEventListener('blur', this.disableTimer.bind(this), false);
    window.removeEventListener('focus', this.initializeTimer.bind(this), false);
}

can anyone guide me how to destroy event listener instance so that when I come to same page next time no second instance will start.

I have tried to remove listener in ngOnInit as well before start of window listener.

working on angular2 application. I have RxJS timer instance that will push notification to user when used logged in. But it should not push notification if tab is not active then scheduler should pause/stop. It is also done.

But main thing is that I have added that window (focus, blur )event listener to ngOnInit(). I have tried to destroy it on ngOnDestroy() when we change page/component but though also it does not stop. When we came back to same page then second instance also started of that listener and there will be 2 scheduler instance now in my memory/scope.

So anyone have idea that how to remove/destroy window.listener on ngOnDestroy or any other place !

Code:

timerFlag: boolean = true;
private timer;
private sub: Subscription;

ngOnInit() {
    this.sub = null;
    this.timer = null;
    console.log("home-init");
    window.addEventListener('blur', this.disableTimer.bind(this), false);
    window.addEventListener('focus', this.initializeTimer.bind(this), false);
}
disableTimer() {
    if (this.sub !== undefined && this.sub != null) {
        this.sub.unsubscribe();
        this.timer = null;
    }
}
initializeTimer() {
    if (this.timerFlag) {
        if (this.timer == null) {
            this.timer = Observable.timer(2000, 5000);
            this.sub = this.timer.subscribe(t => this.runMe());
        }
    }
}
runMe() {
    console.log("notification called : " + new Date());
}
ngOnDestroy() {
    console.log("Destroy timer");
    this.sub.unsubscribe();
    this.timer = null;
    this.sub = undefined;
    this.timerFlag = false;
    window.removeEventListener('blur', this.disableTimer.bind(this), false);
    window.removeEventListener('focus', this.initializeTimer.bind(this), false);
}

can anyone guide me how to destroy event listener instance so that when I come to same page next time no second instance will start.

I have tried to remove listener in ngOnInit as well before start of window listener.

Share Improve this question edited Dec 8, 2016 at 6:22 user663031 asked Dec 8, 2016 at 4:46 user3145373 ツuser3145373 ツ 8,1467 gold badges48 silver badges65 bronze badges 7
  • Possible duplicate of JavaScript: remove event listener – user663031 Commented Dec 8, 2016 at 5:07
  • The listener being removed must be identical (in the === sense) to the one added. this.disabletimer.bind(this) is not identical when you call it twice. By the way, this has nothing to do with Angular. It's a pure JS issue. – user663031 Commented Dec 8, 2016 at 5:08
  • so, is there anyway I can remove listener !! – user3145373 ツ Commented Dec 8, 2016 at 5:15
  • Yes, as the duplicate question suggests, store the listener in a variable, then remove it using that variable. – user663031 Commented Dec 8, 2016 at 5:21
  • as the below answer, right ? – user3145373 ツ Commented Dec 8, 2016 at 5:22
 |  Show 2 more comments

1 Answer 1

Reset to default 19

1) I guess this should work:

ngOnInit() {
  window.addEventListener('blur', this.disableTimer, false);
  window.addEventListener('focus', this.initializeTimer, false);
}

disableTimer = () => { // arrow function
  ...
}
initializeTimer = () => { // arrow function
  ... 
}

ngOnDestroy() {
  window.removeEventListener('blur', this.disableTimer, false);
  window.removeEventListener('focus', this.initializeTimer, false);
}

Plunker Example

2) Another way is to store your listener in variable because .bind returns new function every time

disableTimerFn: EventListenerOrEventListenerObject;

ngOnInit() {
  this.disableTimerFn = this.disableTimer.bind(this);
  window.addEventListener('blur', this.disableTimerFn, false); 
}

ngOnDestroy() {
  window.removeEventListener('blur', this.disableTimerFn, false);
}

Plunker Example

3) But maybe is the best way is to use angular2 way:

@HostListener('window:blur', ['$event'])
disableTimer (event) { ... }

It will be automatically removed when component will be destroyed

Plunker Example

4) One more angular2 way is using Renderer

globalListenFunc: Function;
constructor(private renderer: Renderer) { }
ngOnInit() {
  this.globalListenFunc = this.renderer.listenGlobal('window', 'click', this.onClick.bind(this))
}

onClick() {
  alert('click');
}

ngOnDestroy() {
  this.globalListenFunc(); // destroy listener
}

Plunker Example

See also

  • Dynamically add event listener in Angular 2
发布评论

评论列表(0)

  1. 暂无评论