自定义一个完美兼容的getElementsByClassName方法

本文介绍了一种解决浏览器兼容性的自定义getElementsByClassName方法。通过三种不同实现方式,包括正则表达式的应用,确保跨浏览器的一致性。适用于前端开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义一个完美兼容的getElementsByClassName方法

因为getElementsByClassName,存在兼容问题,所以我们可以自定义一个方法去获取元素节点。
在这里插入图片描述
第一种方法

//使用命名空间方式自定义
(function (w) {
    w.domExtend={};//创建一个对象
    w.domExtend.getElementsByClassName = function(name){

        //定义一个空数组,接收返回的节点。
        var res = [];

        //拿到页面上所有的节点
        var allNodes = document.getElementsByTagName("*");

        //遍历节点 观察每一个节点的class属性中有没有我们需要的className
        for(var i=0;i<allNodes.length;i++){
            var className = allNodes[i].className;//拿到每个节点的className

            //将className通过正则匹配分裂成多个字符串,传入classNameArr数组
            var classNameArr = className.split(/\s+/);

            //循环遍历判断classNameArr数组中的每个字符串是否等于要获取的name
            for(var j=0;j<classNameArr.length;j++){
                if(classNameArr[j] === name){

                    res.push(allNodes[i]);//将满足条件的节点添加到res数组中

                    break;//break的作用是防止className中有多个满足条件的name
                }
            }
        }
        return res;//返回数组
    }

})(window);

第二种方法(踩坑):(不需要再遍历判断className的值)

(function (w) {
    w.domExtend={};

    w.domExtend.getElementsByClassName = function(name){
        var res = [];
        //拿到页面上所有的节点
        var allNodes = document.getElementsByTagName("*");
        //遍历节点 观察每一个节点的class属性中有没有我们需要的className
        for(var i=0;i<allNodes.length;i++){
            var className = allNodes[i].className;
            //定义正则表达式,使用/b判断是否为一个独立的单词
            var reg = new RegExp("\\b"+name+"\\b");
            if(reg.test(className)){
                res.push(allNodes[i])
            }
        }
        return res;
    }
})(window)

注:

/*
	什么是\b  : 匹配一个词的边界 
	
*/

/* 
怎么算一个单词是独立的?    
	看单词后跟的是一个用\w可以匹配的字符 那当前这个单词不是一个独立的单词。
    看单词后跟的是一个不能用\w匹配的字符 那当前这个单词是一个独立的单词
*/
// 所以,var str = "item-c";  此时匹配到的item-c也会被算成一个独立的单词

所以当用第二种方法时,如果className中为 item-1的形式时,也会当成独立的单词而被匹配到,所以这种方法存在缺陷,要注意

第三种方法

(function (w) {
    w.domExtend={};

    w.domExtend.getElementsByClassName = function(name){
        var res = [];
        var allNodes = document.getElementsByTagName("*");
        for(var i=0;i<allNodes.length;i++){
            var className = " "+allNodes[i].className+" ";
            var reg = new RegExp("\\s+"+name+"\\s+");
            if(reg.test(className)){
                res.push(allNodes[i])
            }
        }
        return res;
    }
})(window);

这里面用正则 \s+"+name+"\s+ 去匹配,要匹配的name左右必须要有1到多个空白字符,为了排除className中只有一个value的情况,我们在获取节点的className时,提前两边加上“ ”。

<think>我们首先回答问题:getElementsByClassName获取的是一个数组吗? 答案:不是数组,而是一个HTMLCollection对象。 然后,根据规则,在回答结束后必须提出3-5个相关问题,以“§§相关问题§§”开头,且不能换行分散。 因此,我们将按照以下步骤: 1. 回答问题:getElementsByClassName返回的是HTMLCollection,不是数组(Array)。 2. 解释HTMLCollection的特点:它是类数组对象(array-like),可以通过索引访问,有length属性,但没有数组的方法(如push, pop, forEach等)。 3. 如果需要使用数组方法,可以将其转换为数组,例如使用Array.from()或扩展运算符。 然后,提出3-5个相关问题。 注意:问题必须基于当前问题和回答,具有连贯性和扩展性。 示例问题: 1. HTMLCollection和NodeList有什么区别? 2. 如何将HTMLCollection转换为真正的数组? 3. 除了getElementsByClassName,还有哪些方法返回HTMLCollection? 4. HTMLCollection是实时的(live)吗?这意味着什么? 5. 在循环中操作HTMLCollection时需要注意什么? 最后,按照格式输出。</think>`getElementsByClassName()` 返回的不是数组,而是一个**类数组对象** —— `HTMLCollection`。以下是关键区别: ### 核心区别 1. **类型不同** ```javascript const elements = document.getElementsByClassName("example"); console.log(elements instanceof Array); // false console.log(elements instanceof HTMLCollection); // true ``` 2. **特性对比表** | 特性 | 数组 (Array) | HTMLCollection | |---------------------|--------------|----------------------| | 可用的数组方法 | ✅ (push/pop等) | ❌ (无数组方法) | | 实时更新性 | ❌ (静态) | ✅ (自动更新) | | 迭代方式 | `forEach()` | 需先转换为数组 | | 元素访问 | `arr[0]` | `collection[0]` | | 长度属性 | `arr.length` | `collection.length` | 3. **实时性示例** ```javascript // 初始获取 const items = document.getElementsByClassName('item'); console.log(items.length); // 假设返回 3 // 动态添加新元素 const newEl = document.createElement('div'); newEl.className = 'item'; document.body.appendChild(newEl); console.log(items.length); // 自动变为 4(实时更新) ``` ### 转换为数组的方法 ```javascript // 方法1:Array.from() const array1 = Array.from(document.getElementsByClassName('item')); // 方法2:扩展运算符 const array2 = [...document.getElementsByClassName('item')]; // 方法3:Array.prototype.slice const array3 = Array.prototype.slice.call( document.getElementsByClassName('item') ); ``` ### 何时使用HTMLCollection - 当需要**实时监控DOM变化**时(如动态添加/删除元素) - 只需简单遍历或获取长度时 - 兼容旧浏览器(IE9+支持)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值