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

How to communicate with popup after reload

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

window.opener.postMessage("initialize")

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

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;
};

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

有没有办法用postMessage解决这个问题?我想到的唯一其他选择是使用 localstorage 来放置信息并定期查找,但我对这样的解决方案不是很满意。

所以总而言之,我需要一个函数 (createPopup),它将创建或将辅助 window/popup 带到前面。主 window 需要能够与其通信,并且在使用同一主页面的不同实例时它必须工作。 (但 运行 切换实例时再次使用该功能即可。)

在JavaScript中设置失败,在features-parameter中打开window直接设置就可以了:

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-based 浏览器中似乎仍然不起作用,但这确实是一个非常不同的错误。