<!doctype html>
<html>
<head>
<link rel="stylesheet" href="lib/style.css">
<script src="lib/script.js"></script>
</head>
<body>
<h1 id="title">Parent Window</h1>
<button onclick="openWindow()">Open Window</button>
<button onclick="focusWindow()">Focus Window</button>
<button onclick="closeWindow()">Close Window</button>
<form>
<label for="id">Window Id (*)</label>
<input type="id" id="id" name="id">
</form>
</body>
</html>
let windows = {}; // This is used as a key-value map for windows objects
let options = ['height=' + screen.height, 'width=' + screen.width].join(',');
let id = 0;
// Interval to keep syncrhonized status between parent and children windows
parentWindow = !window.opener;
if (parentWindow) {
console.log("Parent window");
setInterval(() => {
for (let id in windows) {
let ref = windows[id];
if (ref.closed) { // delete closed windows
console.log("Remove closed window ID", id);
delete windows[id];
}
ref.setParentWindows(windows); // update windows
}
}, 10000);
} else {
console.log("Child window");
}
function openWindow() {
try {
const id = getWindowId();
let ref = windows[id];
if (ref) {
alert("Window ID already exist");
throw new Error("Window ID already exist");
}
ref = window.open(`child-window.html`, id, options);
// This only works if the window is closed with window.close()
ref.addEventListener('load', (event) => {
ref.id = id;
ref.setWindowTitle(id);
ref.setParentWindows(windows);
ref.addEventListener('customfocus', (event) => {
console.log("Custom focus event received from window ID", id, event.detail); // window to focus
const ref2 = windows[event.detail];
if (!ref2) {
alert("Window ID not exist");
throw new Error("Window ID not exist");
}
// window.focus(); // parent window
// window.alert('focus'); //
// ref.blur(); // sender window
ref2.focus(); // child window
ref2.alert('focus'); //
}, false);
});
ref.addEventListener('beforeunload', (event) => {
console.log("Remove closed window ID", id);
delete windows[id];
event.preventDefault();
event.returnValue = '';
});
console.log("Add opened window ID", id);
windows[id] = ref;
} catch (error) {
console.error(error);
}
}
function focusWindow() {
try {
if (parentWindow) {
window.focus();
} else {
const id = getWindowId();
focusChildWindow(id);
}
} catch (error) {
console.error(error);
}
}
function focusChildWindow(id) {
const event = new CustomEvent('customfocus', { detail: id }); // window to focus
console.log(event);
window.dispatchEvent(event);
console.log("Custom focus event sent from window ID", window.id, id);
}
function closeWindow() {
try {
const id = getWindowId();
const ref = windows[id];
if (!ref) {
alert("Window ID not exist");
throw new Error("Window ID not exist");
}
ref.close(); // only parent can close children windows
//delete windows[id];
} catch (error) {
console.error(error);
}
}
////////////////////////////////////////////////////////////////////////////////
function setParentWindows(parentWindows) {
windows = parentWindows;
}
function getWindowId() {
const id = document.getElementById("id").value;
if (!id) {
alert("Window ID is required");
throw new Error("Window ID is required");
}
return id;
}
function setWindowTitle(id) {
document.getElementById("title").innerHTML += " " + id;
}
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="lib/style.css">
<script src="lib/script.js"></script>
</head>
<body>
<h1 id="title">Child Window</h1>
<button onclick="focusWindow()">Focus Window</button>
<button onclick="closeWindow()">Close Window</button>
<form>
<label for="id">Window Id (*)</label>
<input type="id" id="id" name="id">
</form>
</body>
</html>