概述

JavaScript中getElementsByClassName()方法IE8及以下不支持。本文通过使用正则表达式实

现1个兼容方案。

本文内容分为3个部分。

  • 浏览器原生getElementsByClassName()功能和用法。
  • 兼容方案用到的正则表达式理解。
  • 完整代码示例。

大家不用一听到正则表达式就慌,本方案用到的正则表达式并不复杂,而且我也会详细解释的。

原生getElementsByClassName

语法

var elements = document.getElementsByClassName(names);
var elements = rootElement.getElementsByClassName(names);
  • names可以是多个类名,用空格分开。
  • 返回值elements是一个元素数组。
  • 若果用rootElement调用,则只在该元素下搜索。

示例

// 返回所有类名是test的元素
document.getElementsByClassName('test'); // 返回所有同时具有red和test类的元素
document.getElementsByClassName('red test'); // 在id为main这个元素里,拿出所有具有类名test的元素
document.getElementById('main').getElementsByClassName('test'); // 直接拿到类名为test的第一个元素
var testTarget = document.getElementsByClassName("test")[0];

正则表达式简要分析

实现兼容方案的整体思路是:使用getElementsByTagName("*")全部元素,然后循环遍历把这些

元素的类名都拿出来,拿出这些类名之后,最关键的问题就是判断,这些类名是不是符合我要查询的

类名,这就要用到正则表达式来比较,请看下面的代码:

function getElementsByClassName(names, rootElement) {
if (!rootElement) {
rootElement = document;
} var classElements = [];
var allElements = rootElement.getElementsByTagName("*");
// (^|\s)names(\s|$)
pattern = new RegExp("(^|\\s)" + names + "(\\s|$)"); for (var i = 0, j = 0; i < allElements.length; i++) {
if (pattern.test(allElements[i].className)) {
console.log(allElements[i]);
classElements[j] = allElements[i];
j++;
}
} return classElements;
}

上面的代码最难理解的就是正则表达式部分。首先,我默认你已经有一点点正则表达式基础,如果听

都没听过正则表达式,可以考虑看看我写的这篇正则表达式 - JavaScript描述

http://www.cnblogs.com/asheng2016/p/7401391.html

OK,首先我们梳理一下代码逻辑,看看我们需要什么样的正则表达式。假设我们要查找的类名有下面

这几种情况:"ab", "ab cd", "ab cd ef", "ab cd ef gh"。也就是说,如果我们能找到这个类

并成功匹配,那么这个类要么在开头,要么在中间,要么在末尾,只有这三种情况。

我们使用(^|\s)names(\s|$)这个正则表达式就可以实现对上述三种情况的匹配,其中names

变量就表示类名字符串的所有情况(3种)。该正则表达式的图形化含义如下:

根据图像我们理解该正则表达式,首先中间是已知的类名,这没问题,然后就是这个类名的两边可能

存在的情况,可能是开头+类名+结尾、空格+类名+空格、开头+类名+空格等。

\s 表示匹配类名,并且因为在字符串中\也有转义的功能,所以在new RegExp中写成\\

完整函数及测试

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>getElementsByClassName 兼容</title>
</head>
<body> <p><pre>(^|\s)names(\s|$)</pre></p>
<div class="ab cd">ab cd</div>
<div class="a c">a c</div>
<script> function getElementsByClassName(names, rootElement) {
if (!rootElement) {
rootElement = document;
} if (rootElement.getElementsByClassName) {
// console.log("走的是原生方法");
return rootElement.getElementsByClassName(names);
} // console.log("走的是兼容方案");
var classElements = [];
var allElements = rootElement.getElementsByTagName("*");
pattern = new RegExp("(^|\\s)" + names + "(\\s|$)"); for (var i = 0, j = 0; i < allElements.length; i++) {
if (pattern.test(allElements[i].className)) {
classElements[j] = allElements[i];
j++;
}
} return classElements;
} var mt = getElementsByClassName("ab");
console.log(mt[0].className); // "ab cd" var mt2 = getElementsByClassName("a");
console.log(mt2[0].className); // "a c" var mt3 = getElementsByClassName("ac");
console.log(mt3); // [] // 亲测在IE8下可用
</script>
</body>
</html>

参考链接

http://regexper.com

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName

getElementsByClassName - 兼容详细介绍的更多相关文章

  1. linux配置网卡IP地址命令详细介绍及一些常用网络配置命令

    linux配置网卡IP地址命令详细介绍及一些常用网络配置命令2010-- 个评论 收藏 我要投稿 Linux命令行下配置IP地址不像图形界面下那么方 便,完全需要我们手动配置,下面就给大家介绍几种配置 ...

  2. 【转载】硬盘MBR详细介绍

    原文地址:http://blog.chinaunix.net/uid-15007890-id-106892.html 硬盘MBR详细介绍      硬盘是现在计算机上最常用的存储器之一.我们都知道,计 ...

  3. Android manifest之manifest标签详细介绍

    AndroidManifest详细介绍 本文主要对AndroidManifest.xml文件中各个标签进行说明.索引如下: 概要PART--01 manifest标签PART--02 安全机制和per ...

  4. 详细介绍android rom移植知识普及

    详细介绍android rom移植知识普及 最近接到很多兄弟们的求助,也回答过无数个和下面这个问题类似的问题: 如何编译android 原生代码得到一个rom,然后跑到某某手机上. 鉴于很多兄弟对这块 ...

  5. vue对比其他框架详细介绍

    vue对比其他框架详细介绍 对比其他框架 — Vue.jshttps://cn.vuejs.org/v2/guide/comparison.html React React 和 Vue 有许多相似之处 ...

  6. Oracle11g服务详细介绍

    Oracle11g服务详细介绍及哪些服务是必须开启的? Oracle ORCL VSS Writer Service Oracle卷映射拷贝写入服务,VSS(Volume Shadow Copy Se ...

  7. 详细介绍Redis的几种数据结构以及使用注意事项(转)

    原文:详细介绍Redis的几种数据结构以及使用注意事项 1. Overview 1.1 资料 <The Little Redis Book>,最好的入门小册子,可以先于一切文档之前看,免费 ...

  8. Tkinter 控件详细介绍

    Tkinter 控件详细介绍 1.Button 按钮.类似标签,但提供额外的功能,例如鼠标掠过.按下.释放以及键盘操作/事件 2.Canvas 画布.提供绘图功能(直线.椭圆.多边形.矩形) ;可以包 ...

  9. kvm详细介绍

    KVM详解,太详细太深入了,经典 2016-07-18 19:56:38 分类: 虚拟化 原文地址:KVM详解,太详细太深入了,经典 作者:zzjlzx KVM 介绍(1):简介及安装 http:// ...

随机推荐

  1. CentOS/Linux 网卡设置 IP地址配置永久生效

    CentOS/Linux下设置IP地址 1.临时生效设置 1.1修改IP地址 #ifconfig eth0 192.168.100.100 1.2修改网关地址 #route add default g ...

  2. android定义dialog

    对于一些特殊的dialog,我们想自定义一些特殊的样式.这时候假设使用dialog指定的一些功能.是无法实现我们的需求的,这时候就要自己去定制实现dialog了,如今这个样例是我从stackoverf ...

  3. android camera之nv21旋转

    这周做的一个android的camera开发,需要获取到视频帧数据,并且需要是nv21格式的byte数组,并且视频帧的图像需要是正方向的.和android相机打过交道的都清楚,android的came ...

  4. python read文件内容的iter方式

    遍历file的方式 iter(lambda: f.read(4096), "")等价与while True: data = f.read(4096) if not data: br ...

  5. 封装常用的selenium方法

    package com.yk.userlive.base; import java.net.MalformedURLException;import java.net.URL;import java. ...

  6. MFC绘图相关GDI工具对象和函数介绍

    在利用MFC进行界面编程时,除了需要熟悉各种类型控件的操作外,还会经常遇到图形绘制和显示的问题,比如时频分析界面.图像处理界面等.处理这些软件界面开发问题时,不可避免地需要用到一系列GDI工具对象和相 ...

  7. RNN与BPTT (公式甚多)

    前言: 现在深度学习是一个潮流,同时,导师也给自己制定了深度学习的方向.在一次组会中,自己讲解了RNN的基本用法,和RNN数学原理的推导.以下是自己根据当时的PPT总结下来的东西.

  8. 怎样看K线图(实图详解)

    K线图由开盘价.收盘价.最高价和最低价组成.       上面两种图叫作实体红K线和实体黑K线,实体红K线意味买力强劲,市场有强烈的做多欲望,此时可持股待涨.实体黑K线则代表市场完全进入恐惧状态,如果 ...

  9. 嵌入式开发之davinci--- 8148/8168/8127 中的图像采集格式Sensor信号输出YUV、RGB、RAW DATA、JPEG 4种方式区别

    简单来说,YUV: luma (Y) + chroma (UV) 格式, 一般情况下sensor支持YUV422格式,即数据格式是按Y-U-Y-V次序输出的RGB: 传统的红绿蓝格式,比如RGB565 ...

  10. 嵌入式驱动开发之spi---spi串口通信调试

    一. 概念 SPI是 Serial Peripheral Interface(串型外部接口)的缩写.SPI接口有4根PIN脚,分别是:          * SPICLK     : 用于传输数据的同 ...