javascript文件。getElementsByClassName IE兼容

时间:2022-12-01 19:18:43

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.

我会用文档。getElementsByClassName但是IE不支持它。

So I tried Jonathan Snook's solution:

所以我尝试了乔纳森·斯努克的解决方案:

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?

有什么想法,更好的方法,bug修复?

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

我宁愿不使用任何涉及jQuery或其他“笨重的javascript”的解决方案。

Update:

I got it to work!

我成功了!

As @joe mentioned the function is not a method of document.

正如@joe提到的,函数不是文档的方法。

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+ support then 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');

7 个解决方案

#1


54  

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

#2


16  

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;
    }
}

#3


13  

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.getElementsByClassName when it can.

很确定这和Leonid的功能相同,但它使用的是document。getElementsByClassName时。

#4


9  

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 = getArrayByClassNames(当地侧边栏)

#5


8  

IE8:

IE8:

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

#6


0  

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

#7


0  

I just want to improve querySelectorAll fallback for IE8.

我只是想改进querySelectorAll fallback for IE8。

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

和其他人一样,简单的方法是将函数添加到元素中。原型与

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"     ->  ".\000031234"

Code:

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
);

#1


54  

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

#2


16  

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;
    }
}

#3


13  

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.getElementsByClassName when it can.

很确定这和Leonid的功能相同,但它使用的是document。getElementsByClassName时。

#4


9  

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 = getArrayByClassNames(当地侧边栏)

#5


8  

IE8:

IE8:

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

#6


0  

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

#7


0  

I just want to improve querySelectorAll fallback for IE8.

我只是想改进querySelectorAll fallback for IE8。

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

和其他人一样,简单的方法是将函数添加到元素中。原型与

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"     ->  ".\000031234"

Code:

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
);