Ember.js组件中Bootstrap标签页事件处理器失效问题
解决Ember.js中Bootstrap标签页
shown.bs.tab事件不触发的问题 这种情况我碰到过好几次,通常是事件绑定时机和Bootstrap初始化节奏不匹配或者直接绑定动态元素导致事件丢失引起的。下面给你几个针对性的解决办法,按优先级推荐:
1. 改用事件委托绑定事件
Bootstrap初始化标签页时可能会对DOM元素做一些隐式处理,直接绑定到a[data-toggle="tab"]上的事件容易失效。换成事件委托,把事件绑定到组件根元素上,就能确保事件被正确捕获:
didInsertElement() { this._super(...arguments); // 绑定到组件根元素,委托给目标标签页链接 this.$().on('shown.bs.tab', 'a[data-toggle="tab"]', (e) => { console.log('TAB SHOWN....'); console.log(e); }); } // 组件销毁时记得解绑事件,避免内存泄漏 willDestroyElement() { this._super(...arguments); this.$().off('shown.bs.tab'); }
2. 手动初始化Bootstrap标签页后再绑定事件
有时候Ember渲染完成后,Bootstrap并没有自动完成标签页的初始化,这时候需要手动触发初始化,再绑定事件:
didInsertElement() { this._super(...arguments); // 先手动初始化Bootstrap标签页组件 this.$('a[data-toggle="tab"]').tab(); // 再绑定shown事件 this.$('a[data-toggle="tab"]').on('shown.bs.tab', (e) => { console.log('TAB SHOWN....'); console.log(e); }); }
3. 借助Ember Run Loop确保DOM完全就绪
如果上面两种方法都没效果,可能是didInsertElement执行时DOM还没完全稳定(虽然这个钩子本身是元素插入DOM后触发,但Bootstrap的初始化可能依赖更晚的渲染阶段)。可以把绑定逻辑放到afterRender队列里:
didInsertElement() { this._super(...arguments); Ember.run.scheduleOnce('afterRender', this, function() { this.$('a[data-toggle="tab"]').on('shown.bs.tab', (e) => { console.log('TAB SHOWN....'); console.log(e); }); }); }
小排查点
你已经打印过this.$("a[data-toggle='tab']"),可以再确认下返回的jQuery对象长度是否大于0,确保元素确实被选中了。既然控制台执行代码有效,说明事件本身没问题,核心就是绑定时机和上下文的问题。
内容的提问来源于stack exchange,提问作者Muhammad Aamir
相关产品推荐
相关产品推荐

