getElementsByName в IE7
-
07-07-2019 - |
Вопрос
У меня есть код, делающий это:
var changes = document.getElementsByName(from);
for (var c=0; c<changes.length; c++) {
var ch = changes[c];
var current = new String(ch.innerHTML);
etc.
}
Это отлично работает в FF и Chrome, но не в IE7.Предположительно, потому что getElementsByName не работает в IE.Какой лучший обходной путь?
Решение
Если вы не знаете, почему это не работает в IE, вот документация MSDN для этой функции :
Когда вы используете метод getElementsByName, возвращаются все элементы в документе, которые имеют указанный атрибут NAME или значение атрибута ID.
Элементы, которые поддерживают как атрибут NAME, так и атрибут ID, включаются в коллекцию, возвращаемую методом getElementsByName, но элементы с расширением NAME не включаются в коллекцию; поэтому этот метод нельзя использовать для извлечения пользовательских тегов по имени.
Firefox позволяет getElementsByName ()
для извлечения элементов, использующих расширение NAME, поэтому оно работает. Хорошо это или нет, & # 8482; может быть спорным, но это реальность.
Итак, один из вариантов - использовать getAttribute ()
метод DOM, чтобы запросить атрибут NAME, а затем проверить значение, чтобы увидеть, является ли оно тем, что вы хотите, и, если да, добавить его в массив. Однако для этого потребуется перебирать все узлы на странице или, по крайней мере, в подразделе, что не будет наиболее эффективным. Вы можете заранее ограничить этот список, используя что-то вроде getElementsByTagName ()
возможно.
Другой способ сделать это, если вы контролируете HTML-код страницы, - это присвоить всем интересующим элементам идентификатор, который изменяется только по номеру, например:
<div id="Change0">...</div>
<div id="Change1">...</div>
<div id="Change2">...</div>
<div id="Change3">...</div>
А потом используйте такой JavaScript:
// assumes consecutive numbering, starting at 0
function getElementsByModifiedId(baseIdentifier) {
var allWantedElements = [];
var idMod = 0;
while(document.getElementById(baseIdentifier + idMod)) { // will stop when it can't find any more
allWantedElements.push(document.getElementById(baseIdentifier + idMod++));
}
return allWantedElements;
}
// call it like so:
var changes = getElementsByModifiedId("Change");
Это, конечно, взлом, но он будет выполнять ту работу, которая вам нужна, и не будет слишком неэффективным по сравнению с некоторыми другими взломами.
Если вы используете какой-то фреймворк / инструментарий JavaScript, ваши варианты намного лучше, но у меня нет времени разбираться в этих особенностях, если вы не укажете, что используете их. Лично я не знаю, как люди живут без него, они экономят столько времени, усилий и разочарований, что вы не можете не использовать их.
Другие советы
Есть пара проблем:
- IE действительно сбивает с толку
id=""
сname=""
name=""
запрещено на<span>
Для исправления предлагаю:
- Изменить все
name=""
кclass=""
- Измените свой код следующим образом:
-
var changes = document.getElementById('text').getElementsByTagName('span');
for (var c=0; c<changes.length; c++) {
var ch = changes[c];
if (ch.className != from)
continue;
var current = new String(ch.innerHTML);
Редко найти элементы, используя свойство NAME. Я бы порекомендовал перейти к свойству ID.
Однако вы можете найти элементы с определенным именем, используя jQuery:
$("*[name='whatevernameYouWant']");
это вернет все элементы с заданным именем.
getElementsByName поддерживается в IE, но есть ошибки. В частности, он возвращает элементы, чей & # 8216; id & # 8217; соответствует заданному значению, а также & # 8216; name & # 8217 ;. Не могу сказать, если это проблема, которую у вас есть, без немного больше контекста, кода и фактических сообщений об ошибках.
В общем, getElementsByName, вероятно, лучше избегать, потому что & # 8216; name & # 8217; Атрибут в HTML имеет несколько перекрывающихся целей, которые могут сбить с толку. Использование getElementById намного надежнее. При конкретной работе с полями формы вы можете более надежно использовать form.elements [name] для извлечения искомых полей.
Еще одна ошибка DOM в IE:
Ошибка 1: http: // webbugtrack. blogspot.com/2007/08/bug-411-getelementsbyname-doesnt-work.html р>
Ошибка 2: http: // webbugtrack. blogspot.com/2008/04/bug-403-another-getelementsbyname-bugs.html р>
Я успешно использовал оболочку для возврата массива элементов. Работает в IE 6 и 7 тоже. Имейте в виду, что это не на 100% то же самое, что document.getElementsByName, так как это не NodeList. Но для чего мне это нужно, а именно для запуска цикла for на массиве элементов для выполнения простых вещей, таких как установка .disabled = true, это работает достаточно хорошо.
Даже если эта функция все еще использует getElementsByName, она работает, если используется таким образом. Смотрите сами.
function getElementsByNameWrapper(name) {
a = new Array();
for (var i = 0; i < document.getElementsByName(name).length; ++i) {
a.push(document.getElementsByName(name)[i]);
}
return a;
}
Обходной путь
var listOfElements = document.getElementsByName('aName'); // Replace aName with the name you're looking for
// IE hack, because it doesn't properly support getElementsByName
if (listOfElements.length == 0) { // If IE, which hasn't returned any elements
var listOfElements = [];
var spanList = document.getElementsByTagName('*'); // If all the elements are the same type of tag, enter it here (e.g.: SPAN)
for(var i = 0; i < spanList.length; i++) {
if(spanList[i].getAttribute('name') == 'aName') {
listOfElements.push(spanList[i]);
}
}
}