2010-02-19 4 views
15

J'ai écrit un système d'onglets en utilisant du Javascript très basique et il fonctionne comme un champion dans IE 8 mais, dans FireFox 3 je suis à court . Le pertitent HTML est comme suit:element.firstChild retourne '<TextNode ...' au lieu d'un objet en FF

  <div id="tabs"> 
       <ul class="tabs"> 
        <li class="current"><a><span>News</span></a></li> 
        <li><a><span>Videos</span></a></li> 
        <li><a><span>Photos</span></a></li> 
        <li><a><span>Twitter</span></a></li> 
       </ul> 
      </div> 

Ensuite, la charge de la page, je suis tombé dans cette méthode:

function processTabs(TabContainer, PageContainer, Index) { 
var tabContainer = document.getElementById(TabContainer); 
var tabs = tabContainer.firstChild; 

var tab = tabs.firstChild; 
var i = 0; 
.... more code } 

Le reste du code n'a pas d'importance à ce stade, car il ne sera jamais appelé . TabContainer est correctement défini pour référencer la div avec les onglets d'identité. Maintenant, dans Internet Explorer quand je l'appelle tabContainer.firstChild la variable « onglets » fait référence à mon UL puis sur l'onglet appel var = tabs.firstChild; références mon premier LI. Le problème est que quand je l'appelle tabContainer.firstChild Venkman me dit qu'il est de retour. Donc firefox lit mes nouvelles lignes comme des enfants réels à l'intérieur de la div! Mon UL est en fait le deuxième enfant de la collection childNodes!

Y at-il un moyen de résoudre ce problème?

Merci!

Répondre

24

Vous devez ignorer la TextNodes, une fonction simple peut vous aider à:

function getFirstChild(el){ 
    var firstChild = el.firstChild; 
    while(firstChild != null && firstChild.nodeType == 3){ // skip TextNodes 
    firstChild = firstChild.nextSibling; 
    } 
    return firstChild; 
} 

Utilisation:

var tabContainer = document.getElementById(TabContainer); 
var tabs = getFirstChild(tabContainer); 
+1

Bien fait, travaillé comme un charme! – dparsons

+3

Dans la fonction 'getFirstChild' je vérifierais' firstChild.nodeType! = 1' au lieu de 'firstChild.nodeType == 3' afin d'ignorer aussi d'autres types de nœuds tels que les commentaires. – Cito

+0

Cette réponse devrait être mise à jour pour le changement @Cito suggéré, je viens de rencontrer un développeur qui a copié ce code exact, et bien sûr, il y avait un commentaire HTML avant le premier nœud de l'élément qui a été recherché ...et donc échoué. – scunliffe

11

Vous pouvez utiliser node.firstElementChild d'ignorer le texte principal, ou utiliser une bibliothèque comme jQuery qui prend soin de cela.

+2

node.firstElementChild est pris en charge dans 3,5 FF alors que je le vent toujours avec le problème dans les anciennes versions. jQuery n'est pas une option dans mon cas. Le message de CMS ci-dessus a résolu le problème. – dparsons

0

Je recommande tous ceux qui essaient de travailler avec les DOM en javascript pour utiliser une bibliothèque comme jquery. Cela rendra votre vie beaucoup plus facile.

Vous pouvez ensuite réécrire la fonction JS placé comme suit:

function processTabs(TabContainer, PageContainer, Index) { 
    var tabContainer = document.getElementById(TabContainer); 

    // jquery used to find all the <li> elements 
    var tabs = $(tabContainer).filter('li'); 

    // use the jquery get(index) function to retrieve the first tab 
    var tab = tabs.get(0); 
    var i = 0; 
    .... more code 
} 
+3

Bien que les cadres sont agréables, ils ne sont pas un luxe que je suis actuellement autorisé à utiliser. Merci pour la solution! – dparsons

+1

Bien que j'aime jQuery, il est difficile de l'insérer dans un bookmarklet! – scraimer

2

Avec un oeil aussi sur l'efficacité, cette fonction retourne nœud d'élément firstChild de el

function firstChildElement(el) 
{ 
    el = el.firstChild; 
    while (el && el.nodeType !== 1) 
     el = el.nextSibling; 
    return el; 
} 
+0

@yckart: merci pour la correction, c'était totalement faux. –

5

Utilisez element.querySelector("*") pour obtenir la première élément enfant.

Démo:

var container = document.getElementById("container") 
 

 
console.log(container.querySelector("*")) // <div>This is a test</div> 
 
console.log(container.firstChild) // #text 
 
console.log(container.childNodes[0]) // #text
<div id="container"> 
 
    <div>This is a test</div> 
 
</div>

+0

Pas de vote à ce sujet, quelle que soit la raison pour laquelle ce n'est pas la solution? – Joel

+3

@Joel J'ai ajouté la réponse 6 ans plus tard, c'est peut-être pourquoi :) – CoderPi

0

Vous pouvez

document.getElementById(TabContainer).firstElementChild; 

au lieu de firstChild

Questions connexes