You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery中Bootstrap Toggle无限循环问题求助

解决Bootstrap Toggle开关无限循环问题

问题根源

当AJAX请求失败需要回滚开关状态时,调用bootstrapToggle('on/off')会再次触发checkbox的change事件,导致updateStatus函数被反复调用,形成无限循环;同时原代码存在重复绑定事件、HTML元素重复ID的问题,进一步加剧了异常。

分步解决方案

1. 修复HTML重复ID问题

一个DOM元素只能拥有唯一ID,原代码中input的两个id属性冲突,先修正:

<form method="post" id="toggleForm_{{$detail['id']}}">
    <input type="checkbox" id="sce_{{$detail['id']}}" 
           data-onstyle="success" data-offstyle="danger" 
           data-toggle="toggle" name="sce" 
           data-on="Active" data-off="InActive" 
           {{ $detail['status'] == 1 ? 'checked' : '' }}>
    <input type="hidden" class="statusForDetail" 
           value="{{$detail['id']}}" page="sections-set-status" >
</form>

2. 修改JavaScript代码解决循环与重复绑定

核心思路:

  • 确保事件只绑定一次,避免多次调用onToggle导致多事件触发
  • 回滚状态时,使用不触发change事件的方式刷新Toggle UI

修改后的完整代码:

// 抽离事件绑定逻辑,避免重复代码
function bindToggleChange(cbRef, id, page, sid) {
    cbRef.off('change').on('change', function() {
        const status_val = this.checked ? 1 : 0;
        updateStatus(status_val, id, page, sid, $(this));
    });
}

function onToggle() {
    var page = $(".statusForDetail").attr('page');
    $(".statusForDetail").each((index, element) => {
        let id = $(element).val();
        let sid = id;
        const toggleEl = $('#sce_' + sid);
        bindToggleChange(toggleEl, id, page, sid);
    });
}

function updateStatus(status_val, id, page, sid, cbRef) {
    // 注意:移除硬编码的id=9,使用传入的id参数
    // id = 9; 

    $.ajax({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        },
        type: "POST",
        url: "/admin/" + page,
        data: {
            status: status_val,
            id: id
        },
        success: function(result) {
            if (result[0] == "Success!") {
                $("#updatedAt").fadeIn(0)
                    .html(`<font color='green' font size='2px'> : ${result[0]}${result[1]}</font>`)
                    .fadeOut(1500);
            } else {
                // 回滚状态:先解绑事件,避免触发循环
                const targetChecked = status_val === 1 ? false : true;
                cbRef.prop('checked', targetChecked);
                // 用refresh刷新UI,不会触发change事件
                cbRef.bootstrapToggle('refresh');
                // 重新绑定事件
                bindToggleChange(cbRef, id, page, sid);
            }
        },
        error: function() {
            // 错误场景同样回滚状态
            const targetChecked = status_val === 1 ? false : true;
            cbRef.prop('checked', targetChecked);
            cbRef.bootstrapToggle('refresh');
            bindToggleChange(cbRef, id, page, sid);
        }
    });
}

关键修复点说明

  • 使用bootstrapToggle('refresh'):仅同步Toggle UI与checkbox的checked状态,不会触发change事件,彻底避免循环触发。
  • off('change').on('change'):确保每个开关只绑定一个change事件,防止多次调用onToggle导致重复触发AJAX。
  • 抽离bindToggleChange函数:减少重复代码,保证事件绑定逻辑统一。

内容的提问来源于stack exchange,提问作者Orkhan Orkhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:24:47