我在解决如何解决IE中的getElementsByClassName问题时遇到了问题。我如何最好地实现罗伯特·尼曼(不能发布链接,因为我的代表只有1)解析到我的代码?或者jquery解决方案会更好吗?我的代码是
function showDesc(name) {
var e = document.getElementById(name);
//Get a list of elements that have a class name of service selected
var list = document.getElementsByClassName("description show");
//Loop through those items
for (var i = 0; i < list.length; ++i) {
//Reset all class names to description
list[i].className = "description";
}
if (e.className == "description"){
//Set the css class for the clicked element
e.className += " show";
}
else{
if (e.className == "description show"){
return;
}
}}
我正在此页dev.msmnet.com/services/practice-management上使用它来显示/隐藏每项服务的说明(适用于Chrome和FF)。任何提示将不胜感激。
答案 0 :(得分:2)
这应该支持多个类。
function getElementsByClassName(findClass, parent) {
parent = parent || document;
var elements = parent.getElementsByTagName('*');
var matching = [];
for(var i = 0, elementsLength = elements.length; i < elementsLength; i++){
if ((' ' + elements[i].className + ' ').indexOf(findClass) > -1) {
matching.push(elements[i]);
}
}
return matching;
}
您也可以传入父级,以便更快地搜索DOM。
如果您希望getElementsByClassName('a c')
与HTML <div class="a b c" />
匹配,请尝试更改它...
var elementClasses = elements[i].className.split(/\s+/),
matchClasses = findClass.split(/\s+/), // Do this out of the loop :)
found = 0;
for (var j = 0, elementClassesLength = elementClasses.length; j < elementClassesLength; j++) {
if (matchClasses.indexOf(elementClasses[j]) > -1) {
found++;
}
}
if (found == matchClasses.length) {
// Push onto matching array
}
如果您希望此功能仅在尚不存在时可用,请使用
包装其定义if (typeof document.getElementsByClassName != 'function') { }
答案 1 :(得分:2)
我很想知道你的函数的jQuery版本会是什么样的,所以我提出了这个:
function showDesc(name) {
var e = $("#" + name);
$(".description.show").removeClass("show");
if(e.attr("class") == "description") {
e.addClass("show");
} else if(e.hasClass("description") && e.hasClass("show")) {
return;
}
}
答案 2 :(得分:1)
更简单的jQuery解决方案:
$('.service').click( function() {
var id = "#" + $(this).attr('id') + 'rt';
$('.description').not(id).hide();
$( id ).show();
}
如果使用jQuery,为什么还要使用show
类?
答案 3 :(得分:1)
我曾经实现HTMLElement.getElementByClassName(),但至少Firefox和Chrome只在这些元素很多的时候找到了一半的元素,而是使用类似的东西(实际上它是一个更大的函数):
getElmByClass(clm, parent){
// clm: Array of classes
if(typeof clm == "string"){ clm = [clm] }
var i, m = [], bcl, re, rm;
if (document.evaluate) { // Non MSIE browsers
v = "";
for(i=0; i < clm.length; i++){
v += "[contains(concat(' ', @"+clc+", ' '), ' " + base[i] + " ')]";
}
c = document.evaluate("./"+"/"+"*" + v, parent, null, 5, null);
while ((node = c.iterateNext())) {
m.push(node);
}
}else{ // MSIE which doesn't understand XPATH
v = elm.getElementsByTagName('*');
bcl = "";
for(i=0; i < clm.length; i++){
bcl += (i)? "|":"";
bcl += "\\b"+clm[i]+"\\b";
}
re = new RegExp(bcl, "gi");
for(i = 0; i < v.length; i++){
if(v.className){
rm = v[i].className.match(bcl);
if(rm && rm.length){ // sometimes .match returns an empty array so you cannot use just 'if(rm)'
m.push(v[i])
}
}
}
}
return m;
}
我认为没有XPATH会有更快的迭代方式,因为RegExp很慢(可能是带有.indexOf的函数,需要测试),但它运行良好
答案 4 :(得分:1)
这是我放在一起的,可靠的,可能是最快的。应该适用于任何情况。
function $class(className) {
var children = document.getElementsByTagName('*') || document.all;
var i = children.length, e = [];
while (i--) {
var classNames = children[i].className.split(' ');
var j = classNames.length;
while (j--) {
if (classNames[j] == className) {
e.push(children[i]);
break;
}
}
}
return e;
}
答案 5 :(得分:0)
您可以使用以下内容替换getElementsByClassName()
:
function getbyclass(n){
var elements = document.getElementsByTagName("*");
var result = [];
for(z=0;z<elements.length;z++){
if(elements[z].getAttribute("class") == n){
result.push(elements[z]);
}
}
return result;
}
然后你可以像这样使用它:
getbyclass("description") // Instead of document.getElementsByClassName("description")