避免多次添加事件侦听器

时间:2017-04-05 15:01:37

标签: javascript angularjs popup window addeventlistener

我有一个Office加载项,可以通过

打开一个弹出式浏览器窗口
popup = window.open("https://localhost:3000/#/new", "popup", "status=1, location=1, width=1000, height=1200")

此页面由angular编码。为了启用加载项和弹出窗口之间的通信,我在控制器中添加了一个监听器。因此,他们可以通过postMessage向对方发送消息。

app.controller("Ctrl", ["$scope", "$window", function($scope, $window) {
    ... ...
    $window.addEventListener("message", receiveMessage, false);
}

通信有效,除非加载项将弹出窗口的URL更改为newUrl(其中newUrl是另一个使用相同控制器的页面实例),

popup.location.href = newUrl

从视觉上看,弹出窗口已更改,但之前的侦听器未被删除。结果,加载项发送的一条消息被接收并处理两次(即,通过新页面和上一页)。

当加载项更改弹出页面时,是否有人知道如何正确清理侦听器?

2 个答案:

答案 0 :(得分:0)

this.receiveMessage = function(e){
  ...
}
$window.addEventListener("message", this.receiveMessage, {once: true, capture: false});

答案 1 :(得分:0)

Cenk的评论是正确的:事件删除和事件添加逻辑必须在完全相同的函数范围内。

因此,在加载项一侧,当弹出窗口更改为另一个Url时,我需要通过close手动向postMessage发送popup.postMessage({ "req": "close" }, popup.location.href); popup.location.href = url 条消息:

receiveMessage

在弹出页面的一侧,我可以删除app.controller("Ctrl", ["$scope", "$window", function($scope, $window) { ... ... var receiveMessage = function (event) { ... ... switch (event.data) { ... ... case "close": $window.removeEventListener("message", receiveMessage, false) } } }]) 中的监听器,因为它仍处于相同的页面/功能范围内:

export class Child2Component{
    @Input() person;

    child2Form : FormGroup; 
    ngOnit(){
       this.child2Form= this.fb.group({
           name: ''
       });
       this.child2Form.patchValue({
          name: this.person.name
       });
    }