首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Layer 彈窗點擊「取消」按鈕無反應:setTimeout 延時執行解決回調衝突

     編輯:程式設計疑難解答

問題現象

使用 Layer 彈窗,點擊「確認」正常彈出提示,但點擊「取消」按鈕(`no` 回調)無任何反應,不彈出「您選擇了取消」提示。

代碼還原

layer.open({
    content: '您確認取消認購?',
    btn: ['確認', '取消'],
    shadeClose: false,
    yes: function() {
        layer.open({content: '確認取消認購', time: 1});
    },
    no: function() {
        layer.open({content: '您選擇了取消', time: 1});
    }
});

根本原因

Layer 內部機制衝突:

  1. 用戶點擊「取消」按鈕
  2. Layer 開始關閉當前彈窗動畫(fade out、destroy DOM)
  3. 同時執行 `no` 回調,嘗試 `layer.open` 創建新彈窗
  4. **舊彈窗銷毀過程與新彈窗創建過程衝突**,導致新彈窗初始化失敗或被立即銷毀

解決方案:setTimeout 延時執行

no: function() {
    setTimeout(function() {
        // 500ms 後再彈出,等待舊彈窗完全銷毀
        layer.open({content: '您選擇了取消', time: 1});
    }, 500);
}

原理分析

  • JavaScript 事件循環:`setTimeout` 將回調推入**宏任務隊列**
  • 當前調用棧執行完畢(包含 Layer 關閉動畫啟動)
  • 瀏覽器渲染幀、完成舊彈窗 DOM 移除
  • 事件循環取出宏任務,執行新 `layer.open`
  • 新彈窗在乾淨環境中正常初始化

最佳實踐封裝

// 通用 Layer 確認對話框
function layerConfirm(options) {
    const defaults = {
        title: '提示',
        btn: ['確定', '取消'],
        shadeClose: false,
        yes: function(index, layero) {
            options.onConfirm?.(index, layero);
            layer.close(index);
        },
        no: function(index, layero) {
            // 統一延時處理,避免衝突
            setTimeout(() => {
                options.onCancel?.(index, layero);
            }, 300);
        }
    };
    
    layer.open({...defaults, ...options, content: options.content});
}

// 使用示例
layerConfirm({
    content: '您確認取消認購?',
    onConfirm: function() {
        layer.msg('確認取消認購');
        // 執行取消認購業務邏輯
    },
    onCancel: function() {
        layer.msg('您選擇了取消');
    }
});

延時時間選擇建議

場景建議延時理由
簡單提示彈窗300-500msLayer 關閉動畫約 200-300ms
複雜表單彈窗500-800msDOM 結構複雜,銷毀耗時較長
iframe 頁面層800-1000msiframe 卸載、父頁面重排需更多時間

其他同類衝突場景

  • Bootstrap Modal `hidden.bs.modal` 事件中打開新 Modal
  • SweetAlert2 關閉回調中彈出新提示
  • 原生 `alert/confirm` 後續彈窗(瀏覽器會阻塞,較少見)

通用原則:在關閉動畫完成前避免創建新彈窗,使用宏任務延時。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved