Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/410.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么JavaScript;window.postMessage“;创建重复消息?_Javascript_Popupwindow - Fatal编程技术网

为什么JavaScript;window.postMessage“;创建重复消息?

为什么JavaScript;window.postMessage“;创建重复消息?,javascript,popupwindow,Javascript,Popupwindow,我正在尝试打开一个弹出窗口,做一些事情,然后将消息发送回打开的窗口,这样我就可以用它发送的数据做更多的事情 基本上,我正在适应 这是我在“打开窗口”上的代码。单击“社交连接”按钮时,它将运行。该代码打开一个弹出窗口,并在打开窗口上分配一个侦听器事件,以接收来自弹出窗口的消息: //Do the operation let windowObjectReference = null; let previousUrl = null; const openSignInWindow = (url, na

我正在尝试打开一个弹出窗口,做一些事情,然后将消息发送回打开的窗口,这样我就可以用它发送的数据做更多的事情

基本上,我正在适应

这是我在“打开窗口”上的代码。单击“社交连接”按钮时,它将运行。该代码打开一个弹出窗口,并在打开窗口上分配一个侦听器事件,以接收来自弹出窗口的消息:

//Do the operation
let windowObjectReference = null;
let previousUrl = null;

const openSignInWindow = (url, name) => {

    // remove any existing event listeners
    window.removeEventListener('message', receiveMessage);

    // window features
    const strWindowFeatures =
        'toolbar=no, menubar=no, width=600, height=700, top=100, left=100';

    if (windowObjectReference === null || windowObjectReference.closed) {
        /* if the pointer to the window object in memory does not exist
         or if such pointer exists but the window was closed */
        windowObjectReference = window.open(url, name, strWindowFeatures);
    } else if (previousUrl !== url) {
        /* if the resource to load is different,
         then we load it in the already opened secondary window and then
         we bring such window back on top/in front of its parent window. */
        windowObjectReference = window.open(url, name, strWindowFeatures);
        windowObjectReference.focus();
    } else {
        /* else the window reference must exist and the window
         is not closed; therefore, we can bring it back on top of any other
         window with the focus() method. There would be no need to re-create
         the window or to reload the referenced resource. */
        windowObjectReference.focus();
    }

    // add the listener for receiving a message from the popup
    window.addEventListener('message', event => receiveMessage(event), false);

    // assign the previous URL
    previousUrl = url;

};


const receiveMessage = event => {
    // Do we trust the sender of this message? (might be different from what we originally opened, for example).
    if (event.origin !== websiteHomeUrlNoSlash) {
        return;
    }

    const { data } = event;
    console.log(data); //<--- THIS WHERE I'm SEEING DUPLICATES

};

//Invoke the function
openSignInWindow(url, name);
// Get the message data
const messageObj = {
    pluginReason: pluginReasonVar,
    displayName: displayNameVar,
    provider: providerVar,
};

if (window.opener) {
    // send them to the opening window
    window.opener.postMessage(messageObj, websiteHomeUrlNoSlash);
    // close the popup
    if (closePopup) {
        window.close();
    }
}
一切都像预期的那样。用户可以登录到他们的社交帐户,所有的重定向和弹出窗口的打开和关闭都可以正常工作

问题:

如果用户多次执行社交连接过程而没有刷新页面,则每次运行时打印到控制台的消息数据会越来越多地重复

例如:

  • 在第一次运行控制台时,日志(数据)打印一次。到目前为止,这是预期的效果
  • 在第二次运行时,
    console.log(数据)
    打印两次。它只能打印一次
  • 在第三次运行时,
    console.log(数据)
    打印三次。它只能打印一次
每次运行Social Connect进程时,它应该只打印一次。但不知何故,它在每次后续运行时都会添加一个副本

这种重复不断增加,直到用户刷新页面,这将从1开始计数

我想在
console.log(data)
上进行更多的数据操作,但在每次后续运行中创建重复副本时,我不能这样做

我如何阻止这种情况发生


可能是因为侦听器事件没有分离?如果是这样,我该如何修复它?

您已经创建了一个匿名方法
(event)=>{}
作为包装,并将其附加到
addEventListener
方法

window.addEventListener('message', event => receiveMessage(event), false);
它不能被删除

window.removeEventListener('message', receiveMessage);
要修复它,请进行如下更改:

window.addEventListener('message', receiveMessage, false);
同时,如果每次关闭窗口时方法
receiveMessage
都丢失,最好将
removeEventListener
部分移到
receiveMessage

const receiveMessage = (event)=> {
  window.removeEventListener('message', receiveMessage);
  // do something else
}

我认为您只需要在窗口关闭后{EventTarget}.removeEventListener()。否则将复制侦听器事件侦听器位于打开的窗口上,而不是弹出窗口上。试图将其从弹出窗口(其中
window.close();
所在位置)中删除时,只会抛出一个ReferenceError,因为该窗口上没有定义事件侦听器。另外,我已经添加了一个
窗口到打开的窗口。您可以在
openSignInWindow
的第一行找到它。这将删除打开窗口上的任何现有事件侦听器。也许问题不是事件侦听器没有分离,而是别的什么吗?考虑使用而不是PASSMEST API,你的问题就会自行消失。请参见“谢谢”,但广播频道的浏览器支持率为76.26%(),而发布消息的浏览器支持率为96.29%()。所以在这种情况下,我需要使用Post消息,因为它有更好的支持。我已经注释掉了
window.addEventListener('Message',event=>receiveMessage(event),false)内部
openSignInWindow
并将其替换为
窗口。addEventListener('message',receiveMessage,false)。不幸的是,这并没有解决问题,我仍然得到重复的
console.log
打印。可能需要一些指导,以确定您希望我在哪里测试
window.receiveMessage=()=>{}但是我已经在
窗口下测试了它
以及直接位于
openSignInWindow(oneAllDirectConnectUrl,windowName)上方的。两个位置仍然存在重复打印的问题。我删除了那个位置,因为我刚刚意识到它是一个不同的
窗口
对象。方向是每次启动新窗口时,
receiveMessage
都是一个新方法,即使它具有相同的名称。所以我在想,你是否可以将它传入或存储在全局对象中的某个地方,以确保它在每次工作时都是相同的方法。顺便问一下,它是否是放置
window.removeEventListener('message',receiveMessage)的一个选项在你的
receiveMessage
功能中?开始工作了!我替换了
window.addEventListener('message',event=>receiveMessage(event),false)带有
窗口。addEventListener('message',receiveMessage,false)如您在回答中建议的,然后我还添加了
窗口。removeEventListener('message',receiveMessage)
receivemessage
功能中,如上述注释所示。现在,它每次只打印一个:)如果您编辑您的答案以包含最后一部分,我将标记为已接受。干杯