如何修复端口下拉框克隆卡顿及克隆后范围不生效的问题
问题根因说明
- 问题1:点击添加按钮响应不灵敏:
onclick事件绑定在按钮内部的<i>图标元素上,只有点击到图标区域才会触发事件,点击按钮其他空白区域无响应 - 问题2:克隆的下拉框不生效:
- 页面存在重复id,DOM规范要求id唯一,你所有克隆出来的下拉框都和原始组共用
fromPortId、toPortId的id,JS用$('#fromPortId')取值永远只能取到第一个组的下拉值 - 全局变量存储端口列表逻辑不合理,新生成的范围直接覆盖文本域原有内容,没有做汇总处理
- 端口范围生成逻辑是固定取第一个组的数值,没有适配多组的取值逻辑
- 页面存在重复id,DOM规范要求id唯一,你所有克隆出来的下拉框都和原始组共用
代码修改方案
1. 修改待克隆的端口组HTML
调整事件绑定位置,去掉重复id,改用class标识元素:
<div id="first"> <div class="port"> <div class="row"> <div class="col-md-4"> <div class="form-group"> <label>From Port ID</label> <select class="custom-select mb-3 fromPortId" onchange="updatePortRange();"> <option selected>Select</option> {% for items in righttable %} <option value="{{items.0}}">{{items.0}}</option> {%endfor%} </select> </div> </div> <div class="col-md-4"> <div class="form-group"> <label>To Port ID</label> <select class="custom-select mb-3 toPortId" onchange="updatePortRange();"> <option selected>Select</option> {%for items in righttable%} <option value="{{items.0}}">{{items.0}}</option> {%endfor%} </select> </div> </div> <div class="col-md-1"> <div class="form-group"> <div class="text-sm-center"> <br /> <button type="button" class="btn btn-outline-success btn-rounded" onclick="addButton();"><i class="dripicons-plus"></i></button> </div> </div> </div> </div> </div> </div>
2. 重写JS逻辑
删除原有fromPortIdChange、toPortIdChange、portIdRange、calculateRange、旧addButton函数,替换为以下代码:
// 新增端口组 function addButton(){ // 克隆后清空新组的下拉选择,避免和原组值一致 const newPortGroup = $('#first .port').clone(); newPortGroup.find('.fromPortId').val('Select'); newPortGroup.find('.toPortId').val('Select'); newPortGroup.appendTo('#morerows'); // 新增后自动刷新端口范围 updatePortRange(); } // 全量更新端口范围文本域 function updatePortRange() { let allPorts = []; // 遍历所有端口组 $('.port').each(function() { const fromVal = $(this).find('.fromPortId').val(); const toVal = $(this).find('.toPortId').val(); // 只有两个下拉都选了才计算范围 if (fromVal === 'Select' || toVal === 'Select') return; // 解析接口名称和端口序号 const fromLastSliced = fromVal.slice(-5); const interfaceName = fromVal.substring(0, fromVal.length - 1); const fromNum = parseInt(fromLastSliced.split('/')[2]); const toNum = parseInt(toVal.slice(-5).split('/')[2]); // 生成当前组的端口列表 for(let i = fromNum; i <= toNum; i++) { allPorts.push(interfaceName + i); } }); // 把所有端口用逗号分隔填入文本域,如果需要换行可以把','换成'\n' $('#port_range').val(allPorts.join(',')); }
调整后效果
- 点击按钮任意位置都能触发克隆,一次点击即可新增端口组
- 所有新增组的下拉选择都会触发全量端口范围重算,自动汇总所有组的端口到文本域
- 自动跳过未完成选择的端口组,不会生成无效数值
- 修改任意旧组的端口选择,都会自动同步更新文本域内容
内容的提问来源于stack exchange,提问作者L.Calvin
相关产品推荐
相关产品推荐

