简体   繁体   English

我们在javascript中有getElementsByClassName吗?

[英]Do we have getElementsByClassName in javascript?

Just like in jQuery we can use $(".classname"), is there a similar thing in javascript as well? 就像在jQuery中我们可以使用$(“。classname”),javascript中也有类似的东西吗? Or if we don't have such method then how can i implement that. 或者,如果我们没有这样的方法,那么我该如何实现呢。
According to http://www.dustindiaz.com/getelementsbyclass/ i will have to iterate through all tags and then collect all elements which are having the same class as specified. 根据http://www.dustindiaz.com/getelementsbyclass/,我将遍历所有标签,然后收集所有与指定类相同的元素。

Is there any better solution? 有没有更好的解决方案?

i will have to iterate through all tags and then collect all elements which are having the same class as specified. 我将不得不遍历所有标签,然后收集所有与指定类相同的元素。

Yes. 是。 There are a couple of ways to improve the function from the page you linked, though: 但是,有几种方法可以改善您链接的页面的功能:

  • RegExp-escape class names passed in so that it isn't broken by punctuation in the class name. 传入RegExp-escape类名,以便它不会被类名中的标点符号破坏。 For example a call to getElementsByClassName('ab.cd') shouldn't match class="abxcd" . 例如,对getElementsByClassName('ab.cd')的调用不应与class="abxcd"匹配。

  • The HTML5 specification that defines getElementsByClassName allows multiple space-separated class names, all of which have to be present on the element to match. 定义getElementsByClassName的HTML5规范允许多个以空格分隔的类名,所有这些都必须存在于要匹配的元素上。 Implement this. 实现这一点。

  • optionally, allow a hint of tag name to be passed in to narrow down the number of elements the function has to look through for the common case where only one type of tag is affected. 可选地,允许传递标记名称的提示以缩小函数必须查看的元素的数量,以用于仅影响一种类型标记的常见情况。 (This will do nothing on a real browser-native getElementsByClassName call, so you shouldn't rely on it to filter out elements you don't want.) (这对于真正的浏览器本机getElementsByClassName调用无效,因此您不应该依赖它来过滤掉您不想要的元素。)

Example implementation: 示例实现:

if (!('getElementsByClassName' in document)) {
    document.getElementsByClassName= function(classnames, taghint) {
        var exps= classnames.split(/\s+/).map(function(name) {
            name= name.replace(/([/\\^$*+?.()|[\]{}])/g, '\\$1');
            return new RegExp('(^|\\s)'+name+'(\\s|$)');
        });
        var els= this.getElementsByTagName(taghint || '*');
        var matches= [];
        for (var i= 0, n= this.length; i<n; i++)
            var el= els[i];
            if (exps.every(function(exp) {
                return exp.test(el.className);
            }))
                matches.push(el);
        }
        return matches;
    };
}

However this does also use a couple of ECMAScript Fifth Edition (or JavaScript 1.6) Array methods which IE doesn't yet have either, so you'd have to add fallback implementations for those, too: 然而,这也使用了IE还没有的一些ECMAScript第五版(或JavaScript 1.6)数组方法,因此您还必须为这些方法添加回退实现:

if (!('map' in Array.prototype)) {
    Array.prototype.map= function(mapper, that) {
        var other= new Array(this.length);
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this)
                other[i]= mapper.call(that, this[i], i, this);
        return other;
    };
}

if (!('every' in Array.prototype)) {
    Array.prototype.every= function(tester, that) {
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this && !tester.call(that, this[i], i, this))
                return false;
        return true;
    };
}

Unfortunately not consistently between browsers. 不幸的是浏览器之间不一致 If you don't need all of jQuery, but still would like to do selection based on CSS selectors, take a look at Sizzle , the selector library jQuery uses. 如果你不需要所有的jQuery,但仍想根据CSS选择器进行选择,请看一下jQuery使用的选择器库Sizzle

Another good implementation of getElementsByClassName getElementsByClassName另一个很好的实现

Mixes an XPath and DOM implementation; 混合XPath和DOM实现; using XPath wherever possible. 尽可能使用XPath。

if (!('getElementsByClassName' in document)) {
    document.getElementsByClassName = function(className, parentElement) {
        if (Prototype.BrowserFeatures.XPath) {
            var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
            return document._getElementsByXPath(q, parentElement);
        } else {
            var children = ($(parentElement) || document.body).getElementsByTagName('*');
            var elements = [],
                child;
            for (var i = 0, length = children.length; i < length; i++) {
                child = children[i];
                if (Element.hasClassName(child, className)) elements.push(Element.extend(child));
            }
            return elements;
        }
    };
}​


PS: Posting it here because I guess its faster than bobince answer . PS:在这里发布,因为我猜它比bobince答案更快。 No offense :) 没有冒犯的意思 :)
Got this from John Resig's getElementsByClassName Speed Comparison 从John Resig的getElementsByClassName速度比较得到了这个

Some browsers, for example Firefox 3 support getElementsByClassName , others you have to iterate though all the tags, so if you wanted to support all browsers with a single function you should use the iterative method. 有些浏览器,例如Firefox 3支持getElementsByClassName ,其他浏览器必须迭代所有标签,所以如果你想支持所有具有单一功能的浏览器,你应该使用迭代方法。

The best solution is to use jQuery or any other framework which will use the best available method. 最好的解决方案是使用jQuery或任何其他将使用最佳可用方法的框架。

Yes, you'd have to iterate to support all browsers. 是的,您必须迭代以支持所有浏览器。 If you do, tho, make sure you take advantage of the browser's built in functionality where it exists: 如果您这样做,请确保您利用浏览器内置的功能:

if(document.getElementsByClassName) {
   return document.getElementsByClassName(className);
} else {
   // iterate
}

Other than that, I'm with Jochen; 除此之外,我和Jochen在一起; use a framework 使用框架

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM