2009-05-04 10 views
1

Étant donné que la fonction getElementsByTagName() est nouvelle (DOM-1?), J'ai voulu une autre méthode plus fiable pour obtenir une référence à un élément en fonction de son nom/identifiant de tag.Alternative à getElementsByTagName

Éditer- Sans utiliser un cadre, puisque je dois réduire la taille; donc 10-20K pour un cadre est inacceptable. Je dois juste le code JS qui peut récupérer un élément

+0

Fait correctement le 20k ou plus pour jquery est seulement téléchargé une fois. – cletus

+4

getElementsByTagName() est en effet DOM niveau 1. Il supporte depuis IE5, Opera 7 et toutes les versions de Mozilla et Safari. De quel navigateur es-tu inquiet? NN3? ;) Ref: http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#method-getElementsByTagName – JPot

+0

@Jeremy: sérieusement, êtes-vous en train de viser une personne plus âgée? navigateur (s) qui ne supporte pas getElementsByTagName()? – JPot

Répondre

15

getElementsByTagName est pas nouveau. Il est supporté depuis IE5, FF1 et Opera 7 selon w3schools

[edit] Merci d'avoir signalé cela. Il était en effet supporté depuis Opera 7.

+0

Merci pour la clarification. C'était une très vieille rumeur. –

+0

Son Opera 7, et toutes les versions de Mozilla et Safari - selon "indéfini". –

+0

En fait, Opera l'avait déjà v7. Voir http://www.opera.com/docs/specs/opera7/js/dom/ – JPot

4

Comme mentionné précédemment, getElementsByTagName n'est pas nouveau ...

Je pense que vous allez obtenir environ 10 références à jQuery.

Renvoie tous les éléments de paragraphe:

$('p').length 

Si 19kb est trop grand, et que vous voulez juste faire la sélection des éléments, quelque chose comme sizzle fonctionne bien, à environ 4 Ko. La seule chose que je noterais, c'est que vous allez probablement avoir besoin de quelque chose qui est en jQuery de toute façon.

http://sizzlejs.com/

requêtes sont très similaires:

Sizzle("li"); 

19kb est un très petit prix unique à payer pour la puissance de jQuery.

+0

Qu'en est-il de la fenêtre [id?] Et du document [id?]. –

+5

Je n'ai pas encore trouvé de raison * pas * d'utiliser jquery. C'est juste si élégant et facile à utiliser ... –

+0

Je ne sais pas pourquoi vous voudriez faire cela, ma réponse serait non. – cgp

0

Ou un prototype, etc. Vous devrez utiliser une de ces bibliothèques de colle javascript pour y parvenir. Tous appellent cette fonction si elle existe, mais simulez-la autrement.

+0

Oui. :) Exactement. – cgp

3

Si tout ce que vous voulez faire est de sélectionner des éléments, il peut être judicieux d'utiliser simplement le moteur de sélection Sizzle et non une bibliothèque complète. J'irais avec la bibliothèque complète, mais, aller avec un moteur de sélection pourrait être utile dans des circonstances limitées.

Sizzle est le moteur de sélection CSS qui alimente jQuery.

http://sizzlejs.com/

0

Voici une implémentation basée sur l'implémentation jQuery 1.12.4. Il utilise getElementsByTagName si disponible. Sinon, il utilise querySelectorAll si disponible. Sinon, il revient sur la traversée récursive. jQuery 1.12.4 prend en charge les navigateurs plus anciens, tels que IE6, selon themselves.

function getElementsByTagName(node, tagName) { 
    if (tagName == '*') { 
    tagName = undefined; 
    } 
    var merge = function(first, second) { 
     var len = +second.length, 
      j = 0, 
      i = first.length; 

     while (j < len) { 
      first[ i++ ] = second[ j++ ]; 
     } 

     // Support: IE<9 
     // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) 
     if (len !== len) { 
      while (second[ j ] !== undefined) { 
       first[ i++ ] = second[ j++ ]; 
      } 
     } 

     first.length = i; 

     return first; 
    }, 
    nodeName = function(elem, name) { 
     return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 
    }, 
    elems, elem, 
    i = 0, 
    context = node, 
    tag = tagName, 
    found = typeof context.getElementsByTagName !== "undefined" ? 
     context.getElementsByTagName(tag || "*") : 
     typeof context.querySelectorAll !== "undefined" ? 
      context.querySelectorAll(tag || "*") : 
      undefined; 

    if (!found) { 
     for (found = [], elems = context.childNodes || context; 
      (elem = elems[ i ]) != null; 
      i++ 
     ) { 
      if (!tag || nodeName(elem, tag)) { 
       found.push(elem); 
      } else { 
       merge(found, getElementsByTagName(elem, tag)); 
      } 
     } 
    } 

    return found; 
/* return tag === undefined || tag && nodeName(context, tag) ? 
     merge([ context ], found) : 
     found;*/ 
} 

Je pris la getAll() fonction interne de jQuery 1.12.4 et dans les deux copiés fonctions d'aide dont il a besoin (et jQuery.nodeName jQuery.merge). J'ai également fait en sorte que vous pouvez l'appeler avec "*" comme tagName en ajoutant quelques lignes dans le haut de la fonction. Enfin, à la fin de la fonction, j'ai commenté certaines fonctionnalités, ce qui ajoute le nœud courant au résultat (s'il correspond), et renvoie simplement les nœuds trouvés. Sachez que la fonction renvoie dans certains cas un HTMLCollection et, dans d'autres circonstances, renvoie un tableau. Notez également que lorsque "*" est transmis en tant que variable, la sortie diffère en fonction du navigateur: L'élément.prototype.getElementsByTagName ne renvoie pas TextNodes, mais la traversée récursive le fait. Vous pouvez également utiliser picoQuery. picoQuery est une implémentation de jQuery, dans laquelle vous pouvez sélectionner les méthodes dont vous avez besoin dans un générateur en ligne. Dans ce cas, vous n'avez besoin d'aucune méthode, car la sélection fait partie du noyau et la construction est gzippée à seulement 1kb. picoQuery est écrit pour les navigateurs modernes, mais revient à jQuery 1.12.4 pour les navigateurs plus anciens.