, -, , . . , , . , , /, . , . , , .
Edit
, , . , loaded unloaded, , . , . , , - .
ParentModule.spawnChild(). , . , , . . , same-origin policy.
, .
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 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.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);
});
}