2010-02-19 10 views
15

Ho scritto un sistema di tabulazione utilizzando un Javascript molto semplice e funziona come un campione in IE 8 ma, in FireFox 3 sto arrivando in breve . Il codice HTML pertitent è la seguente:element.firstChild restituisce '<TextNode ...' invece di un oggetto in 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> 

Poi, al caricamento della pagina, si disconnette in questo metodo:

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

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

Il resto del codice non importa a questo punto perché non è mai viene chiamato . tabContainer è impostato correttamente per fare riferimento al div con le schede ID. Ora, in Internet Explorer quando chiamo tabContainer.firstChild la variabile 'tabs' fa riferimento alla mia UL e quindi alla variabile var call = tabs.firstChild; fa riferimento alla mia prima LI. Il problema è che quando chiamo tabContainer.firstChild Venkman mi sta dicendo che sta tornando. Quindi Firefox sta leggendo le mie nuove righe come veri bambini all'interno del div! Il mio UL è in realtà il secondo figlio della collezione childNodes!

C'è un modo per risolvere questo problema?

Grazie!

risposta

24

Si dovrebbe saltare la TextNodes, una semplice funzione può aiutare:

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

Usage:

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

Ben fatto, ha funzionato come un fascino! – dparsons

+3

Nella funzione 'getFirstChild' verificherei' firstChild.nodeType! = 1' invece di 'firstChild.nodeType == 3' per saltare anche altri tipi di nodi come i commenti. – Cito

+0

Questa risposta dovrebbe essere aggiornata alla modifica suggerita da @Cito, ho appena incontrato uno sviluppatore che ha copiato questo codice esatto e sicuramente c'era un commento HTML prima del primo nodo di elementi che era stato cercato ...e quindi fallito. – scunliffe

11

È possibile utilizzare node.firstElementChild per ignorare il testo principale o utilizzare una libreria come jQuery che si occupa di questo.

+2

node.firstElementChild è supportata solo in FF 3.5 quindi ho ancora finire con il problema nelle versioni precedenti. jQuery non è un'opzione nel mio caso. Il post di CMS sopra ha risolto il problema. – dparsons

0

Consiglierei a chiunque cercando di lavorare con il DOM in javascript per usare una libreria come jquery. Renderà la tua vita molto più facile.

È quindi possibile riscrivere la funzione di JS come Fallows:

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

Mentre le strutture sono belle, non sono un lusso che mi è attualmente consentito di usare. Grazie per la soluzione però! – dparsons

+1

Anche se adoro jQuery, è difficile inserirlo in un bookmarklet! – scraimer

2

Con un occhio anche su efficienza, questa funzione restituisce firstChild nodo elemento di el

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

@yckart: grazie per la correzione, era totalmente sbagliato. –

5

Usa element.querySelector("*") per ottenere la prima elemento figlio.

Demo:

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

Nessun voto su questo, nessun motivo questa non è la soluzione? – Joel

+3

@Joel Ho aggiunto la risposta 6 anni dopo, forse questo è il motivo :) – CoderPi

0

Si può provare

document.getElementById(TabContainer).firstElementChild; 

invece di firstChild

Problemi correlati