on()方法失效问题:需在新增元素上执行$(".select").selectmenu()
嘿,我懂你遇到的糟心事了——页面加载时就存在的.select元素能正常用selectmenu()变成样式好看的下拉菜单,但后来动态新增的同款元素就完全没反应,对吧?其实问题出在插件初始化的时机上,跟on()事件委托不是一回事,我给你拆解清楚:
为什么原来的方法没用?
on()是用来给元素绑定事件处理函数的(比如点击、输入这类交互事件),但selectmenu()是jQuery UI的初始化方法——它会把原生的<select>元素转换成带样式的UI组件,这个操作必须在元素已经存在于DOM中的时候执行。页面加载时你调用了一次$(".select").selectmenu(),但新增的元素是后来才出现的,根本没被这个初始化代码覆盖到。
正确的解决步骤
1. 先处理页面已有的元素
页面加载完成后,先给原本就存在的.select做初始化:
$(document).ready(function() { // 初始化页面加载时就存在的.select $(".select").selectmenu(); });
2. 动态添加元素后,立即初始化新元素
不管你是通过点击按钮新增模块,还是AJAX加载内容,在元素被插入DOM之后,马上对新的.select调用selectmenu()。举个实际例子:
假设你是用append添加新的Div11模块:
// 构造新增的HTML内容 var newSelectModule = ` <div class="Div11" > <label>Choisir Une Colonne</label> <select class="select"> <option value="Sum">Somme</option> <option value="Max">Max</option> <option value="Avarage">Moyenne</option> <option value="Min">Min</option> </select> <label>Choisir Une Colonne</label> <select class="select">...</select> </div> `; // 把新模块添加到页面的某个容器里 $("#your-container-id").append(newSelectModule); // 关键:只初始化刚新增的.select,避免重复处理已有的 $("#your-container-id").find(".select").not(".ui-selectmenu-menu").selectmenu();
这里的.not(".ui-selectmenu-menu")是个小技巧——因为selectmenu()会把原生<select>隐藏,生成带ui-selectmenu-menu类的新元素,加这个判断能防止重复初始化已经处理过的下拉菜单。
3. 如果是AJAX加载的内容
要是你的新元素是通过AJAX请求获取的,就在success回调里完成初始化:
$.ajax({ url: "你的数据接口地址", method: "GET", success: function(response) { // 把返回的HTML插入容器 $("#your-container-id").html(response); // 初始化新的.select元素 $("#your-container-id .select").selectmenu(); } });
总结一下
别再纠结on()了,它管的是事件绑定,不是插件初始化。核心就是:元素什么时候出现在DOM里,什么时候就调用一次selectmenu()。这样不管是页面原本的还是后来新增的下拉菜单,都能正常渲染啦!
内容的提问来源于stack exchange,提问作者fatiDev

