好的,我写了一些代码来测试这个功能,因为之前从未听说过。但是,它的效果很不错。我有一个父窗口,它在数组中跟踪它产生的子窗口。每次它产生一个新窗口时,它会告诉子窗口他们的新兄弟姐妹,以便他们也能跟踪他。然后,每个子窗口都有自己的方法让它们接收来自其兄弟姐妹的消息。我还为它们提供了简单的输入来相互发送消息并打印出它们接收到的消息。
编辑
好的,我完全重写了代码,使其更加健壮,并使您不必手动告诉子代彼此的存在。现在,父级已钩入事件,以便在加载和卸载时通知其子代它将不再存在。但由于在创建它们时就通知了子代彼此的存在,所以这并不重要。唯一有点棘手的是,如果在父窗口关闭后创建更多的窗口。
父窗口通过ParentModule.spawnChild()
函数协调子窗口。这就是让子窗口知道新子窗口的方法。因此,如果您想在父窗口关闭后创建新窗口,则必须调整一些函数。但是,这里是即使在父窗口关闭后进行父子窗口之间交互的代码。请记住,这依赖于同源策略
。
还添加了一种让父窗口知道其子代何时关闭的方法。
父级
parent.html
<!DOCTYPE html>
<html>
<head>
<title>Parent</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style></style>
<script src="parent.js"></script>
</head>
<body onload="main();" onunload="ParentModule.notifyChildren();">
<button id="closer">Close</button>
<div>New Child's Name</div>
<input type="text" id="newChildName">
<button id="spawner">Spawn Child</button>
<div id="log"></div>
</body>
</html>
parent.js
var ParentModule = (function() {
var exports = {};
exports.childWindows = {};
exports.numChildren = 0;
exports.spawnChild = function(childName) {
var newChild = window.open(
"child.html",
childName,
"height=200, width=200, top=200, left=" + (200 * exports.numChildren)),
parent = window;
newChild.addEventListener("load", function() {
document.getElementById("log").innerHTML = "New child: " + childName;
newChild.ChildModule.giveName(childName);
newChild.ChildModule.setParent(parent);
for (var child in exports.childWindows) {
newChild.ChildModule.addSibling(exports.childWindows[child], child);
}
for (var child in exports.childWindows) {
exports.childWindows[child].ChildModule.addSibling(newChild, childName);
}
exports.childWindows[childName] = newChild;
newChild.ChildModule.start();
});
};
exports.removeChild = function(childName) {
var log = document.getElementById("log");
log.innerHTML = "My child: " + childName + " is gone";
delete exports.childWindows[childName];
};
exports.notifyChildren = function() {
for (var child in exports.childWindows) {
exports.childWindows[child].ChildModule.removeParent();
}
};
exports.closeAllChildren = function() {
for (var child in exports.childWindows) {
exports.childWindows[child].close();
}
};
return exports;
}());
function main() {
document.getElementById("spawner").addEventListener("click", function() {
ParentModule.spawnChild(document.getElementById("newChildName").value);
});
document.getElementById("closer").addEventListener("click", function() {
ParentModule.closeAllChildren();
});
}
Child
child.html
<!DOCTYPE html>
<html>
<head>
<title>Child</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style></style>
<script src="child.js"></script>
</head>
<body onload="main();" onunload="ChildModule.notifyKinOfDeath();">
<div>Destination Window</div>
<input type="text" id="whichWin">
<div>Message</div>
<input type="text" id="message">
<button id="sendMessage">Send Window a Message</button>
<div id="myName">I'm a child</div>
<div id="log"></div>
</body>
</html>
child.js
var ChildModule = (function() {
var exports = {};
exports.siblingWindows = {};
exports.name = "";
exports.parent = null;
exports.sendMessage = function(envelope) {
var log = document.getElementById("log");
log.innerHTML = "Got: " + envelope.message + " from: " + envelope.sender;
};
exports.passMessage = function(targetSibling, message) {
var log = document.getElementById("log");
if (exports.siblingWindows[targetSibling]) {
exports.siblingWindows[targetSibling].ChildModule.sendMessage({
"sender": exports.name,
"message": message
});
}
else {
log.innerHTML = "I have no sibling: " + targetSibling;
}
};
exports.giveName = function(name) {
exports.name = name;
document.getElementById("myName").innerHTML = "My name is: " + exports.name;
};
exports.getName = function() {
return exports.name;
};
exports.setParent = function(parent) {
exports.parent = parent;
};
exports.start = function() {
var log = document.getElementById("log");
log.innerHTML = "Hello, my name is: " + exports.name;
};
exports.addSibling = function(sibling, siblingName) {
var log = document.getElementById("log");
exports.siblingWindows[siblingName] = sibling;
log.innerHTML = "I have a brother named: " + siblingName;
};
exports.removeSibling = function(siblingName) {
var log = document.getElementById("log");
log.innerHTML = "My brother: " + siblingName + " is gone";
delete exports.siblingWindows[siblingName];
};
exports.removeParent = function() {
var log = document.getElementById("log");
exports.parent = null;
log.innerHTML = "My parent is gone";
};
exports.notifyKinOfDeath = function() {
if (exports.parent) {
exports.parent.ParentModule.removeChild(exports.name);
}
for (var sibling in exports.siblingWindows) {
exports.siblingWindows[sibling].ChildModule.removeSibling(exports.name);
console.log("I've told them");
}
};
return exports;
}());
function main() {
document.getElementById("sendMessage").addEventListener("click", function() {
var whichWin = document.getElementById("whichWin").value,
messageToSend = document.getElementById("message").value;
ChildModule.passMessage(whichWin, messageToSend);
});
}