最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

JavaScript跨浏览器获取页面中相同class节点的方法_javascript技巧

来源:动视网 责编:小采 时间:2020-11-27 21:35:10
文档

JavaScript跨浏览器获取页面中相同class节点的方法_javascript技巧

JavaScript跨浏览器获取页面中相同class节点的方法_javascript技巧:网页开发时,在很多时候我们需要操作相同类名的元素,即class相同的元素。昨天参加笔试,有一道相关的题目没答上来: JavaScript获取页面中class为test的节点 于是收集了一些相关的资料,在本文中列举了两种我觉得比较好的方法,不足之处,还望大家批评指正。
推荐度:
导读JavaScript跨浏览器获取页面中相同class节点的方法_javascript技巧:网页开发时,在很多时候我们需要操作相同类名的元素,即class相同的元素。昨天参加笔试,有一道相关的题目没答上来: JavaScript获取页面中class为test的节点 于是收集了一些相关的资料,在本文中列举了两种我觉得比较好的方法,不足之处,还望大家批评指正。


网页开发时,在很多时候我们需要操作相同类名的元素,即class相同的元素。昨天参加笔试,有一道相关的题目没答上来:

JavaScript获取页面中class为test的节点

于是收集了一些相关的资料,在本文中列举了两种我觉得比较好的方法,不足之处,还望大家批评指正。如果大家有更好的方法,希望可以分享。

Solution1 Jeremy Keuth方案

Jeremy Keuth大叔在《JavaScript DOM 编程艺术》(第2版)(英文:DOM Scripting-Web Design with JavaScript and the Document Object Model)一书的第三章第四节中讲到了getElementsByClass这个方法,并讲到了如何在不支持该属性的浏览器(IE6,IE7和IE8,让我们鄙视他们)中应用这一方法,摘录在此,个别地方有修改。

HTML5 DOM中新增了一个方法让我们通过class属性中的类名来访问元素,这就是:getELementsByClassName,由于方法比较新,某些的DOM实现里还没有,因此在使用的时候要当心。下面我们先来看一看这个方法能帮我们做什么,然后在讨论怎么可靠的使用该方法。
与getELementsByTagName方法类似,getElementsByClassName也只接受一个参数,就是类名:
代码如下:
getElementsByClassName(class)

这个方法的返回值也与getElementsByTagName类似,都是一个具有相同类名的元素的数组,下面这行代码返回的就是一个数组,其中包含类名为“sale”的所有元素:
代码如下:
document.getElementsByClassName("sale")

使用这个方法还可以查找那些带有多个类名的元素。要指定多个类名,只要在字符串参数中用空格分隔类名即可。例如,在标签中添加下面这行代码:
代码如下:
alert(document.getElementsByClassName("sale important").length);

完整代码

代码如下:




Shopping List


What to buy


Don't forget to buy this stuff.



  • A thin of beans

  • Cheese

  • Milk



  • alert(document.getElementsByClassName("sale important").length);



    你会看到警告框中显示1,表示只有一个元素匹配,因为只有一个元素同时带有”important”和”sale”类名。注意,即使在元素的class属性中,类名的顺序是”sale important”而非参数中指定的”important sale”,也会照样匹配该元素。不仅类名的实际顺序不重要,就算元素还带有更多类名也没有关系。与使用getELementsByTagName一样,也可以组合使用getElementsByClassName和getElementById。如果你想知道在id为purchase的元素中有多少类名包含test的列表项,可以先找到那个特定的对象,然后再调用getElementsByClassName:

    代码如下:
    var shopping=document.getElementById("purchase");
    var sales = shopping.getElementsByClassName("sale");

    这样,sales数组中包含的就只是位于”purchase”列表中的带有”sales”类的元素,运行下面这行代码,就会看到sales数组包含两项:

    代码如下:
    alert(sales.length);

    这个getELementsByClassName方法非常有用,但只有较新的浏览器(Safari 3.1,Chorme,Firefox 3 and Opera 9.5以上)才支持它。为了弥补这一不足,DOM脚本程序员需要使用已有的DOM方法来实现自己的getElementsByClassName,有点像成人礼似的。而多数情况下,他们的实现过程都与下面这个getElementsByClassName大致相似,这个函数能适用于新老浏览器。

    代码如下:
    function getElementsByClassName(node,classname){
    if(node.getElementsByClassName){
    return node.getElementsByClassName(classname);
    }else{
    var results = [];
    var elems = node.getElementsByTagName("*");
    for(var i=0;i if(elems[i].className.indexOf(classname)!=-1){
    results[results.length]=elems[i];
    }
    }
    return results;
    }
    }

    这个getElementsByClassName函数接受两个参数。第一个node表示DOM树中的搜索起点,第二个classname就是要搜索的类名了。如果传入节点上已经存在了适当的getElementsByClassName函数,那么这个新函数就直接返回相应的节点列表。如果getElementsByClassName函数不存在,这个新函数就会循环遍历所有标签,查找带有相应类名的元素。

    这个方法的缺点是不适用于多个类名。

    如果使用这个函数来模拟前面取得购物列表的操作,就可以这样写:
    代码如下:
    var shopping=document.getElementById("purchase");
    var sales = shopping.getElementsByClassName(shopping,"test");
    console.log(sales);

    因此,要解决文章开头的那道题目,所用代码如下:

    代码如下:




    Shopping List


    What to buy


    Don't forget to buy this stuff.



  • A thin of beans

  • Cheese

  • Milk



  • function getElementsByClassName(node,classname){
    if(node.getElementsByClassName){
    return node.getElementsByClassName(classname);
    }else{
    var results = [];
    var elems = node.getElementsByTagName("*");
    for(var i=0;i if(elems[i].className.indexOf(classname)!=-1){
    results[results.length]=elems[i];
    }
    }
    return results;
    }
    }
    var body = document.getElementsByTagName("body")[0];
    var sales= getElementsByClassName(body,"sales");
    console.log(sales);



    Solution2 Robert Nyman方案

    搜索匹配的DOM元素的方法还有很多,但真正高效的却不多,Jeremy Keuth大叔的方法有一个缺点就是不能用于多个类名,2008年,Robert Nyman在文章 The Ultimate GetElementsByClassName, Anno 2008中提供了自己的解决方案。在2005年,Robert大叔就已经给出了自己的getElementsByClassName的函数,在2008年的时候,修改了部分代码,添加了许多新的功能:

    1.如果当前浏览器支持getElementsByClassName函数,则调用该原生函数;
    2.如果当前浏览器支持则使用XPath;//小飞鱼:一种浏览器内置的定位XML文档的强大方式,不过浏览器支持方面不统一
    3.支持多个类名的搜索,不计先后顺序;
    4.返回真正的节点数组,而不是原生的一个nodelist。//小飞鱼:原生的getElementsByClassName方法返回的是一个NodeList对象,它很像数组,有length和数字索引属性,但并不是数组,不能用pop,push等数组特有的方法,Robert提供的代码中,将NodeList对象转成了数组。可以将NodeList对象转换成数组的方法:
    代码如下:
    myList = Array.prototype.slice.call (myNodeList)

    这是Robert大叔的方法,有些地方还不太明白,待我研究一下再来更新好了。

    代码如下:
    /*
    Developed by Robert Nyman, http://www.robertnyman.com
    Code/licensing: http://code.google.com/p/getelementsbyclassname/
    */
    var getElementsByClassName = function (className, tag, elm){
    if (document.getElementsByClassName) {
    getElementsByClassName = function (className, tag, elm) {
    elm = elm || document;
    var elements = elm.getElementsByClassName(className),
    nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
    returnElements = [],
    current;
    for(var i=0, il=elements.length; i current = elements[i];
    if(!nodeName || nodeName.test(current.nodeName)) {
    returnElements.push(current);
    }
    }
    return returnElements;
    };
    }
    else if (document.evaluate) {
    getElementsByClassName = function (className, tag, elm) {
    tag = tag || "*";
    elm = elm || document;
    var classes = className.split(" "),
    classesToCheck = "",
    xhtmlNamespace = "http://www.w3.org/1999/xhtml",
    namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
    returnElements = [],
    elements,
    node;
    for(var j=0, jl=classes.length; j classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
    }
    try {
    elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
    }
    catch (e) {
    elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
    }
    while ((node = elements.iterateNext())) {
    returnElements.push(node);
    }
    return returnElements;
    };
    }
    else {
    getElementsByClassName = function (className, tag, elm) {
    tag = tag || "*";
    elm = elm || document;
    var classes = className.split(" "),
    classesToCheck = [],
    elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
    current,
    returnElements = [],
    match;
    for(var k=0, kl=classes.length; k classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
    }
    for(var l=0, ll=elements.length; l current = elements[l];
    match = false;
    for(var m=0, ml=classesToCheck.length; m match = classesToCheck[m].test(current.className);
    if (!match) {
    break;
    }
    }
    if (match) {
    returnElements.push(current);
    }
    }
    return returnElements;
    };
    }
    return getElementsByClassName(className, tag, elm);
    };

    文档

    JavaScript跨浏览器获取页面中相同class节点的方法_javascript技巧

    JavaScript跨浏览器获取页面中相同class节点的方法_javascript技巧:网页开发时,在很多时候我们需要操作相同类名的元素,即class相同的元素。昨天参加笔试,有一道相关的题目没答上来: JavaScript获取页面中class为test的节点 于是收集了一些相关的资料,在本文中列举了两种我觉得比较好的方法,不足之处,还望大家批评指正。
    推荐度:
    标签: 获取 技巧 的方法
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top