zoukankan      html  css  js  c++  java
  • JavaScript通过HTML的class来获取HTML元素的方法总结

    对于js来说,我想每一个刚接触它的人都应该会抱怨:为什么没有一个通过class来获取元素的方法。尽管现在高版本的浏览器已经支持getElementsByClassName()函数,但是对于低版本浏览器来说,还是无法兼容,在脱离其他库的时候,还是得自己封装一个方法。

    方法一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function getByClass1(parent, cls){
      var res = [];  //存放匹配结果的数组
      var ele = parent.getElementsByTagName('*');
      for(var i = 0; i < ele.length; i++){
        if(ele[i].className == cls){
          res.push(ele[i]);
        }
      }
      return res;
    }

    当然class里的值只有一个时,上面的方法没问题,但当值为多个时,就会出现问题。

    1
    2
    3
    4
    5
    <div class="test"></div>
    <div class="test box"></div>
    <script>
      getByClass1(document, 'test');  //只获取到第一个div
    </script>

    方法二

    出现问题的时候,我们会尝试着改进,对于多类名的情况我们可以用正则去匹配是否包含所要查找的class名,于是就出现了下面这种写法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getByClass2(parent, cls){
      var res = [];
      var reg = new RegExp('\b' + cls + '\b', 'i');  //匹配cls是一个独立的单词
      var ele = parent.getElementsByTagName('*');
      for(var i = 0; i < ele.length; i++){
        if(reg.test(ele[i].className)){
          res.push(ele[i]);
        }
      }
      return res;
    }

    这种方法看似可以,解决了getByClass1()的问题,我也用了好长一段时间,但是还会有一个隐藏的bug。看下面的例子:

    1
    2
    3
    4
    5
    6
    <div class="test"></div>
    <div class="test_box"></div>
    <div class="test-box"></div>
    <script>
      getByClass2(document, 'test');  //结果获取到了第一个div和第三个div
    </script> 

    理论上应该只获取到第一个,但是却和我们预期不一样。这个bug源于下面这段代码里的

    1
    var reg = new RegExp('\b' + cls + '\b', 'i');

    我们先来看下在正则中的表示的意思

    是正则表达式规定的一个特殊代码,代表着单词的开头或结尾,也就是单词的分界处。

    通俗点说:就是匹配一个单词(从左边界到右边界)。

    而问题也就出在这里,把除字母、数字、下划线外的其他字符都当成是边界,对于上面的例子中第三个class值为test-box,匹配时,把连字符(-)当作单词边界,所以也匹配了第三个div。

    方法三

    因此我们还需要对上面方法进行进一步改进,这里参考了stackoverflow上提到的一种方法:

    How to Get Element By Class in JavaScript?

    改进后的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getByClass3(parent, cls){
      var res = [];
      var reg = new RegExp(' ' + cls + ' ', 'i');  //匹配cls时,两边需要有空格
      var ele = parent.getElementsByTagName('*');
      for(var i = 0; i < ele.length; i++){
        if(reg.test(' ' + ele[i].className + ' ')){
          res.push(ele[i]);
        }
      }
      return res;
    }

    这种方法舍去了用而采用空格来匹配边界,先在获取到的className值两边加上空格,这样就保证了className里的每个值两边都会有空格,然后再用正则去匹配。

    用这种方法暂时还未发现问题,但是使用时,方法中的单引号内的空格一定不能落下。

    方法四

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getByClass3(parent, cls){
      var res = [];
      var reg = new RegExp('(^|\s)' + cls + '($|\s)', 'i');
      var ele = parent.getElementsByTagName('*');
      for(var i = 0; i < ele.length; i++){
        if(reg.test(ele[i].className)){
          res.push(ele[i]);
        }
      }
      return res;
    }

    空格完全用正则来处理,这样省去了空格容易落下的问题,代码也更美观精简。

    那么这种方法是否就是比较完美的呢,其实不然,下面来看下更优的方案。

    方法五(完美版)

    文章开头已经提到,高版本的浏览器已经支持getElementsByClassName()方法。出于性能考虑,对支持的浏览器使用原生方法势必会更好。而对于低版本的浏览器使用上面的方法四。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function getByClass(parent, cls){
      if(parent.getElementsByClassName){
        return parent.getElementsByClassName(cls);
      }else{
        var res = [];
        var reg = new RegExp(' ' + cls + ' ', 'i')
        var ele = parent.getElementsByTagName('*');
        for(var i = 0; i < ele.length; i++){
          if(reg.test(' ' + ele[i].className + ' ')){
            res.push(ele[i]);
          }
        }
        return res;
      }
    }

    对于js来说,我想每一个刚接触它的人都应该会抱怨:为什么没有一个通过class来获取元素的方法。尽管现在高版本的浏览器已经支持getElementsByClassName()函数,但是对于低版本浏览器来说,还是无法兼容,在脱离其他库的时候,还是得自己封装一个方法。

    方法一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function getByClass1(parent, cls){
      var res = [];  //存放匹配结果的数组
      var ele = parent.getElementsByTagName('*');
      for(var i = 0; i < ele.length; i++){
        if(ele[i].className == cls){
          res.push(ele[i]);
        }
      }
      return res;
    }

    当然class里的值只有一个时,上面的方法没问题,但当值为多个时,就会出现问题。

    1
    2
    3
    4
    5
    <div class="test"></div>
    <div class="test box"></div>
    <script>
      getByClass1(document, 'test');  //只获取到第一个div
    </script>

    方法二

    出现问题的时候,我们会尝试着改进,对于多类名的情况我们可以用正则去匹配是否包含所要查找的class名,于是就出现了下面这种写法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getByClass2(parent, cls){
      var res = [];
      var reg = new RegExp('\b' + cls + '\b', 'i');  //匹配cls是一个独立的单词
      var ele = parent.getElementsByTagName('*');
      for(var i = 0; i < ele.length; i++){
        if(reg.test(ele[i].className)){
          res.push(ele[i]);
        }
      }
      return res;
    }

    这种方法看似可以,解决了getByClass1()的问题,我也用了好长一段时间,但是还会有一个隐藏的bug。看下面的例子:

    1
    2
    3
    4
    5
    6
    <div class="test"></div>
    <div class="test_box"></div>
    <div class="test-box"></div>
    <script>
      getByClass2(document, 'test');  //结果获取到了第一个div和第三个div
    </script> 

    理论上应该只获取到第一个,但是却和我们预期不一样。这个bug源于下面这段代码里的

    1
    var reg = new RegExp('\b' + cls + '\b', 'i');

    我们先来看下在正则中的表示的意思

    是正则表达式规定的一个特殊代码,代表着单词的开头或结尾,也就是单词的分界处。

    通俗点说:就是匹配一个单词(从左边界到右边界)。

    而问题也就出在这里,把除字母、数字、下划线外的其他字符都当成是边界,对于上面的例子中第三个class值为test-box,匹配时,把连字符(-)当作单词边界,所以也匹配了第三个div。

    方法三

    因此我们还需要对上面方法进行进一步改进,这里参考了stackoverflow上提到的一种方法:

    How to Get Element By Class in JavaScript?

    改进后的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getByClass3(parent, cls){
      var res = [];
      var reg = new RegExp(' ' + cls + ' ', 'i');  //匹配cls时,两边需要有空格
      var ele = parent.getElementsByTagName('*');
      for(var i = 0; i < ele.length; i++){
        if(reg.test(' ' + ele[i].className + ' ')){
          res.push(ele[i]);
        }
      }
      return res;
    }

    这种方法舍去了用而采用空格来匹配边界,先在获取到的className值两边加上空格,这样就保证了className里的每个值两边都会有空格,然后再用正则去匹配。

    用这种方法暂时还未发现问题,但是使用时,方法中的单引号内的空格一定不能落下。

    方法四

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getByClass3(parent, cls){
      var res = [];
      var reg = new RegExp('(^|\s)' + cls + '($|\s)', 'i');
      var ele = parent.getElementsByTagName('*');
      for(var i = 0; i < ele.length; i++){
        if(reg.test(ele[i].className)){
          res.push(ele[i]);
        }
      }
      return res;
    }

    空格完全用正则来处理,这样省去了空格容易落下的问题,代码也更美观精简。

    那么这种方法是否就是比较完美的呢,其实不然,下面来看下更优的方案。

    方法五(完美版)

    文章开头已经提到,高版本的浏览器已经支持getElementsByClassName()方法。出于性能考虑,对支持的浏览器使用原生方法势必会更好。而对于低版本的浏览器使用上面的方法四。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function getByClass(parent, cls){
      if(parent.getElementsByClassName){
        return parent.getElementsByClassName(cls);
      }else{
        var res = [];
        var reg = new RegExp(' ' + cls + ' ', 'i')
        var ele = parent.getElementsByTagName('*');
        for(var i = 0; i < ele.length; i++){
          if(reg.test(' ' + ele[i].className + ' ')){
            res.push(ele[i]);
          }
        }
        return res;
      }
    }
  • 相关阅读:
    为什么数据库连接很消耗资源 转
    在Eclipse中编写servlet时出现"The import javax.servlet cannot be resolved" 问题解决办法
    multipart/form-data post 方法提交表单,后台获取不到数据
    java 数据库查询Date类型字段 没有了时分秒 全为 00 的解决办法
    Eclipse/myEclipse 代码提示/自动提示/自动完成设置(转)
    PL/SQL破解方法(不需要注册码)
    Java
    tomcat开发环境配置
    文件操作权限
    Java版office文档在线预览
  • 原文地址:https://www.cnblogs.com/alexguoyihao/p/9143375.html
Copyright © 2011-2022 走看看