多次初始化Select2后首个.item_box元素被重置的修复求助
问题修复:Select2克隆后原有实例失效
问题现象
页面加载时首个.item_box的Select2初始化成功,但点击#addnewitem添加克隆行后,原有Select2被重置为普通选择框,仅新添加的选择框正常初始化。
问题根源
- 模板元素位置错误:模板
<tr id="items_sample">放在了可见的<tbody id="items">中,页面加载时被误初始化Select2,克隆时会带入Select2修改后的DOM痕迹。 - 重复ID冲突:克隆后的选择框与原有选择框ID完全相同,浏览器无法处理重复ID的DOM元素,导致原有Select2实例被破坏。
- 冗余的class修改:强行修改新添加选择框的class,不仅逻辑多余,还可能干扰Select2的事件绑定逻辑。
修复方案
修改后的HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /> <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script> <input type="button" value="addnewitem" id="addnewitem"> <!-- 隐藏的模板容器,避免被误初始化或渲染 --> <div style="display: none;"> <tr id="items_sample"> <td> <select name="items[]['inventory_id']" class="item_box w-full rounded border-[1.5px] border-stroke bg-transparent py-3 px-5 font-medium outline-none transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input dark:focus:border-primary"> <option value="" disabled selected>Select Item</option> <option value="1">Option 1</option> <option value="2">Option 2</option> <option value="3">Option 3</option> <!-- @foreach($inventories as $inventory) <option value="{{ $inventory->id }}">{{ $inventory->name }}</option> @endforeach --> </select> </td> <td> <input type="number" name="items[]['qty']" class="w-full rounded border-[1.5px] border-stroke bg-transparent py-3 px-5 font-medium outline-none transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input dark:focus:border-primary"> </td> <td> <input type="number" name="items[]['price']" readonly class="w-full rounded border-[1.5px] border-stroke bg-transparent py-3 px-5 font-medium outline-none transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input dark:focus:border-primary"> </td> <td> <input type="number" name="items[]['total']" readonly class="w-full rounded border-[1.5px] border-stroke bg-transparent py-3 px-5 font-medium outline-none transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input dark:focus:border-primary"> </td> <td> <center><a href="javascript:void(0)" onClick="removeItem(this)" class="hover:text-primary" title="Remove Item"><i class="fi fi-rr-trash"></i></a></center> </td> </tr> </div> <table class="mt-2.5"> <thead> <tr> <th>Item Name</th> <th>Item Qty</th> <th>Item Price</th> <th>Item Total</th> <th>Action</th> </tr> </thead> <tbody id="items"> <!-- 初始行通过JS动态添加 --> </tbody> <tfoot> <tr> <td colspan="3"><b>Total</b></td> <td colspan="2"><b id="total">Rp 0,00</b></td> </tr> </tfoot> </table>
修改后的JS代码
var items_sample = null; $(document).ready(function() { items_sample = $("#items_sample").html(); // 页面加载时添加初始行 addNewItem(); }); $("#addnewitem").click(addNewItem); // 封装添加行的逻辑,保证初始行和新行逻辑统一 function addNewItem() { $("#items").append("<tr>" + items_sample + "</tr>"); var current_item = $("#items").children().last(); // 仅初始化新添加的选择框 current_item.find(".item_box").select2(); } // 移除行的函数(保留原有逻辑) function removeItem(el) { $(el).closest("tr").remove(); // 可选:这里可以添加总价重新计算的逻辑 }
关键修复点
- 隔离模板:将模板放在隐藏容器中,避免页面加载时被误初始化Select2,保证克隆的是干净的原始HTML。
- 移除重复ID:删除模板中元素的ID(表单提交仅需name属性即可,ID非必需),避免DOM重复ID导致的异常。
- 统一逻辑:封装添加行的函数,初始行和新行都通过该函数添加,保证Select2初始化逻辑一致。
- 简化操作:去掉不必要的class修改,直接针对新添加的选择框初始化Select2,避免干扰原有实例。
内容的提问来源于stack exchange,提问作者user19591044
相关产品推荐
相关产品推荐

