Ottieni elemento all'interno dell'elemento per classe e ID - JavaScript


136

Va bene, mi sono dilettato in JavaScript prima, ma la cosa più utile che ho scritto è un cambio di stile CSS. Quindi sono un po 'nuovo in questo. Diciamo che ho un codice HTML come questo:

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

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

Risposte:


232

Bene, prima devi selezionare gli elementi con una funzione simile getElementById.

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

getElementByIdrestituisce solo un nodo, ma getElementsByClassNamerestituisce un elenco di nodi. Dal momento che esiste solo un elemento con quel nome di classe (per quanto posso dire), puoi semplicemente ottenere il primo (ecco a cosa [0]serve - è proprio come un array).

Quindi, puoi cambiare l'html con .textContent.

targetDiv.textContent = "Goodbye world!";

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


1
In questo caso non è necessario ottenere il genitore tramite ID. document.getElementsByClassNamefunzionerebbe benissimo.
rvighne,

7
@rvighne i requisiti esatti di OP era che "vorrebbe essere più specifico". La persona che stava ponendo la domanda si chiedeva come potesse essere più specifico nella sua traversata dell'albero del DOM. L'uso di getElementByClassName non è stato un punto di confusione, ma posso vedere come qualcuno potrebbe facilmente pensare che stavo indicando entrambi come necessario. Non sono. Se desideri scegliere come target solo elementi di una determinata classe che si trovano sotto un nodo particolare di un determinato ID anziché elementi di quella stessa classe in un nodo diverso, questo è quello che useresti.
Joseph Marikle,

1
Potrebbe essere utile modificare questa risposta e modificarla .innerHtmla .textContentbeneficio della sicurezza dei programmatori di copia / incolla.
codescribblr

14

Puoi farlo in questo modo:

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

oppure, se vuoi farlo con meno controllo degli errori e più brevità, puoi farlo in una riga come questa:

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

In spiegazione:

  1. Ottieni l'elemento con id="foo".
  2. Quindi trovi gli oggetti contenuti in quell'oggetto che hanno class="bar".
  3. Ciò restituisce un nodeList simile ad un array, quindi fai riferimento al primo elemento in quel nodeList
  4. È quindi possibile impostare l' innerHTMLelemento di quell'elemento per modificarne il contenuto.

Avvertenze: alcuni browser meno recenti non supportano getElementsByClassName(ad esempio versioni precedenti di IE). Tale funzione può essere shimmed in posizione se mancante.


Qui è dove consiglio di utilizzare una libreria che ha il supporto selettore CSS3 incorporato piuttosto che preoccuparsi della compatibilità del browser (lasciare che qualcun altro faccia tutto il lavoro). Se vuoi che solo una biblioteca lo faccia, allora Sizzle funzionerà alla grande. In Sizzle, questo sarebbe fatto così:

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

jQuery ha la libreria Sizzle integrata e in jQuery, questo sarebbe:

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

Grazie, ho avuto problemi con document.getElementBy *. jQuery rende le cose molto più facili.
Tanner Babcock,

7

Se questo deve funzionare in IE 7 o versioni precedenti, è necessario ricordare che getElementsByClassName non esiste in tutti i browser. Per questo motivo puoi creare il tuo getElementsByClassName oppure 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!";
    }
}

getElementsByClassNamenon funziona in IE8, ma puoi usarlo querySelectorAllal suo posto (praticamente comunque).
user113716

@ Ӫ _._ Ӫ ... lol ... hai ragione, 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ì dovrebbe essere il codice sopra.
John Hartsock,

Sì, intendevo quel commento a supporto della tua risposta, ma poi anche per sottolineare che è possibile utilizzare qSAin uno shim in modo da poter ancora utilizzare il codice nativo in IE8. Anche se dai un'occhiata più da vicino alla tua soluzione, hai alcune cose che devono essere riparate.
user113716

@ Ӫ _._ Ӫ ... curioso cosa vedi ... perché non lo vedo.
John Hartsock,

var i = 0, var child = fooDiv.childNodes[i]è invalido. i <= fooDiv.childNodesnon ha davvero senso. childNode.className.test("bar")Non ci sono childNodevariabili e una stringa non ha un test()metodo.
user113716

4

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

C'è un bug minore nell'esempio sopra. Invece di tornare all'istante nel percorso else devi controllare se qualcosa è stato trovato per primo. In caso contrario, gli altri nodi figlio non verranno ripetuti. Qualcosa del genere: if (elementToReturn) {return elementToReturn; }
Jannik,

3

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}]`);
}

-4

Document.getElementByID non dovrebbe essere utilizzato perché funziona solo per i controlli lato client quali ID sono corretti. Dovresti usare jquery come nell'esempio seguente.

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

Usa questo :

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

// do not forget to add script tags as above

se si desidera rimuovere, modificare qualsiasi operazione, aggiungere semplicemente "." dietro e fare le operazioni


10
L'uso di un'arma termonucleare per uccidere un cervo funzionerà, ma è leggermente eccessivo. L'uso di una libreria jQuery multi-kb per selezionare un elemento quando Javascript offre che la funzionalità nel suo codice di base è leggermente più eccessivo.
Danejir,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.