自定义一个完美兼容的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时,提前两边加上“ ”。