如何用jQuery替换多个select元素并避免重复代码?
优化方案:避免重复创建相同的Select元素
思路
不用在HTML里重复编写两个完全一致的<select class="dashboard-select">,只需要定义一个模板(可以写在HTML里隐藏,或者直接用JS动态构造),然后通过克隆/创建模板的方式完成替换,彻底消除代码重复。
方案1:HTML保留单个模板+JS克隆替换
优化后的HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="view view-dashboard view-id-dashboard view-display-id-embed_1"> <p> First div, contains lots of things, I only kept the select dropdown to be replaced. </p> <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select"> <option value="ASC">Asc</option> <option value="DESC" selected="selected">Desc</option> </select> </div> <div class="view view-dashboard view-id-dashboard view-display-id-embed_2"> <p> Second div, contains lots of things, again only kept the relevant select below. </p> <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select"> <option value="ASC">Asc</option> <option value="DESC" selected="selected">Desc</option> </select> </div> <!-- 单个模板,用hidden隐藏不影响页面显示 --> <select class="dashboard-select form-select form-element form-element--type-select" hidden> <option value="edited_by_me">Edited by me</option> <option value="created_by_me">Created by me</option> </select>
优化后的JS
let $displays = $('.view-id-dashboard'); $displays.eq(1).toggle(); // 获取模板select const $selectTemplate = $('.dashboard-select'); $('select[data-drupal-selector="edit-sort-order"]').each(function() { $("label[for='" + this.id + "']").text('Edited/Created by me'); // 克隆模板,移除hidden属性后替换原元素 const $newSelect = $selectTemplate.clone().removeAttr('hidden'); $(this).replaceWith($newSelect); }); // 给所有替换后的select绑定事件(用全局选择器确保动态生成的元素也能触发) $('.dashboard-select').on('change', function() { $('.dashboard-select').val(this.value); $displays.toggle(); });
方案2:完全用JS动态生成Select(更简洁)
如果不想在HTML里留模板,可以直接用JS构造Select元素,彻底摆脱冗余代码:
优化后的HTML(移除重复的select)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="view view-dashboard view-id-dashboard view-display-id-embed_1"> <p> First div, contains lots of things, I only kept the select dropdown to be replaced. </p> <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select"> <option value="ASC">Asc</option> <option value="DESC" selected="selected">Desc</option> </select> </div> <div class="view view-dashboard view-id-dashboard view-display-id-embed_2"> <p> Second div, contains lots of things, again only kept the relevant select below. </p> <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select"> <option value="ASC">Asc</option> <option value="DESC" selected="selected">Desc</option> </select> </div>
优化后的JS
let $displays = $('.view-id-dashboard'); $displays.eq(1).toggle(); // 封装创建select的函数 const createDashboardSelect = () => { return $('<select>', { class: 'dashboard-select form-select form-element form-element--type-select' }).append( $('<option>', { value: 'edited_by_me', text: 'Edited by me' }), $('<option>', { value: 'created_by_me', text: 'Created by me' }) ); }; $('select[data-drupal-selector="edit-sort-order"]').each(function() { $("label[for='" + this.id + "']").text('Edited/Created by me'); // 调用函数生成新select,替换原元素 $(this).replaceWith(createDashboardSelect()); }); // 绑定事件(也可以用事件委托更稳妥:$(document).on('change', '.dashboard-select', function() {...})) $('.dashboard-select').on('change', function() { $('.dashboard-select').val(this.value); $displays.toggle(); });
补充说明
之前尝试.clone()失败可能的原因:
- 克隆后没有移除模板的
hidden属性,导致替换后元素不可见 - 初始的
$selects变量指向的是页面上原有的模板元素,替换后这些元素已经被移出DOM,后续绑定事件时失效 - 没有正确使用
clone(true)(如果模板上预先绑定了事件,需要加true来复制事件处理函数;但本案例事件是后续全局绑定的,所以不需要)
用上述两种方案都能彻底解决代码重复问题,同时保留原有功能。
内容的提问来源于stack exchange,提问作者chx
相关产品推荐
相关产品推荐

