项目状态下拉框与阶段复选框联动异常(页面卡顿)求助
问题分析与解决方案
你的代码出现卡顿和报错的核心原因是双向联动触发了无限循环的事件和AJAX请求:
- 当
#idstatus切换为已完成(值1)时,代码会勾选所有.phase-checkbox,触发复选框的change事件 - 复选框
change事件中,因为所有复选框都被勾选,AJAX返回100%进度,又会把#idstatus设为1并触发change事件 - 如此反复循环,导致大量AJAX请求堆积,页面卡顿甚至报错
修复方案
通过添加临时标志位阻止循环触发,同时优化状态切换时的逻辑,避免不必要的AJAX请求:
1. 添加全局标志位,防止事件循环
在脚本开头定义一个标志位,用来标记当前是否是手动触发的状态/复选框变更,避免互相触发:
let isManualUpdate = false;
2. 修改状态下拉框的change事件逻辑
直接设置进度为100%,不再依赖复选框的AJAX请求,同时设置标志位避免触发复选框的change事件:
// Event listener for status change $('#idstatus').change(function () { if (isManualUpdate) return; isManualUpdate = true; var statusId = $(this).val(); if (statusId === '1') { $('.phase-checkbox').prop('checked', true); // 直接设置100%进度,跳过AJAX请求 $('#percentage').text('100%'); $('#total_percentage').val(100); $('#progress-bar').attr('stroke-dasharray', '75 100'); // 设置绿色(完成状态颜色) var completedColor = `rgb(0, 255, 0)`; $('#progress-bar').css('stroke', completedColor); $('#percentage').css('color', completedColor); $('#prog').css('color', completedColor); $('#circle').css('color', `rgba(0, 255, 0, 0.4)`); $('#idstatus').prop('disabled', true); } else { $('.phase-checkbox').prop('checked', false); // 直接重置进度,不要触发复选框的change事件 $('#percentage').text('--%'); $('#progress-bar').attr('stroke-dasharray', '0 100'); $('#total_percentage').val(0); var resetColor = `rgb(255, 0, 0)`; $('#progress-bar').css('stroke', resetColor); $('#percentage').css('color', resetColor); $('#prog').css('color', resetColor); $('#circle').css('color', `rgba(255, 0, 0, 0.4)`); $('#idstatus').prop('disabled', false); } handleStatusChange(statusId); isManualUpdate = false; });
3. 修改复选框的change事件逻辑
添加标志位判断,只有非手动触发的变更才执行后续逻辑:
// Event listener for phase checkboxes $(document).on('change', '.phase-checkbox', function () { if (isManualUpdate) return; isManualUpdate = true; var selectedPhases = []; // Collect all checked phases $('.phase-checkbox:checked').each(function () { selectedPhases.push($(this).val()); }); if (selectedPhases.length > 0) { $.ajax({ type: 'POST', url: 'get_percentage.php', data: { phases: selectedPhases.join(',') }, success: function (response) { var data = JSON.parse(response); var percentage = data.percentage; // Update the percentage text and input value $('#percentage').text(percentage + '%'); $('#total_percentage').val(percentage); // Calculate and update the progress bar based on the percentage var strokeValue = (percentage / 100) * 75; // Max is 75 for full progress $('#progress-bar').attr('stroke-dasharray', strokeValue + ' 100'); // Dynamically calculate color for the progress bar (red to green transition) var red = Math.max(255 - (percentage * 2.55), 0); // Red decreases as percentage increases var green = Math.min(percentage * 2.55, 255); // Green increases as percentage increases var color = `rgb(${red}, ${green}, 0)`; // Combine red and green for a smooth transition // Apply the color transition to relevant elements $('#progress-bar').css('stroke', color); $('#percentage').css('color', color); $('#prog').css('color', color); $('#circle').css('color', `rgba(${red}, ${green}, 0, 0.4)`); // If percentage is 100%, mark status as completed and disable status change if (percentage === 100) { $('#idstatus').val('1'); $('#idstatus').prop('disabled', true); } else { $('#idstatus').val('3'); $('#idstatus').prop('disabled', false); } isManualUpdate = false; }, error: function (xhr, status, error) { console.error("Failed to fetch percentage:", error); isManualUpdate = false; } }); } else { // If no phases are selected, reset the progress bar and percentage $('#percentage').text('--%'); $('#progress-bar').attr('stroke-dasharray', '0 100'); $('#total_percentage').val(0); // Reset color to red (0% progress) var resetColor = `rgb(255, 0, 0)`; $('#progress-bar').css('stroke', resetColor); $('#percentage').css('color', resetColor); $('#prog').css('color', resetColor); $('#circle').css('color', `rgba(255, 0, 0, 0.4)`); // Reset the status to default (in-progress) $('#idstatus').val('2'); $('#idstatus').prop('disabled', false); isManualUpdate = false; } });
关键修改点说明
- 标志位
isManualUpdate:用来区分是用户手动操作触发的变更,还是代码自动触发的变更,避免循环调用事件 - 状态切换为已完成时直接设置进度:跳过复选框的AJAX请求,减少不必要的服务器交互,同时避免触发复选框的
change事件 - 移除复选框
change事件中对#idstatus的trigger('change'):只修改值,不触发事件,防止循环
内容的提问来源于stack exchange,提问作者Efannnnnn
相关产品推荐
相关产品推荐

