javascript document.getElementsByClassName 与 IE 的兼容性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7410949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:10:45  来源:igfitidea点击:

javascript document.getElementsByClassName compatibility with IE

javascriptinternet-explorerclassinternet-explorer-8classname

提问by Web_Designer

What is the best method to retrieve an array of elements that have a certain class?

检索具有特定类的元素数组的最佳方法是什么?

I would use document.getElementsByClassName but IE does not support it.

我会使用 document.getElementsByClassName 但 IE 不支持它。

So I tried Jonathan Snook's solution:

所以我尝试了Jonathan Snook 的解决方案

function getElementsByClassName(node, classname) {
    var a = [];
    var re = new RegExp('(^| )'+classname+'( |$)');
    var els = node.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
        if(re.test(els[i].className))a.push(els[i]);
    return a;
}
var tabs = document.getElementsByClassName(document.body,'tab');

...but IE still says:

...但 IE 仍然说:

Object doesn't support this property or method

对象不支持此属性或方法

Any ideas, better methods, bug fixes?

任何想法,更好的方法,错误修复?

I would prefer not to use any solutions involving jQuery or other "bulky javascript".

我不想使用任何涉及 jQuery 或其他“庞大的 javascript”的解决方案。

Update:

更新:

I got it to work!

我让它工作!

As @joe mentionedthe function is not a method of document.

正如@joe 提到的,该函数不是document.

So the working code would look like this:

所以工作代码看起来像这样:

function getElementsByClassName(node, classname) {
    var a = [];
    var re = new RegExp('(^| )'+classname+'( |$)');
    var els = node.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
        if(re.test(els[i].className))a.push(els[i]);
    return a;
}
var tabs = getElementsByClassName(document.body,'tab');


...Also if you only need IE8+ supportthen this will work:


...此外,如果您只需要 IE8+ 支持,那么这将起作用:

if(!document.getElementsByClassName) {
    document.getElementsByClassName = function(className) {
        return this.querySelectorAll("." + className);
    };
    Element.prototype.getElementsByClassName = document.getElementsByClassName;
}

Use it just like normal:

像平常一样使用它:

var tabs = document.getElementsByClassName('tab');

采纳答案by Joe

It's not a method of document:

这不是一种文件方法:

function getElementsByClassName(node, classname) {
    var a = [];
    var re = new RegExp('(^| )'+classname+'( |$)');
    var els = node.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
        if(re.test(els[i].className))a.push(els[i]);
    return a;
}

tabs = getElementsByClassName(document.body,'tab');  // no document

回答by gdarcan

you may create the function for older browsers

您可以为旧浏览器创建功能

if (typeof document.getElementsByClassName!='function') {
    document.getElementsByClassName = function() {
        var elms = document.getElementsByTagName('*');
        var ei = new Array();
        for (i=0;i<elms.length;i++) {
            if (elms[i].getAttribute('class')) {
                ecl = elms[i].getAttribute('class').split(' ');
                for (j=0;j<ecl.length;j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            } else if (elms[i].className) {
                ecl = elms[i].className.split(' ');
                for (j=0;j<ecl.length;j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            }
        }
        return ei;
    }
}

回答by Mike_OBrien

function getElementsByClassName(className) {
if (document.getElementsByClassName) { 
  return document.getElementsByClassName(className); }
else { return document.querySelectorAll('.' + className); } }

Pretty sure this is the same as Leonid's function but this uses document.getElementsByClassNamewhen it can.

很确定这与 Leonid 的功能相同,但document.getElementsByClassName它会在可能的情况下使用。

回答by kennebec

You can't really replicate getElementsByClassName, because it returns a nodeList, and so its value is live, and updates with the document.

您不能真正复制 getElementsByClassName,因为它返回一个 nodeList,因此它的值是实时的,并随文档更新。

You can return a static Array of elements who share the same classnames- but it won't 'know'when the document changes.

您可以返回共享相同类名的元素的静态数组 - 但它不会“知道”文档何时更改。

(It won't take too many of these kind of things to make a library look svelte...)

(不需要太多这些东西就可以让图书馆看起来很苗条......)

function getArrayByClassNames(classes, pa){
    if(!pa) pa= document;
    var C= [], G;
    if(pa.getElementsByClassName){
        G= pa.getElementsByClassName(classes);
        for(var i= 0, L= G.length; i<L; i++){
            C[i]= G[i];
        }
    }
    else{
        classes= classes.split(/\s+/);
        var who, cL= classes.length,
        cn, G= pa.getElementsByTagName('*'), L= G.length;
        for(var i= 0; i<cL; i++){
            classes[i]= RegExp('\b'+classes[i]+'\b');
        }
        classnameLoop:
        while(L){
            who= G[--L];
            cn= who.className;
            if(cn){
                for(var i= 0; i<cL; i++){
                    if(classes[i].test(cn)== false) {
                        continue classnameLoop;
                    }
                }
                C.push(who);
            }
        }
    }
    return C;
}

//Example

//例子

var A= getArrayByClassNames('sideBar local')

var A= getArrayByClassNames('sideBar local')

回答by Leonid

IE8:

IE8:

document.getElementsByClassName = function (className) {
    return document.querySelectorAll('.' + className)
}

回答by Mohd Afique

function _getClass(whatEverClasNameYouWant){
var a=document.getElementsByTagName('*');
   for(b in a){
      if((' '+a[b].className+' ').indexOf(' '+whatEverClasNameYouWant+' ')>-1){
      return a[b];
      }
   }
}

回答by Oriol

I just want to improve querySelectorAllfallback for IE8.

我只想改进querySelectorAllIE8 的回退。

Like others answered, the simple way is adding the function to Element.prototypewith

像其他人回答一样,简单的方法是将函数添加到Element.prototypewith

this.querySelectorAll('.' + className);

But there are some problems:

但是有一些问题:

  • It doesn't work with untrimmed strings (at the beginning).
  • It doesn't work with multiple classes.
  • It doesn't work with "strange" class characters (/, $, *, etc.)
  • It doesn't work with classes which begin with a digit (invalid identifiers)
  • 它不适用于未修剪的字符串(在开始时)。
  • 它不适用于多个类。
  • 它不“怪”级的人物合作(/$*等)
  • 它不适用于以数字开头的类(无效标识符)

That means there should be some "fixing", for example:

这意味着应该有一些“修复”,例如:

"abcd"     ->  ".abcd"
"a   b cd" ->  ".a.b.cd"
"   a b  " ->  ".a.b  "
"a/b$c d"  ->  ".a\/b$c.d"
"1234"     ->  ".
this.querySelectorAll(className
    .replace(/(?=[^ \w])/g, '\')   // Escape non-word characters
    .replace(/\b\d/g, '\00003$&')  // Escape digits at the beginning
    .replace(/(^| +)(?!$| )/g, '.') // Add "." before classes, removing spaces
);
0031234"

Code:

代码:

##代码##