開發嵌入主框架的 Web 即時通訊系統時,需解決多視窗間的引用管理:防止重複開啟聊天視窗、主視窗關閉時級聯關閉子視窗、跨視窗呼叫函式。本文詳述 JavaScript 視窗註冊機制的完整實作。
// 陣列原型擴充:add、remove、clear
if (!Array.prototype.add) {
Array.prototype.add = function() {
var startLength = this.length;
for (var i = 0; i < arguments.length; i++)
this[startLength + i] = arguments[i];
return this.length;
};
}
if (!Array.prototype.remove) {
Array.prototype.remove = function(index) {
if (index >= 0 && index < this.length)
this.splice(index, 1);
};
}
if (!Array.prototype.clear) {
Array.prototype.clear = function() {
this.splice(0, this.length);
};
}
// 已註冊視窗快取陣列
var g_oWindowArray = new Array();
// 註冊視窗:檢查是否已開啟,未開啟則開啟並加入快取
function RegisterWindow(windowName, url, features) {
for (var i = 0; i < g_oWindowArray.length; i++) {
if (g_oWindowArray[i].name == windowName && !g_oWindowArray[i].closed) {
g_oWindowArray[i].focus();
return g_oWindowArray[i];
}
}
var newWin = window.open(url, windowName, features);
g_oWindowArray.add({ name: windowName, win: newWin });
return newWin;
}
// 關閉視窗並從快取移除
function UnregisterWindow(windowName) {
for (var i = 0; i < g_oWindowArray.length; i++) {
if (g_oWindowArray[i].name == windowName) {
if (!g_oWindowArray[i].win.closed)
g_oWindowArray[i].win.close();
g_oWindowArray.remove(i);
break;
}
}
}
// 級聯關閉:關閉指定視窗及其所有子視窗
function CloseWindowTree(windowName) {
var parent = GetWindow(windowName);
if (!parent) return;
// 遞迴關閉子視窗(需維護父子關係對應表)
// ...
parent.win.close();
}
window.onunload = function() {
for (var i = 0; i < g_oWindowArray.length; i++) {
if (!g_oWindowArray[i].win.closed)
g_oWindowArray[i].win.close();
}
};
closed 屬性檢查,防止重複開啟。window.open 回傳的視窗物件存入陣列,維持跨視窗呼叫能力。onunload、onbeforeunload 事件觸發級聯關閉。window.opener 或 parent 存取主視窗函式與變數。現今專案建議採用 Single Page Application (SPA) 架構,以 Vue/React + SignalR/WebSocket 實作即時通訊,避免多視窗管理複雜度,提升使用者體驗與維護性。