MaterializeCSS 1.0.0配合jQuery DOM更新后重初始化报instanceof错误
MaterializeCSS 动态生成组件失效与初始化报错解决方案
报错根因
你遇到的Uncaught TypeError: Right-hand side of 'instanceof' is not callable报错通常由三类原因触发:
- 调用初始化方法时,目标动态DOM还未实际插入到文档流中,组件初始化时找不到有效节点
- 对已经初始化完成的组件重复执行初始化逻辑,导致内部实例判断异常
- 你使用的jQuery封装初始化语法和当前MaterializeCSS版本不兼容,v1.0+版本官方已优先推荐原生JS初始化方式
解决方案
1. 保证初始化时机正确
必须在动态生成的弹窗DOM完全插入页面之后再执行组件初始化,示例代码:
// 第一步:渲染弹窗内容插入DOM const modalDom = document.querySelector('#你的弹窗ID') modalDom.querySelector('.modal-content').innerHTML = ` 你的弹窗内容 <input type="text" class="datepicker"> ` // 第二步:再执行组件初始化 const dateEls = modalDom.querySelectorAll('.datepicker') M.Datepicker.init(dateEls, { // 你的自定义配置,例:format: 'yyyy-mm-dd' })
2. 避免重复初始化
如果弹窗会多次打开、内容会反复更新,初始化前先销毁已有实例,避免冲突:
const dateEls = document.querySelectorAll('#你的弹窗ID .datepicker') // 先销毁已存在的实例 dateEls.forEach(el => { const existInstance = M.Datepicker.getInstance(el) if(existInstance) existInstance.destroy() }) // 再执行新的初始化 M.Datepicker.init(dateEls, { /* 配置项 */ })
3. 通用全局初始化方案
如果需要适配所有动态插入的Materialize组件,可以封装通用方法,每次动态内容加载完成后调用即可:
/** * 初始化指定容器内所有未初始化的Materialize组件 * @param {HTMLElement} container 容器节点,默认是整个document */ function initAllMComponents(container = document) { // 按需添加你项目中用到的组件 const components = [ { selector: '.datepicker', initFn: M.Datepicker.init }, { selector: 'select', initFn: M.FormSelect.init }, { selector: '.modal', initFn: M.Modal.init }, { selector: '.tooltipped', initFn: M.Tooltip.init }, { selector: '.dropdown-trigger', initFn: M.Dropdown.init } ] components.forEach(({ selector, initFn }) => { const els = Array.from(container.querySelectorAll(selector)) // 过滤掉已经初始化过的元素,避免重复初始化报错 const uninitEls = els.filter(el => !initFn.getInstance(el)) if (uninitEls.length) initFn(uninitEls) }) } // 动态内容插入后调用即可,例:弹窗内容插入后调用 initAllMComponents(document.querySelector('#你的弹窗ID'))
4. 废弃jQuery初始化写法
停止使用$('.datepicker').datepicker()这类jQuery调用方式,改用官方原生M.组件名.init()的写法即可规避版本兼容导致的instanceof报错。
内容的提问来源于stack exchange,提问作者RoyBlunk
相关产品推荐
相关产品推荐

