Question

J'ai du code qui fait ça:

 var changes = document.getElementsByName(from);
 for (var c=0; c<changes.length; c++) {
   var ch = changes[c];
   var current = new String(ch.innerHTML);
   etc.
 }

Cela fonctionne très bien dans FF et Chrome, mais pas dans IE7. Probablement parce que getElementsByName ne fonctionne pas dans IE. Quelle est la meilleure solution de contournement?

Était-ce utile?

La solution

Si vous ne savez pas pourquoi cela ne fonctionne pas dans IE, voici la documentation MSDN sur cette fonction :

  

Lorsque vous utilisez la méthode getElementsByName, tous les éléments du document ayant l'attribut NAME spécifié ou la valeur d'attribut ID sont renvoyés.

     

Les éléments qui prennent en charge les attributs NAME et ID sont inclus dans la collection renvoyée par la méthode getElementsByName, mais les éléments avec un nom NAME expando ne sont pas inclus dans la collection. par conséquent, cette méthode ne peut pas être utilisée pour récupérer des balises personnalisées par nom.

Firefox autorise getElementsByName () pour récupérer des éléments qui utilisent un NOM expando, c’est pourquoi il fonctionne. Que ce soit ou non une bonne chose & # 8482; peut faire l’objet d’un débat, mais c’est la réalité.

Une option consiste donc à utiliser le getAttribute () Méthode DOM pour demander l'attribut NAME, puis tester la valeur pour voir si c'est ce que vous voulez et, le cas échéant, ajoutez-la à un tableau. Cependant, cela nécessiterait que vous parcouriez tous les nœuds de la page ou du moins une sous-section, ce qui ne serait pas le plus efficace. Vous pouvez au préalable contraindre cette liste en utilisant quelque chose comme getElementsByTagName () peut-être.

Si vous maîtrisez le code HTML de la page, vous pouvez également attribuer à tous les éléments d’intérêt un identifiant ne variant que par un nombre, par exemple:

.
<div id="Change0">...</div>
<div id="Change1">...</div>
<div id="Change2">...</div>
<div id="Change3">...</div>

Et puis avoir JavaScript comme ceci:

// 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");

C’est un bidouillage, bien sûr, mais cela ferait le travail dont vous avez besoin et ne serait pas trop inefficace comparé à d’autres bidouilleurs.

Si vous utilisez une sorte de framework / toolkit JavaScript, vos options sont bien meilleures, mais je n'ai pas le temps d'entrer dans ces détails sauf si vous indiquez que vous en utilisez un. Personnellement, je ne sais pas comment les gens vivent sans un, ils économisent tellement de temps, d’efforts et de frustration que vous ne pouvez pas vous permettre de ne pas en utiliser un.

Autres conseils

Il y a quelques problèmes:

  1. IE confond effectivement id = "" " avec name = " "
  2. name = "" " n'est pas autorisé sur < span >

Pour résoudre ce problème, je suggère:

  1. Remplacez tous les name = "" " par class = ""
  2. Modifiez votre code comme suit:

-

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);

Il n'est pas très courant de trouver des éléments à l'aide de la propriété NAME. Je recommanderais de passer à la propriété ID.

Vous pouvez cependant trouver des éléments avec un nom spécifique en utilisant jQuery:

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

cela retournera tous les éléments avec le nom donné.

getElementsByName est pris en charge dans IE, mais il existe des bogues. En particulier, il renvoie les éléments dont le "id" correspond à la valeur donnée, ainsi que le "nom". Vous ne pouvez pas savoir si c'est le problème que vous rencontrez sans un peu plus de contexte, de code et de messages d'erreur réels.

En général, il est probablement préférable d'éviter getElementsByName, car l'attribut "name" en HTML a plusieurs objectifs qui se chevauchent, ce qui peut prêter à confusion. L'utilisation de getElementById est beaucoup plus fiable. Lorsque vous travaillez spécifiquement avec des champs de formulaire, vous pouvez utiliser de manière plus fiable form.elements [nom] pour récupérer les champs que vous recherchez.

J'ai réussi à utiliser un wrapper pour renvoyer un tableau des éléments. Fonctionne dans IE 6 et 7 aussi. Gardez à l'esprit que ce n'est pas exactement la même chose que document.getElementsByName, car ce n'est pas une liste de noeuds. Mais pour ce dont j’ai besoin, c’est d’exécuter une boucle for sur un tableau d’éléments pour effectuer des opérations simples, telles que la définition de .disabled = true, cela fonctionne suffisamment bien.

Même si cette fonction utilise toujours getElementsByName, elle fonctionne si elle est utilisée de cette façon. Voyez vous-même.

function getElementsByNameWrapper(name) {
  a = new Array();

  for (var i = 0; i < document.getElementsByName(name).length; ++i) {
    a.push(document.getElementsByName(name)[i]);
  }

  return a;
}

Solution de contournement

                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]);
                    }
                }
            }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top