使用jQuery克隆Select下拉框后选项无法启用的技术咨询
解决MDB Select克隆后无法交互的问题
看起来你遇到的是MDB(Material Design Bootstrap)下拉框克隆后未初始化导致的功能异常——因为MDB的mdb-select不是原生下拉框,它是通过JavaScript把原生select转换成带Material Design样式的交互组件,单纯克隆DOM结构不会复制它的交互逻辑,所以才会出现“类似禁用”的状态。
下面是针对你的代码的修复方案:
核心问题分析
- MDB的
mdb-select依赖JS初始化来绑定点击、展开等交互事件,克隆DOM只是复制了静态HTML,没有触发初始化。 clone(true)虽然复制了事件,但MDB的组件实例是绑定在原始元素上的,克隆后的元素无法复用这些实例。- 你的DOM操作过于零散,多次重复查找容器的最后子元素,容易出错且影响性能。
修复后的代码
HTML部分(保持不变)
<div id="dvlstBusinessUnitAndRoles"> <div class="row mt-5" id="dvRegion1"> <div class="col-xl-3"> <select class="mdb-select md-form colorful-select dropdown-primary" name="ddlProjectRegion" id="ddlProjectRegion1"> <option value="" disabled selected>Select Region(s)</option> </select> <label>Select Region(s)</label> </div> <div class="col-xl-3"> <select class="mdb-select md-form colorful-select dropdown-primary" name="ddlRoles" id="ddlRoles1"> <option value="" disabled selected>Select Role(s) </option> </select> <label>Select Role(s)</label> </div> <div class="col-xl-3"> <div class="pt-4"> <input type="checkbox" class="form-check-input" id="limitaccess"> <label class="form-check-label" for="limitaccess"> Primary Region </label> <a href="#" id="hrefRegion" onclick="AddNewRow();" class="note"> <img id="imgNewRow" src="~/Content/images/plus-g.png" /> </a> </div> </div> </div> </div>
修改后的AddNewRow函数
function AddNewRow() { const imgSource = '/Content/images/cross-g.png'; const count = $("div[id^='dvRegion']").length + 1; const newId = 'dvRegion' + count; const newddlRegionId = 'ddlProjectRegion' + count; const newddlRoleId = 'ddlRoles' + count; const chkId = 'limitaccess' + count; // 1. 克隆原始行,先不添加到DOM,在内存中修改属性(减少DOM操作次数) const clonedRow = $("#dvRegion1").clone(false); // 不用clone(true),后续重新初始化组件即可绑定事件 clonedRow.attr('id', newId); // 2. 修改区域下拉框的ID、name,并重置选中状态 const regionSelect = clonedRow.find('[name="ddlProjectRegion"]'); regionSelect.attr({ id: newddlRegionId, name: newddlRegionId }).val(''); // 重置默认提示选项的状态 regionSelect.find('option:first').prop({ disabled: true, selected: true }); // 3. 修改角色下拉框的ID、name,重置选中状态 const roleSelect = clonedRow.find('[name="ddlRoles"]'); roleSelect.attr({ id: newddlRoleId, name: newddlRoleId }).val(''); roleSelect.find('option:first').prop({ disabled: true, selected: true }); // 4. 修改复选框和标签的关联ID const checkbox = clonedRow.find('#limitaccess'); checkbox.attr('id', chkId); clonedRow.find('.form-check-label').attr('for', chkId); // 5. 修改按钮的图片和点击事件(替换内联onclick为jQuery绑定,更可靠) const actionBtn = clonedRow.find('#hrefRegion'); actionBtn.off('click').on('click', function(e) { e.preventDefault(); DeleteRow(newId); }); clonedRow.find('#imgNewRow') .attr("src", imgSource) .attr("id", 'imgDelete'); // 6. 将修改好的克隆行添加到容器 clonedRow.appendTo('#dvlstBusinessUnitAndRoles'); // 7. 关键步骤:重新初始化新添加的MDB select组件 clonedRow.find('.mdb-select').materialSelect(); // 新版MDB可能需要用.mdbSelect(),请根据你的版本调整 // 滚动到页面底部 $("html, body").animate({ scrollTop: $(document).height() }, 1000); } // 补充DeleteRow函数示例(删除时销毁组件实例,避免内存泄漏) function DeleteRow(rowId) { $('#' + rowId).find('.mdb-select').materialSelect('destroy'); $('#' + rowId).remove(); }
关键修复点说明
- 减少DOM操作:先在内存中完成所有属性修改,再添加到DOM,比多次查找容器子元素更高效且不易出错。
- 不复制原始事件:用
clone(false)代替clone(true),因为MDB的组件事件是通过初始化绑定的,复制旧事件可能导致冲突。 - 重置下拉框状态:确保克隆后的下拉框回到初始的未选中状态,避免继承原始元素的状态。
- 重新初始化组件:这是解决问题的核心!克隆后必须调用
materialSelect()(或对应版本的方法)来激活新下拉框的交互功能。 - 事件绑定优化:把内联
onclick改成jQuery的on('click'),更灵活且避免ID变化带来的问题。
如果你的MDB版本是较新的,可能需要把materialSelect()换成mdbSelect(),可以查看MDB官方文档确认对应的初始化方法。
内容的提问来源于stack exchange,提问作者How To Learn
相关产品推荐
相关产品推荐

