getElementsByName в IE7 - PullRequest
       25

getElementsByName в IE7

17 голосов
/ 10 ноября 2008

У меня есть код, делающий это:

 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. Какой лучший обходной путь?

Ответы [ 7 ]

17 голосов
/ 10 ноября 2008

Если вы не знаете, почему это не работает в IE, вот документация MSDN по этой функции :

Когда вы используете метод getElementsByName, возвращаются все элементы в документе, которые имеют указанный атрибут NAME или значение атрибута ID.

Элементы, которые поддерживают как атрибут NAME, так и атрибут ID, включаются в коллекцию, возвращаемую методом getElementsByName, но элементы с расширением NAME не включаются в коллекцию; поэтому этот метод нельзя использовать для получения пользовательских тегов по имени.

Firefox позволяет getElementsByName() извлекать элементы, использующие расширение NAME, поэтому оно работает. Является ли это хорошей вещью или нет, может быть спорным, но это реальность этого.

Итак, один из вариантов - использовать метод DOM getAttribute(), чтобы запросить атрибут 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, ваши варианты намного лучше, но у меня нет времени разбираться в этих особенностях, если вы не укажете, что используете их. Лично я не знаю, как люди живут без него, они экономят столько времени, усилий и разочарований, что вы не можете позволить себе , а не , чтобы использовать его.

4 голосов
/ 10 ноября 2008

Есть несколько проблем:

  1. IE действительно путает id="" с name=""
  2. name="" не разрешено <span>

Чтобы исправить, я предлагаю:

  1. Изменить все name="" на class=""
  2. Измените свой код следующим образом:

-

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);
2 голосов
/ 10 ноября 2008

Редко найти элементы, используя свойство NAME. Я бы порекомендовал перейти к свойству ID.

Однако вы можете найти элементы с определенным именем, используя jQuery:

 $("*[name='whatevernameYouWant']");

это вернет все элементы с заданным именем.

1 голос
/ 06 ноября 2013

Обход

                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]);
                    }
                }
            }
1 голос
/ 19 июля 2013

Я успешно использовал оболочку для возврата массива элементов. Работает в 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;
}
1 голос
/ 11 ноября 2008
1 голос
/ 10 ноября 2008

getElementsByName поддерживается в IE, но есть ошибки. В частности, он возвращает элементы, чей «id» соответствует заданному значению, а также «name». Не могу сказать, если это проблема, которую у вас есть, без немного больше контекста, кода и фактических сообщений об ошибках.

В общем, getElementsByName, вероятно, лучше избегать, поскольку атрибут «name» в HTML имеет несколько перекрывающихся целей, которые могут привести к путанице. Использование getElementById намного надежнее. При конкретной работе с полями формы вы можете более надежно использовать form.elements [name] для извлечения искомых полей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...