如何使用原生JavaScript结合Materialize刷新/更新Select组件
解决Materialize框架下原生JS动态更新Select选项后UI不同步的问题
我明白你的问题了——你已经能通过原生JS修改<select>的选项,但Materialize渲染的下拉菜单没同步更新。这是因为Materialize的Select组件会把原生<select>隐藏,生成一套自定义的UI结构,直接修改原生元素不会自动触发UI更新,必须手动调用Materialize的API来同步。
下面是具体的解决方案:
步骤1:保存Select组件的Materialize实例
首先,在DOM加载完成初始化Select时,把目标Select对应的实例保存下来,方便后续调用更新方法:
// 全局变量保存目标select的Materialize实例 let voteSelectInstance; document.addEventListener('DOMContentLoaded', function() { // 初始化页面上所有select const selectElements = document.querySelectorAll('select'); const instances = M.FormSelect.init(selectElements); // 筛选出id为voteNoList的select实例 voteSelectInstance = instances.find(instance => instance.el.id === 'voteNoList'); });
步骤2:修改选项后调用update()方法
不管是添加还是删除选项,在修改原生<select>的DOM之后,调用实例的update()方法,让Materialize重新读取选项并刷新UI:
完善后的添加选项函数:
function PersonInfo(){ const selectOption = document.createElement("option"); selectOption.text = "Text55"; selectOption.value = "myvalue55"; const selectList = document.getElementById("voteNoList"); selectList.appendChild(selectOption); // 关键:更新Materialize的select组件UI voteSelectInstance.update(); }
完善后的删除选项函数:
function PersonDelete(){ const selectList = document.getElementById("voteNoList"); for (let i = 0; i < selectList.length; i++){ if (selectList.options[i].value === "2"){ selectList.remove(i); break; } } // 关键:更新Materialize的select组件UI voteSelectInstance.update(); }
为什么这样有效?
Materialize的Select组件工作机制是:
- 隐藏原生的
<select>元素 - 基于原生元素的选项生成自定义的下拉菜单DOM
- 当用户交互时,同步修改原生元素的值
所以当你直接修改原生<select>的选项时,Materialize的自定义UI并不知道这些变化,update()方法会让组件重新读取原生元素的选项列表,重新渲染自定义下拉菜单,从而实现UI和原生元素的同步。
如果你不想保存实例,也可以每次修改后重新初始化该select,但保存实例的方式更高效:
// 替代方案:每次修改后重新初始化 const selectList = document.getElementById("voteNoList"); // 先销毁现有实例(可选,防止重复初始化) M.FormSelect.getInstance(selectList)?.destroy(); // 重新初始化 M.FormSelect.init(selectList);
这样就能实现你想要的“点击按钮增减Select选项,UI同步更新”的效果了。
内容的提问来源于stack exchange,提问作者WFTsai
相关产品推荐
相关产品推荐

