如何在重新加载后与弹出窗口通信

时间:2018-03-22 19:26:57

标签: javascript window.open postmessage window.opener

我的页面打开一个弹出窗口并使用window.postMessage与之通信。要知道它什么时候准备就绪,弹出脚本中的第一件事就是:

window.opener.postMessage("initialize")

然后我回复并提供数据等等。 但是,如果我打开同一页面的两个实例,我会遇到一些问题。在Chrome和Firefox中,即使设置了windowName,它也会实际打开单个弹出窗口。使用myPopup.focus()设置焦点似乎甚至无法将它们提升到顶部。然而,在IE中,它重用了同一个窗口,我最初认为这是一个很大的改进。

As stated in the spec,但是,即使另一个父项重新打开,window.opener引用仍然不会更新。这意味着初始代码将与我的第一个实例进行通信。我曾尝试以各种方式改变行为,但我似乎无法以任何方式在这些行为之间进行沟通。

然后我找到了一种巧妙的方法来检测它,存储尺寸和位置,然后关闭并重新打开它。它看起来像这样:

const createPopup = (dimensions) => {
  let features = "menubar=0,toolbar=0,status=0,personalbar=0,location=0,resizable=1,scrollbars=1";
  const myPopup = window.open("/imageViewer.html", "ImageViewer", features);
  if (myPopup.opener !== window) {
    dimensions = { height: myPopup.outerHeight, width: myPopup.outerWidth, X: myPopup.screenX, Y: myPopup.screenY };
    myPopup.close();
    return createPopup(dimensions);
  }
  if (dimensions) {
    myPopup.moveTo(dimensions.X, dimensions.Y);
    myPopup.resizeTo(dimensions.width, dimensions.height);
  } else {
    myPopup.focus();
  }

  return myPopup;
};

问题在于,我的主要用途是当弹出窗口位于辅助监视器上时,似乎不允许弹出窗口移动到主屏幕的尺寸之外。< / p>

无论如何使用postMessage来解决这个问题?我唯一想到的另一个选择是使用localstorage来放置信息并按时间间隔查看,但我对这样的解决方案并不满意。

总而言之,我需要一个函数(createPopup),它将创建或带来一个辅助窗口/弹出窗口。主窗口需要能够与它通信,并且在使用同一主页的不同实例时它必须工作。 (但切换实例时再次运行该功能正常。)

1 个答案:

答案 0 :(得分:0)

虽然在JavaScript中设置失败,但在feature-parameter中打开窗口时直接设置时可以正常工作:

export const createPopup = (dim) => {
  let features = "menubar=0,toolbar=0,status=0,personalbar=0,location=0,resizable=1,scrollbars=1";
  if (dim) {
    features += ",left=" + dim.X + ",top=" + dim.Y + ",width=" + dim.width + ",height=" + dim.height;
  }
  const myPopup = window.open("/imageViewer.html", "ImageViewer", features);
  try {
    if (myPopup.opener !== window) {
      throw Error("just trying to read opener will throw exception in IE if the opening window has been closed");
    }
  } catch {
    dim = { height: myPopup.outerHeight, width: myPopup.outerWidth, X: myPopup.screenX, Y: myPopup.screenY };
    myPopup.close();
    return createPopup(dim);
  }
  myPopup.focus();

  return myPopup;
};

焦点仍然无法在基于chrome的浏览器中运行,但这确实是一个非常不同的错误。