我正在尝试在Internet Explorer 8中为我拥有的HTML创建一个可折叠列表:
<li>
<a href="#" onclick="test('node1')">hello</a>
<ul id="node1" class="node" style="display:none">
<li>Sub-item 1</li>
<li>Sub-item 2</li>
</ul>
</li>
<li>
<a href="#" onclick="test('node2')">test</a>
<ul id="node2" class="node" style="display:none">
<li>Sub-item 1</li>
<li>Sub-item 2</li>
</ul>
</li>
在javascript中我有
function test2(className, link) {
var e = document.getElementsByClassName(className);
for (var i = 0, len = e.length; i < len; i++) {
e[i].style.display = "none";
}
link.innerHTML = "Expand";
}
我用它来称呼它:
<a href="#" onclick="test2('node', this)">Collapse</a>
不幸的是,这种方法在IE8中不起作用,querySelectAll
也没有。有人可以举例说明如何解决这个问题吗?
答案 0 :(得分:15)
通过扩展Element.prototype
和document
:
(function() {
if (!document.getElementsByClassName) {
var indexOf = [].indexOf || function(prop) {
for (var i = 0; i < this.length; i++) {
if (this[i] === prop) return i;
}
return -1;
};
getElementsByClassName = function(className, context) {
var elems = document.querySelectorAll ? context.querySelectorAll("." + className) : (function() {
var all = context.getElementsByTagName("*"),
elements = [],
i = 0;
for (; i < all.length; i++) {
if (all[i].className && (" " + all[i].className + " ").indexOf(" " + className + " ") > -1 && indexOf.call(elements, all[i]) === -1) elements.push(all[i]);
}
return elements;
})();
return elems;
};
document.getElementsByClassName = function(className) {
return getElementsByClassName(className, document);
};
if(Element) {
Element.prototype.getElementsByClassName = function(className) {
return getElementsByClassName(className, this);
};
}
}
})();
然而,扩展原型对象并不总是最好的想法,特别是对于一个名为与不存在的本机函数完全相同的函数。如果要避免原型扩展导致的问题,请使用以下代码:
(function() {
var indexOf = [].indexOf || function(prop) {
for (var i = 0; i < this.length; i++) {
if (this[i] === prop) return i;
}
return -1;
};
window.getElementsByClassName = function(className,context) {
if (context.getElementsByClassName) return context.getElementsByClassName(className);
var elems = document.querySelectorAll ? context.querySelectorAll("." + className) : (function() {
var all = context.getElementsByTagName("*"),
elements = [],
i = 0;
for (; i < all.length; i++) {
if (all[i].className && (" " + all[i].className + " ").indexOf(" " + className + " ") > -1 && indexOf.call(elements,all[i]) === -1) elements.push(all[i]);
}
return elements;
})();
return elems;
};
})();
这样,您可以安全地使用接受两个参数的getElementsByClassName()
函数:
className
:CSS类context
:节点答案 1 :(得分:4)
IE8不支持getElementsByClassName
,但支持querySelectorAll
。
要使用querySelectorAll
,您需要一个有效的类选择器,这意味着它需要对类使用Selectors API语法,该语法使用.
来表示类。
function test2(className, link) {
var e = document.querySelectorAll("." + className);
for (var i = 0, len = e.length; i < len; i++) {
e[i].style.display = "none";
}
link.innerHTML = "Expand";
}
答案 2 :(得分:0)
如果不存在,您可以自己实施:
// shim for older browsers:
if (!document.getElementsByClassName) {
document.getElementsByClassName = (function(){
// Utility function to traverse the DOM:
function traverse (node, callback) {
callback(node);
for (var i=0;i < node.childNodes.length; i++) {
traverse(node.childNodes[i],callback);
}
}
// Actual definition of getElementsByClassName
return function (name) {
var result = [];
traverse(document.body,function(node){
if (node.className == name) {
result.push(node);
}
});
return result;
}
})()
}
现在,您可以在旧版浏览器中使用document.getElementsByClassName
。垫片和本机实现之间的一个区别是垫片返回一个真实的数组而不是nodelist(或htmlelementcollection)。