[英]Avoid from adding event listeners several times
I have an Office add-in which can open a popup browser window by 我有一个Office加载项,可以通过以下方式打开弹出浏览器窗口
popup = window.open("https://localhost:3000/#/new", "popup", "status=1, location=1, width=1000, height=1200")
This page is coded by angular. 该页面按角度编码。 To enable the communication between the add-in and the popup, I have added a listener in the controller.
为了启用外接程序和弹出窗口之间的通信,我在控制器中添加了一个侦听器。 As a result, they can send messages to each other by
postMessage
. 结果,他们可以通过
postMessage
相互发送消息。
app.controller("Ctrl", ["$scope", "$window", function($scope, $window) {
... ...
$window.addEventListener("message", receiveMessage, false);
}
The communication works, except when the add-in changes the url of the popup to newUrl
(where newUrl
is another page instance which uses the same controller), by 除外接程序将弹出窗口的URL更改为
newUrl
(其中newUrl
是使用同一控制器的另一个页面实例)外,通信均有效。
popup.location.href = newUrl
Visually, the popup has changed, however the previous listener is not removed . 外观上,弹出窗口已更改,但是先前的侦听器未删除 。 As a result, one message sent by the add-in is received and treated twice (ie, by the new page and the previous page).
结果,外接程序发送的一条消息被接收并处理了两次(即,新页面和上一页)。
Does anyone know how to properly clean the listener when the add-in changes the popup page? 加载项更改弹出页面时,有人知道如何正确清理侦听器吗?
this.receiveMessage = function(e){
...
}
$window.addEventListener("message", this.receiveMessage, {once: true, capture: false});
The comment of Cenk is correct: the event-remove and event-add logic must be in exactly the same function scope. Cenk的评论是正确的:事件删除和事件添加逻辑必须在完全相同的功能范围内。
So, on the side of the add-in, when the popup changes to another Url, I need to send manually a close
message by postMessage
to the page: 因此,在外接程序一侧,当弹出窗口更改为另一个URL时,我需要通过
postMessage
手动向页面发送close
消息:
popup.postMessage({ "req": "close" }, popup.location.href);
popup.location.href = url
On the side of the popup page, I could remove the listener in the receiveMessage
, because it is still in the same page/function scope: 在弹出页面的一侧,我可以在
receiveMessage
删除侦听器,因为它仍在同一页面/函数范围内:
app.controller("Ctrl", ["$scope", "$window", function($scope, $window) {
... ...
var receiveMessage = function (event) {
... ...
switch (event.data) {
... ...
case "close":
$window.removeEventListener("message", receiveMessage, false)
}
}
}])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.