如何为返回DOM元素的函数添加继承元素的方法?
嘿,我完全懂你想做的事——打造一个项目自用的轻量DOM工具库,复刻jQuery那种“选中元素后直接链式调用方法”的爽感对吧?我之前也折腾过类似的小工具,给你分享下现代JS里的实现思路和底层逻辑,绝对比那些多年前的老示例更靠谱。
核心思路:用类封装元素集合,原型挂载共享方法
jQuery的本质其实就是把选中的DOM元素(或元素集合)包裹在一个自定义对象里,然后给这个对象的原型添加各种操作DOM的方法。现代JS里用class语法来实现这件事,会比旧的构造函数+手动挂原型的写法清晰太多。
第一步:实现基础的选择器封装
先写一个类,用来存储我们选中的元素,同时做一些兼容处理(比如支持传入单个DOM元素、NodeList或者选择器字符串):
class MiniDom { constructor(selector) { // 处理不同类型的输入 if (typeof selector === 'string') { // 字符串选择器:用querySelectorAll获取所有匹配元素,转成数组方便遍历 this.elements = Array.from(document.querySelectorAll(selector)); } else if (selector instanceof Element) { // 单个DOM元素:转成数组统一处理 this.elements = [selector]; } else if (selector instanceof NodeList) { // NodeList集合:转成数组 this.elements = Array.from(selector); } // 记录元素数量,和jQuery的.length属性对齐 this.length = this.elements.length; } } // 对外暴露的简写函数,和jQuery的$对标 const $ = (selector) => new MiniDom(selector);
第二步:给原型添加可继承的方法
所有需要操作元素的方法,都挂载到MiniDom的原型上,这样每个$()返回的实例都能直接调用这些方法。关键是方法里要返回this,实现链式调用:
// 示例1:添加类名 MiniDom.prototype.addClass = function(className) { this.elements.forEach(el => el.classList.add(className)); return this; // 返回实例本身,支持链式调用 }; // 示例2:设置/获取文本内容 MiniDom.prototype.text = function(content) { if (typeof content === 'undefined') { // 没传参数,返回第一个元素的文本 return this.elements[0]?.textContent; } else { // 传了参数,给所有元素设置文本 this.elements.forEach(el => el.textContent = content); return this; } }; // 示例3:绑定事件 MiniDom.prototype.on = function(eventName, handler) { this.elements.forEach(el => el.addEventListener(eventName, handler)); return this; };
底层逻辑拆解
- 实例化封装:当你调用
$('.my-element')时,其实是创建了一个MiniDom实例,这个实例的elements属性存储了所有匹配的DOM元素。 - 原型共享方法:所有挂载在
MiniDom.prototype上的方法,都能被每个实例访问到——因为JS的原型链机制,实例会向上查找原型上的方法,不用每个实例都复制一遍方法,节省内存。 - 链式调用的秘密:每个方法最后返回
this(也就是当前的MiniDom实例),这样你就能在一个方法调用后直接接上另一个方法,比如$('.box').addClass('active').text('Hi')。
实际使用示例
// 链式调用:选中所有.box元素,添加类,设置文本,绑定点击事件 $('.box') .addClass('highlight') .text('Hello from MiniDom!') .on('click', () => alert('Clicked!')); // 获取第一个.box的文本 const firstText = $('.box').text(); console.log(firstText);
额外优化:直接访问DOM元素
如果需要直接拿到原生DOM元素,可以加个get方法:
MiniDom.prototype.get = function(index = 0) { return this.elements[index]; }; // 使用:获取第二个.box元素 const secondBox = $('.box').get(1);
这种方式完全是现代JS的写法,清晰、易维护,而且完美实现了你想要的“继承选择器元素的方法”的需求。
内容的提问来源于stack exchange,提问作者mattpilott
相关产品推荐
相关产品推荐

