getElementsByClassName IE проблема разрешения
У меня возникли проблемы, выясняя, как решить проблему getElementsByClassName в IE. Как мне лучше всего реализовать разрешение robert nyman (не могу разместить ссылку на него, так как моя репутация составляет всего 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). Любые советы будут очень признательны.
6 ответов:
Мне было любопытно посмотреть, как будет выглядеть 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; } }
Это должно поддерживать несколько классов.
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') { }
Еще более простое решение jQuery:
$('.service').click( function() { var id = "#" + $(this).attr('id') + 'rt'; $('.description').not(id).hide(); $( id ).show(); }
Зачем беспокоиться о классе
show
, Если вы используете jQuery?
Вот один, который я собрал, надежный и, возможно, самый быстрый. Должен работать в любой ситуации.
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; }
Я использовал для реализации 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, потому что регулярное выражение медленное (возможно, функция с .indexOf, он должен быть протестирован), но он работает хорошо
Можно заменить
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")