用戶點擊元素 → 彈出層 → 發起 AJAX 請求 → 將返回數據渲染到彈出層中。關鍵點:**異步請求與 UI 交互的協調**,以及**彈出層組件的選擇**。
<button id="triggerBtn">查看詳情</button>
<div id="popupOverlay" class="popup-overlay" style="display:none;">
<div class="popup-container">
<div class="popup-header">
<span>詳情信息</span>
<button class="popup-close">×</button>
</div>
<div id="popupContent" class="popup-body">加載中...</div>
</div>
</div>
.popup-overlay {
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.5); z-index: 1000;
display: flex; align-items: center; justify-content: center;
}
.popup-container {
background: white; width: 90%; max-width: 600px; max-height: 80vh;
border-radius: 8px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.2);
}
.popup-header { display: flex; justify-content: space-between; padding: 16px; border-bottom: 1px solid #eee; }
.popup-body { padding: 16px; overflow-y: auto; }
document.getElementById('triggerBtn').addEventListener('click', async () => {
const overlay = document.getElementById('popupOverlay');
const content = document.getElementById('popupContent');
overlay.style.display = 'flex'; // 顯示彈出層
content.innerHTML = '加載中...'; // 顯示加載狀態
try {
const response = await fetch('/api/getDetail', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({id: 123}) // 根據業務傳參
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
content.innerHTML = renderDetail(data); // 渲染數據
} catch (error) {
content.innerHTML = `加載失敗: ${error.message}`;
console.error(error);
}
});
// 關閉彈出層
document.querySelector('.popup-close').addEventListener('click', () => {
document.getElementById('popupOverlay').style.display = 'none';
});
// 點擊遮罩關閉
document.getElementById('popupOverlay').addEventListener('click', (e) => {
if (e.target === e.currentTarget) e.currentTarget.style.display = 'none';
});
function renderDetail(data) {
return `<h3>${data.title}</h3><p>${data.content}</p>`; // 根據實際數據結構渲染
}
推薦 Layer (layer.layui.com) 或 SweetAlert2,功能豐富、兼容性好、API 簡潔。
// 引入 layer.js 後
$('#triggerBtn').click(function() {
var index = layer.load(1, {shade: 0.3}); // 顯示加載圖標
$.ajax({
url: '/api/getDetail',
type: 'POST',
data: {id: 123},
dataType: 'json',
success: function(res) {
layer.close(index); // 關閉加載層
layer.open({
type: 1,
title: '詳情信息',
area: ['600px', '400px'],
content: renderDetail(res), // 直接渲染 HTML
btn: ['關閉'],
yes: function(index) { layer.close(index); }
});
},
error: function() {
layer.close(index);
layer.msg('加載失敗', {icon: 2});
}
});
});
若詳情頁邏輯極其複雜(含表單、腳本、樣式隔離),可用 iframe:
layer.open({
type: 2, // iframe 層
title: '詳情頁面',
area: ['800px', '600px'],
content: '/detailPage?id=123', // 直接加載 URL
maxmin: true
});
role="dialog"、aria-modal="true"、焦點陷阱、ESC 鍵關閉支持。現代 Web 開發中,**原生 fetch + CSS 動畫彈出層** 輕量靈活,適合簡單場景;**Layer/SweetAlert2** 開箱即用,適合企業級應用;**iframe** 解決複雜頁面嵌入與樣式隔離。核心邏輯均為:觸發 → 顯示容器 → 異步請求 → 渲染數據 → 錯誤兜底。
onBindViewHolder 全量觸發卡頓:佈局測量導致的錯誤回收機制
ScrollView 嵌套 RecyclerView 獲取總高度方案
Visual C++ char 數組溢出:DLL 寫入超過主程序預期長度導致崩潰
Android 預置資料庫:將 SQLite 檔放入 assets 目錄並在首次啟動複製到可寫入路徑
C# async/await 與 Task.Delay().Wait() 的 TaskStatus 差異分析
C 語言初學者求助:年齡換算秒數程序邏輯疑問