2011-10-19 9 views
68

OK, mi sono già dilungato in JavaScript, ma la cosa più utile che ho scritto è un commutatore di stili CSS. Quindi sono un po 'nuovo a questo. Diciamo che ho un codice HTML come questo:Ottieni elemento all'interno dell'elemento per classe e ID - JavaScript

<div id="foo"> 
    <div class="bar"> 
     Hello world! 
    </div> 
</div> 

Come cambierei "Ciao mondo!" a "Addio mondo!" ? So come funzionano document.getElementByClass e document.getElementById, ma vorrei essere più specifico. Scusate se questo è stato già chiesto precedentemente.

risposta

126

Beh, in primo luogo è necessario selezionare gli elementi con una funzione come getElementById.

var targetDiv = document.getElementById("foo").getElementsByClassName("bar")[0]; 

getElementById restituisce un solo nodo, ma getElementsByClassName restituisce un elenco dei nodi. Dato che c'è un solo elemento con quel nome di classe (per quanto posso dire), puoi semplicemente prendere il primo (è quello che è lo [0] per-è proprio come un array).

Quindi, è possibile modificare l'html con .innerHTML.

targetDiv.innerHTML = "Goodbye world!"; 

var targetDiv = document.getElementById("foo").getElementsByClassName("bar")[0]; 
 
targetDiv.innerHTML = "Goodbye world!";
<div id="foo"> 
 
    <div class="bar"> 
 
     Hello world! 
 
    </div> 
 
</div>

+1

In questo caso non è necessario ottenere il genitore tramite ID. 'document.getElementsByClassName' funzionerebbe correttamente. – rvighne

+6

@rvighne i requisiti esatti dell'OP erano che "desiderava essere più specifico". La persona che ha posto la domanda stava chiedendo come avrebbe potuto essere più specifico nella sua traversata dell'albero DOM. L'uso di getElementByClassName non era un punto di confusione, ma posso vedere come qualcuno potrebbe facilmente pensare che stavo indicando entrambi come necessario. Non sono. Se vuoi scegliere come target solo gli elementi di una determinata classe che si trovano sotto un particolare nodo di un determinato ID anziché elementi della stessa classe in un nodo diverso, questo è ciò che useresti. –

+1

@JosephMarikle Vedo. Credo di aver letto la domanda troppo velocemente. – rvighne

10

Si può fare in questo modo:

var list = document.getElementById("foo").getElementsByClassName("bar"); 
if (list && list.length > 0) { 
    list[0].innerHTML = "Goodbye world!"; 
} 

o, se si vuole farlo con con meno controllo degli errori e più brevità, può essere fatto in una sola riga come questa:

document.getElementById("foo").getElementsByClassName("bar")[0].innerHTML = "Goodbye world!"; 

In spiegazione:

  1. si ottiene l'elemento con id="foo".
  2. Quindi si trovano gli oggetti contenuti all'interno dell'oggetto che hanno class="bar".
  3. che restituisce un array nodeList come, in modo si fa riferimento il primo elemento che nodeList
  4. È quindi possibile impostare la innerHTML di tale elemento per modificarne il contenuto.

Avvertenze: alcuni browser meno recenti non supportano getElementsByClassName (ad esempio versioni precedenti di IE). Quella funzione può essere rimessa a posto se mancante.


Questo è dove mi consiglia di utilizzare una libreria che ha il supporto integrato selettore CSS3 piuttosto che preoccuparsi di compatibilità del browser te (lasciare che qualcun altro fare tutto il lavoro). Se vuoi solo una libreria per farlo, allora Sizzle funzionerà alla grande. In Sizzle, questo sarebbe essere fatto in questo modo:

Sizzle("#foo .bar")[0].innerHTML = "Goodbye world!"; 

jQuery ha biblioteca Sizzle incorporato e in jQuery, questo sarebbe:

$("#foo .bar").html("Goodbye world!"); 
+0

Grazie, ho avuto problemi con document.getElementBy *. jQuery rende le cose molto più semplici. –

4

Se questo ha bisogno di lavorare in IE 7 o inferiore è necessario ricordare che getElementsByClassName non esiste in tutti i browser. Per questo motivo puoi creare il tuo getElementsByClassName o puoi provare questo.

var fooDiv = document.getElementById("foo"); 

for (var i = 0, childNode; i <= fooDiv.childNodes.length; i ++) { 
    childNode = fooDiv.childNodes[i]; 
    if (/bar/.test(childNode.className)) { 
     childNode.innerHTML = "Goodbye world!"; 
    } 
} 
+0

'getElementsByClassName' non funziona nemmeno in IE8, ma puoi usare' querySelectorAll' al suo posto (praticamente lo stesso). – user113716

+0

@ Ӫ _._ Ӫ ... lol ... il tuo corretto ma tu provi ancora di più la mia risposta. Non puoi fare affidamento su getElementsByClassName se la tua pagina deve funzionare su più browser. jQuery sarebbe sicuramente un'opzione ma così come il codice sopra. –

+0

Sì, intendevo quel commento a sostegno della tua risposta, ma poi anche per segnalare che è possibile usare 'qSA' in uno shim in modo che tu possa ancora usare il codice nativo in IE8. Anche se dai un'occhiata più da vicino alla tua soluzione, hai alcune cose che devono essere risolte. – user113716

-3

Si consiglia di non utilizzare document.getElementById perché il suo lavoro solo per i controlli lato client che id sono fissi. Dovresti usare jquery invece come nell'esempio qui sotto.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>                            
<div id="foo"> 
    <div class="bar"> 
      Hello world! 
    </div> 
</div> 

uso questo: ""

$("[id^='foo']").find("[class^='bar']") 

// do not forget to add script tags as above 

se volete qualsiasi modifica cancellare qualunque operazione poi basta aggiungere alle spalle e fare le operazioni

+7

Utilizzo di un'arma termonucleare per uccidere un cervo funzionerà, ma è un po 'eccessivo. Usare una libreria jQuery multi-kb per selezionare un elemento quando Javascript offre quella funzionalità nel suo codice base è leggermente più esagerato. – Danejir

3

funzione ricorsiva:

function getElementInsideElement(baseElement, wantedElementID) { 
    var elementToReturn; 
    for (var i = 0; i < baseElement.childNodes.length; i++) { 
     elementToReturn = baseElement.childNodes[i]; 
     if (elementToReturn.id == wantedElementID) { 
      return elementToReturn; 
     } else { 
      return getElementInsideElement(elementToReturn, wantedElementID); 
     } 
    } 
} 
0

il modo più semplice per farlo è:

function findChild(idOfElement, idOfChild){ 
    let element = document.getElementById(idOfElement); 
    return element.querySelector('[id=' + idOfChild + ']'); 
} 

o meglio leggibile:

findChild = (idOfElement, idOfChild) => { 
    let element = document.getElementById(idOfElement); 
    return element.querySelector(`[id=${idOfChild}]`); 
}