迁移聊天室全局弹窗脚本
This commit is contained in:
@@ -1,6 +1,183 @@
|
|||||||
// 聊天室全局弹窗事件绑定,替代 Blade 内联 onclick。
|
// 聊天室全局弹窗组件,提供 alert / confirm / prompt API 与按钮事件绑定。
|
||||||
|
|
||||||
let globalDialogEventsBound = false;
|
let globalDialogEventsBound = false;
|
||||||
|
let dialogResolve = null;
|
||||||
|
let currentDialogType = "alert";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按 ID 读取全局弹窗节点。
|
||||||
|
*
|
||||||
|
* @param {string} id
|
||||||
|
* @returns {HTMLElement|null}
|
||||||
|
*/
|
||||||
|
function getDialogElement(id) {
|
||||||
|
return document.getElementById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开弹窗并按模式同步标题、内容、输入框和按钮状态。
|
||||||
|
*
|
||||||
|
* @param {object} options
|
||||||
|
* @param {string} options.message
|
||||||
|
* @param {string} options.title
|
||||||
|
* @param {string} options.color
|
||||||
|
* @param {string} options.type
|
||||||
|
* @param {string} [options.defaultVal]
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function openDialog({ message, title, color, type, defaultVal }) {
|
||||||
|
currentDialogType = type;
|
||||||
|
|
||||||
|
const header = getDialogElement("global-dialog-header");
|
||||||
|
const messageBox = getDialogElement("global-dialog-message");
|
||||||
|
const confirmButton = getDialogElement("global-dialog-confirm-btn");
|
||||||
|
const inputWrap = getDialogElement("global-dialog-input-wrap");
|
||||||
|
const inputElement = getDialogElement("global-dialog-input");
|
||||||
|
const cancelButton = getDialogElement("global-dialog-cancel-btn");
|
||||||
|
const modal = getDialogElement("global-dialog-modal");
|
||||||
|
|
||||||
|
if (!header || !messageBox || !confirmButton || !inputWrap || !(inputElement instanceof HTMLTextAreaElement) || !cancelButton || !modal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
header.textContent = title;
|
||||||
|
header.style.background = color;
|
||||||
|
messageBox.textContent = message;
|
||||||
|
confirmButton.style.background = color;
|
||||||
|
|
||||||
|
if (type === "prompt") {
|
||||||
|
inputElement.value = defaultVal ?? "";
|
||||||
|
inputWrap.style.display = "";
|
||||||
|
window.setTimeout(() => {
|
||||||
|
inputElement.focus();
|
||||||
|
inputElement.select();
|
||||||
|
}, 80);
|
||||||
|
} else {
|
||||||
|
inputWrap.style.display = "none";
|
||||||
|
inputElement.value = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelButton.style.display = type === "confirm" || type === "prompt" ? "" : "none";
|
||||||
|
confirmButton.style.flex = type === "alert" ? "1 1 100%" : "1";
|
||||||
|
modal.style.display = "flex";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 隐藏弹窗并重置 Promise 回调状态。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function hideDialog() {
|
||||||
|
const modal = getDialogElement("global-dialog-modal");
|
||||||
|
if (modal) {
|
||||||
|
modal.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogResolve = null;
|
||||||
|
currentDialogType = "alert";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建兼容旧调用点的全局 chatDialog API。
|
||||||
|
*
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
function createChatDialogApi() {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* 显示提示弹窗。
|
||||||
|
*
|
||||||
|
* @param {string} message
|
||||||
|
* @param {string} title
|
||||||
|
* @param {string} color
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
alert(message, title = "提示", color = "#336699") {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
dialogResolve = resolve;
|
||||||
|
openDialog({ message, title, color, type: "alert" });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示确认弹窗。
|
||||||
|
*
|
||||||
|
* @param {string} message
|
||||||
|
* @param {string} title
|
||||||
|
* @param {string} color
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
confirm(message, title = "请确认", color = "#cc4444") {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
dialogResolve = resolve;
|
||||||
|
openDialog({ message, title, color, type: "confirm" });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示文本输入弹窗。
|
||||||
|
*
|
||||||
|
* @param {string} message
|
||||||
|
* @param {string} defaultVal
|
||||||
|
* @param {string} title
|
||||||
|
* @param {string} color
|
||||||
|
* @returns {Promise<string|null>}
|
||||||
|
*/
|
||||||
|
prompt(message, defaultVal = "", title = "请输入", color = "#336699") {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
dialogResolve = resolve;
|
||||||
|
openDialog({ message, title, color, type: "prompt", defaultVal });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认当前弹窗。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
_confirm() {
|
||||||
|
if (currentDialogType === "prompt") {
|
||||||
|
dialogResolve?.(getDialogElement("global-dialog-input")?.value ?? "");
|
||||||
|
} else if (currentDialogType === "confirm") {
|
||||||
|
dialogResolve?.(true);
|
||||||
|
} else {
|
||||||
|
dialogResolve?.();
|
||||||
|
}
|
||||||
|
|
||||||
|
hideDialog();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消当前弹窗。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
_cancel() {
|
||||||
|
dialogResolve?.(currentDialogType === "prompt" ? null : false);
|
||||||
|
hideDialog();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接隐藏当前弹窗。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
_hide() {
|
||||||
|
hideDialog();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保全局 chatDialog API 已挂载。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function ensureChatDialog() {
|
||||||
|
if (!window.chatDialog) {
|
||||||
|
window.chatDialog = createChatDialogApi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定全局弹窗确认与取消按钮。
|
* 绑定全局弹窗确认与取消按钮。
|
||||||
@@ -13,6 +190,8 @@ export function bindGlobalDialogControls() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
globalDialogEventsBound = true;
|
globalDialogEventsBound = true;
|
||||||
|
ensureChatDialog();
|
||||||
|
|
||||||
document.addEventListener("click", (event) => {
|
document.addEventListener("click", (event) => {
|
||||||
if (!(event.target instanceof Element)) {
|
if (!(event.target instanceof Element)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -93,131 +93,3 @@
|
|||||||
opacity: .88;
|
opacity: .88;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
|
||||||
/**
|
|
||||||
* 全局弹窗工具,提供 alert / confirm 两种模式。
|
|
||||||
* 替代浏览器原生弹窗,兼容 Chrome/Edge/Safari。
|
|
||||||
*
|
|
||||||
* 用法:
|
|
||||||
* await window.chatDialog.alert('操作成功!', '提示', '#16a34a');
|
|
||||||
* const yes = await window.chatDialog.confirm('确定要删除吗?', '请确认');
|
|
||||||
* if (yes) { ... }
|
|
||||||
*/
|
|
||||||
window.chatDialog = (function() {
|
|
||||||
let _resolve = null;
|
|
||||||
let _currentType = 'alert';
|
|
||||||
|
|
||||||
const $ = id => document.getElementById(id);
|
|
||||||
|
|
||||||
/** 打开弹窗内部方法 */
|
|
||||||
function _open({ message, title, color, type, defaultVal }) {
|
|
||||||
_currentType = type;
|
|
||||||
|
|
||||||
$('global-dialog-header').textContent = title;
|
|
||||||
$('global-dialog-header').style.background = color;
|
|
||||||
$('global-dialog-message').textContent = message;
|
|
||||||
$('global-dialog-confirm-btn').style.background = color;
|
|
||||||
|
|
||||||
// prompt 模式显示输入框,并填入默认值
|
|
||||||
const inputWrap = $('global-dialog-input-wrap');
|
|
||||||
const inputEl = $('global-dialog-input');
|
|
||||||
if (type === 'prompt') {
|
|
||||||
inputEl.value = defaultVal ?? '';
|
|
||||||
inputWrap.style.display = '';
|
|
||||||
// 弹出后自动聚焦
|
|
||||||
setTimeout(() => { inputEl.focus(); inputEl.select(); }, 80);
|
|
||||||
} else {
|
|
||||||
inputWrap.style.display = 'none';
|
|
||||||
inputEl.value = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// alert 模式隐藏取消按钮
|
|
||||||
const cancelBtn = $('global-dialog-cancel-btn');
|
|
||||||
cancelBtn.style.display = (type === 'confirm' || type === 'prompt') ? '' : 'none';
|
|
||||||
|
|
||||||
// alert 模式确认按钮撑满
|
|
||||||
$('global-dialog-confirm-btn').style.flex = type === 'alert' ? '1 1 100%' : '1';
|
|
||||||
|
|
||||||
$('global-dialog-modal').style.display = 'flex';
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
/**
|
|
||||||
* 显示提示弹窗(替代 alert)。
|
|
||||||
*
|
|
||||||
* @param {string} message 提示内容
|
|
||||||
* @param {string} title 标题(默认:提示)
|
|
||||||
* @param {string} color 标题栏颜色(默认蓝色)
|
|
||||||
* @return {Promise<void>}
|
|
||||||
*/
|
|
||||||
alert(message, title = '提示', color = '#336699') {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
_resolve = resolve;
|
|
||||||
_open({ message, title, color, type: 'alert' });
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示确认弹窗(替代 confirm)。
|
|
||||||
*
|
|
||||||
* @param {string} message 确认内容
|
|
||||||
* @param {string} title 标题(默认:请确认)
|
|
||||||
* @param {string} color 标题栏颜色(默认红色)
|
|
||||||
* @return {Promise<boolean>} 用户点确定返回 true,取消返回 false
|
|
||||||
*/
|
|
||||||
confirm(message, title = '请确认', color = '#cc4444') {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
_resolve = resolve;
|
|
||||||
_open({ message, title, color, type: 'confirm' });
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示文本输入弹窗(替代 prompt)。
|
|
||||||
*
|
|
||||||
* @param {string} message 提示文字
|
|
||||||
* @param {string} defaultVal 输入框默认值
|
|
||||||
* @param {string} title 标题(默认:请输入)
|
|
||||||
* @param {string} color 标题栏颜色(默认蓝色)
|
|
||||||
* @return {Promise<string|null>} 确定返回输入内容,取消返回 null
|
|
||||||
*/
|
|
||||||
prompt(message, defaultVal = '', title = '请输入', color = '#336699') {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
_resolve = resolve;
|
|
||||||
_open({ message, title, color, type: 'prompt', defaultVal });
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 点确定按钮 */
|
|
||||||
_confirm() {
|
|
||||||
if (_currentType === 'prompt') {
|
|
||||||
// prompt 模式:返回输入框内容
|
|
||||||
_resolve?.($('global-dialog-input').value);
|
|
||||||
} else if (_currentType === 'confirm') {
|
|
||||||
_resolve?.(true);
|
|
||||||
} else {
|
|
||||||
_resolve?.();
|
|
||||||
}
|
|
||||||
this._hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 点取消按钮 */
|
|
||||||
_cancel() {
|
|
||||||
if (_currentType === 'prompt') {
|
|
||||||
_resolve?.(null);
|
|
||||||
} else {
|
|
||||||
_resolve?.(false);
|
|
||||||
}
|
|
||||||
this._hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 关闭弹窗 */
|
|
||||||
_hide() {
|
|
||||||
$('global-dialog-modal').style.display = 'none';
|
|
||||||
_resolve = null;
|
|
||||||
_currentType = 'alert';
|
|
||||||
},
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user