diff --git a/assets/js/credits.js b/assets/js/credits.js index 637dd071..26a47996 100644 --- a/assets/js/credits.js +++ b/assets/js/credits.js @@ -393,28 +393,59 @@ modal.dataset.aksrtChargeInitialized = '1'; var form = modal.querySelector('[data-aksrt-charge-form]'); var busy = false; - var jq = window.jQuery; + var chargeBackdrop = null; - document.querySelectorAll('[data-aksrt-charge-open]').forEach(function (btn) { - btn.addEventListener('click', function () { - // Zibll 弹窗壳(.modal.fade)走 Bootstrap modal 运行时(zibll 的 refresh_modal 同源行为)。 - if (jq && jq.fn && jq.fn.modal) { - jq(modal).modal('show'); - } else { - modal.style.display = 'block'; - modal.classList.add('in'); - } - }); - }); - if (jq && jq.fn && jq.fn.modal) { - jq(modal).on('hidden.bs.modal', function () { - if (activePoll && typeof activePoll.abort === 'function') { - activePoll.abort(); - notyf('已停止查询支付状态', 'warning', 3, 'aksrt-balance-charge-payment-toast'); - } - activePoll = null; - }); + // 开关自包含:不复依赖 jQuery/Bootstrap modal 运行时,行为与视觉 + // 复刻 Bootstrap 3(.in 显隐 + .modal-backdrop + body.modal-open + ESC)。 + function openChargeModal() { + if (modal.classList.contains('in')) return; + // 兼容旧缓存标记(uc-modal 带 hidden 属性) + modal.removeAttribute('hidden'); + modal.style.display = 'block'; + void modal.offsetWidth; // 强制 reflow,让 .fade 过渡从初始态开始 + modal.classList.add('in'); + if (!chargeBackdrop) { + chargeBackdrop = document.createElement('div'); + chargeBackdrop.className = 'modal-backdrop fade in'; + chargeBackdrop.setAttribute('data-aksrt-charge-backdrop', '1'); + document.body.appendChild(chargeBackdrop); + } + document.body.classList.add('modal-open'); } + function closeChargeModal() { + if (!modal.classList.contains('in')) return; + if (activePoll && typeof activePoll.abort === 'function') { + activePoll.abort(); + notyf('已停止查询支付状态', 'warning', 3, 'aksrt-balance-charge-payment-toast'); + } + activePoll = null; + modal.classList.remove('in'); + document.body.classList.remove('modal-open'); + if (chargeBackdrop && chargeBackdrop.parentNode) { + chargeBackdrop.parentNode.removeChild(chargeBackdrop); + } + chargeBackdrop = null; + // 等过渡结束再撤 display,复刻 Bootstrap 的 fade-out 收尾 + window.setTimeout(function () { + if (!modal.classList.contains('in')) { + modal.style.display = ''; + } + }, 300); + } + document.querySelectorAll('[data-aksrt-charge-open]').forEach(function (btn) { + btn.addEventListener('click', openChargeModal); + }); + modal.addEventListener('click', function (e) { + // 点遮罩层(.modal 自身)或关闭按钮(data-dismiss="modal") + if (e.target === modal || (e.target.closest && e.target.closest('[data-dismiss="modal"]'))) { + closeChargeModal(); + } + }); + document.addEventListener('keydown', function (e) { + if (e.key === 'Escape' && modal.classList.contains('in')) { + closeChargeModal(); + } + }); // Zibll data-for/data-value 选中模型:余额档位(.vip-product.product-box) // 选中变化不产生 change 事件(隐藏 input 由程序赋值),需显式重置幂等键。 function selectProduct(value) {