Javascript 阻止bookmarklet生成多个事件侦听器

Javascript 阻止bookmarklet生成多个事件侦听器,javascript,iframe,bookmarklet,Javascript,Iframe,Bookmarklet,我目前正在开发一个bookmarklet,它可以打开一个iframe,并设置一个来回的postMessage通信。一切正常。 然而,似乎是因为bookmarklet是作为匿名函数加载的,如果我在一个页面上多次运行bookmarklet,侦听器就会成倍增加 有没有什么方法可以跟踪这些AddEventListener,这样它们就不会重叠 我是否需要在匿名函数之外定义rp_receive_消息 下面是一个代码示例: var rp_receive_message = function (e) {

我目前正在开发一个bookmarklet,它可以打开一个iframe,并设置一个来回的postMessage通信。一切正常。 然而,似乎是因为bookmarklet是作为匿名函数加载的,如果我在一个页面上多次运行bookmarklet,侦听器就会成倍增加

有没有什么方法可以跟踪这些AddEventListener,这样它们就不会重叠

我是否需要在匿名函数之外定义rp_receive_消息

下面是一个代码示例:

var rp_receive_message = function (e) {
    var response = e.data;
    console.log("got message with "+ response);
  };

if (window.addEventListener) {
  window.addEventListener('message', rp_receive_message, false);
} else {
  window.attachEvent('onmessage', rp_receive_message);
}

var s1 = window.document.createElement('iframe');

s1.setAttribute('src', 'http://mydomain.com/iframe.html');
s1.setAttribute('id', 'testiframe');
s1.setAttribute('width', '700');
s1.setAttribute('height', '550');
s1.setAttribute('frameBorder', '0');
s1.setAttribute('onload', 'this.contentWindow.postMessage(window.location.href, "http://mydomain.com/iframe.html");');


document.getElementById('container').appendChild(s1);

这可能会解决问题:

window.onmessage = rp_receive_message;
正如您所建议的,下面的代码本身就足够了。我不知道addEventListener和attachEvent是否会多次添加相同的函数,但如果它们会这样做,我一点也不会感到惊讶。我建议只是测试一下

window.rp_receive_message = function(){...}

如果您不喜欢这两种解决方案中的任何一种,您必须设置一个全局变量,该变量看起来几乎没有什么不同,或者大大优于上述变量。全局事件可以是一个简单的布尔值,用于检查事件是否已附加,也可以是一个附加事件列表,您可以自行更新。好的,我很确定,没有原生的JS解决方案可以获得一个特定事件的事件监听器列表。jQuery之类的库维护列表并让您阅读它们;并且可能有其他的技巧,它们是解决一般问题的优雅解决方案。

简单但可行的解决方案!多次运行似乎可以有效地用新的rp_receive_消息覆盖window.onmessage,而不是每次都为新匿名函数的rp_receive_消息创建一个新的侦听器。我必须在不同的环境中试用。谢谢有人知道为什么在IE8中对window.onmessage调用window.postMessage似乎无法通过事件吗?在我上面使用window.onmessage的示例中,e是未定义的,e.data当然不存在,但是函数被激发了;窗口。后消息“嘿”;`导致“SCRIPT5007:无法获取属性“data”的值:IE8模式下IE9上的对象为null或未定义”。postMessage调用函数,但未定义“e”。有什么想法吗?不确定。我在网上看到的情况表明它应该有效。也许可以尝试添加这个e=e | | window.event;。