Discuz! X 前端框架內建 popup 物件,提供統一的彈窗提示、確認對話框、自動跳轉功能。本文解析 popup.open()、popup.close() 參數、三種模式差異、模板標籤用法與進階整合範例。
popup.open(content, type, url) popup.close()
| 參數 | 型別 | 說明 |
|---|---|---|
| content | string / HTMLElement | 提示內容:純字串或選擇器/元素 |
| type | 'alert' | 'confirm' | 模式:alert=單按鈕, confirm=雙按鈕 |
| url | string | 確認/自動跳轉目標 URL(confirm 模式需點確認;alert 模式延遲自動跳轉) |
// JavaScript 呼叫
popup.open('操作成功!', 'alert', 'home.php?mod=space&uid=123');
// 行為:
// 1. 顯示彈窗,內容「操作成功!」,單一「確定」按鈕
// 2. 用戶點擊確定 → 跳轉至 url
// 3. 用戶不操作 → 預設延遲 (約 3 秒) 自動跳轉至 url
// 4. 無 url 參數 → 僅提示,點確定關閉彈窗
// JavaScript 呼叫
popup.open('確定要刪除嗎?', 'confirm', 'forum.php?mod=modcp&action=del&tid=456');
// 行為:
// 1. 顯示彈窗,內容「確定要刪除嗎?」,兩個按鈕:「確定」、「取消」
// 2. 用戶點擊「確定」 → 跳轉至 url
// 3. 用戶點擊「取消」 → 關閉彈窗,不跳轉
// 4. 不會自動跳轉,必須用戶互動
// 傳入選擇器或元素
const customContent = document.getElementById('my-custom-dialog');
popup.open(customContent, 'alert'); // type 仍為 alert/confirm,但內容為自定義 HTML
// 或動態建立
const div = document.createElement('div');
div.innerHTML = '自定義標題
包含表單、圖片等任意內容
';
popup.open(div, 'confirm', 'target_url');
<!-- 判斷用戶未登入,彈窗提示並跳轉登入頁 -->
<!--{if !$_G[uid]}-->
<script>
popup.open('請先登入後再進行操作', 'confirm', 'member.php?mod=logging&action=login');
</script>
<!--{else}-->
<script>
popup.open('操作成功!', 'alert', 'home.php?mod=space&uid={$_G[uid]}');
</script>
<!--{/if}-->
<!-- 關閉當前彈窗 -->
<script>popup.close();</script>
var popup = {
init: function() {
// 綁定 .popup 連結點擊事件
$('.popup').each(function() {
var $this = $(this);
var target = $($this.attr('href'));
if (target && target.attr('popup')) {
target.hide();
$this.on('click', function(e) {
e.preventDefault();
popup.open(target);
});
}
});
this.maskinit();
},
maskinit: function() {
$('#mask').off().on('tap', function() {
popup.close();
});
},
open: function(pop, type, url) {
this.close(); // 關閉現有彈窗
this.maskinit();
// 字串內容 → 建立標準彈窗 HTML
if (typeof pop === 'string') {
$('#ntcmsg').remove();
if (type === 'alert') {
pop = '' + pop + ' ';
} else if (type === 'confirm') {
pop = '' + pop + ' 取消 ';
}
$('body').append('' + pop + '');
pop = $('#ntcmsg');
}
// 定位顯示(置中)
var popupobj = $('#' + pop.attr('id') + '_popmenu');
// ... 計算 left/top ...
popupobj.css({display: 'block', position: 'fixed', left: left, top: top, zIndex: 120, opacity: 1});
$('#mask').css({display: 'block', width: '100%', height: '100%', position: 'fixed', top: 0, left: 0, background: 'black', opacity: '0.2', zIndex: '100'});
},
close: function() {
$('#mask').hide();
$.each(POPMENU, function(index, obj) {
$('#' + index + '_popmenu').hide();
});
}
};
<script>
$(function() {
$('#my-form').on('submit', function(e) {
e.preventDefault();
var $form = $(this);
var $btn = $form.find('button[type=submit]').prop('disabled', true);
$.post($form.attr('action'), $form.serialize(), function(response) {
$btn.prop('disabled', false);
if (response.status === 'success') {
// 成功:alert 模式,自動跳轉
popup.open(response.message, 'alert', response.redirect);
} else if (response.status === 'confirm') {
// 需確認:confirm 模式
popup.open(response.message, 'confirm', response.redirect);
} else {
// 錯誤:alert 模式,不跳轉
popup.open(response.message, 'alert');
}
}, 'json').fail(function() {
$btn.prop('disabled', false);
popup.open('網路錯誤,請稍後再試', 'alert');
});
});
});
</script>
| 問題 | 原因 | 解決 |
|---|---|---|
| 彈窗不顯示 | Common.js 未載入、jQuery 衝突 | 確認 <!--{subtemplate common/header}--> 載入、檢查 console 錯誤 |
| confirm 模式不跳轉 | url 參數錯誤、redirect 按鈕未正確綁定 | 檢查 url 完整性、確認按鈕 class 含 redirect |
| 彈窗位置偏移 | CSS 衝突、body 有 padding/margin | 檢查 #mask、.dialogbox 樣式 |
| 連續呼叫只顯示最後一個 | open() 開頭呼叫 close() |
設計如此,需求不同則修改源碼或用隊列 |
/* 覆寫預設樣式 */
#ntcmsg .tip {
background: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
}
#ntcmsg .tip dt {
font-size: 16px;
margin-bottom: 15px;
color: #333;
}
#ntcmsg .tip dd .button2 {
background: #00a1d6;
color: #fff;
border: none;
padding: 8px 20px;
border-radius: 4px;
cursor: pointer;
}
#ntcmsg .tip dd a {
margin-left: 10px;
color: #666;
}
#mask {
background: rgba(0,0,0,.5) !important;
}