如何实现类似jQuery的$(selector).on形式事件监听调用
实现类似jQuery的链式调用
$(selector).on() 没问题!要把独立的$和on改成$(selector).on()的调用形式,核心是让$返回一个包裹了DOM元素的自定义对象,这样我们就能给这个对象添加on方法,实现链式调用。下面是具体的改造方案:
完整改造代码
// 定义一个包装类,用来封装DOM元素和自定义方法 function DOMWrap(elem) { this.element = elem; } // 给包装类的原型添加on方法,所有实例都能调用 DOMWrap.prototype.on = function(event, callback, capture = false) { // 未选中元素时返回自身,保持链式调用的连贯性 if (!this.element) return this; this.element.addEventListener(event, callback, capture); return this; // 支持链式调用,比如 $(selector).on(...).on(...) }; // 重写$函数,返回包装类的实例 function $(selector, scope = document) { const elem = scope.querySelector(selector); return new DOMWrap(elem); }
改造思路详解
1. 为什么不能直接返回原生DOM元素?
原生DOM元素(比如div、button)的原型链里没有我们自定义的on方法,直接返回它的话,调用.on()会抛出错误。我们需要用自定义对象包裹DOM元素,在这个对象的原型上拓展方法。
2. 包装类的核心作用
DOMWrap类的实例会把选中的DOM元素存在this.element属性中,然后我们给它的原型添加on方法,这样每个$返回的实例都能调用.on()方法。
3. 支持链式调用的小技巧
在on方法末尾加上return this,这样调用完.on()后还能继续调用其他自定义方法(比如后续拓展off方法时,就能写$(selector).on(...).off(...))。
扩展:支持多选元素批量绑定
如果需要像jQuery一样选择多个元素并批量绑定事件,可以稍微修改代码:
function DOMWrap(elements) { this.elements = elements; } DOMWrap.prototype.on = function(event, callback, capture = false) { this.elements.forEach(elem => { elem.addEventListener(event, callback, capture); }); return this; }; function $(selector, scope = document) { const elements = Array.from(scope.querySelectorAll(selector)); return new DOMWrap(elements); }
这样改造后,你就能完全用$(selector).on('click', function() { /* 事件逻辑 */ })的形式来绑定事件啦!
内容的提问来源于stack exchange,提问作者cotut
相关产品推荐
相关产品推荐

