【问题标题】:Avoid from adding event listeners several times避免多次添加事件监听器
【发布时间】:2017-04-05 15:01:37
【问题描述】:

我有一个 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

在视觉上,弹出窗口已经改变,但是之前的监听器没有被移除。因此,加载项发送的一条消息会被接收并处理两次(即,新页面和前一页面)。

有谁知道当插件改变弹出页面时如何正确清理监听器?

【问题讨论】:

    标签: javascript angularjs popup window addeventlistener


    【解决方案1】:
    this.receiveMessage = function(e){
      ...
    }
    $window.addEventListener("message", this.receiveMessage, {once: true, capture: false});
    

    【讨论】:

    • 不知道为什么,我的测试显示监听器还在; removeEventListener 并没有真正删除监听器...
    • 你可以试试这个吗? $window.addEventListener("message", receiveMessage, {once: true, capture: false});
    • 如果您的 receiveMessage 在控制器中,那么每个控制器调用的每个 receiveMessage 回调都与其他回调不同,因此它永远不会被删除。您的事件删除和事件添加逻辑必须在同一函数范围内。
    【解决方案2】:

    Cenk 的评论是正确的:event-remove 和 event-add 逻辑必须在完全相同的函数范围内。

    因此,在加载项方面,当弹出窗口更改为另一个 Url 时,我需要通过postMessage 手动向页面发送close 消息:

    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)
            }
        }
    }])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-13
      • 2012-12-04
      相关资源
      最近更新 更多