Dapatkan elemen di dalam elemen berdasarkan kelas dan ID - JavaScript

136

Baiklah, saya sudah mencoba-coba JavaScript sebelumnya, tetapi hal paling berguna yang saya tulis adalah CSS-switcher gaya. Jadi saya agak baru dalam hal ini. Katakanlah saya memiliki kode HTML seperti ini:

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

Bagaimana saya mengubah "Halo dunia!" ke "Selamat tinggal dunia!" ? Saya tahu bagaimana document.getElementByClass dan document.getElementById berfungsi, tetapi saya ingin lebih spesifik. Maaf jika ini sudah ditanyakan sebelumnya.

Tanner Babcock
sumber

Jawaban:

232

Nah, pertama-tama Anda harus memilih elemen dengan fungsi seperti getElementById.

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

getElementByIdhanya mengembalikan satu simpul, tetapi getElementsByClassNamemengembalikan daftar simpul. Karena hanya ada satu elemen dengan nama kelas itu (sejauh yang saya tahu), Anda bisa mendapatkan yang pertama (itulah gunanya [0]- itu seperti sebuah array).

Kemudian, Anda dapat mengubah html dengan .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>

Joseph Marikle
sumber
1
Mendapatkan ID induk tidak diperlukan dalam kasus ini. document.getElementsByClassNameakan bekerja dengan baik.
rvighne
7
@rvighne persyaratan OP yang pasti adalah bahwa ia "ingin mendapatkan yang lebih spesifik". Orang yang mengajukan pertanyaan menanyakan bagaimana ia bisa lebih spesifik dalam traversal pohon DOM-nya. Penggunaan getElementByClassName bukanlah titik kebingungan, tapi saya bisa melihat bagaimana seseorang dengan mudah berpikir saya mengindikasikan keduanya sebagaimana diperlukan. Mereka tidak. Jika Anda ingin menargetkan hanya elemen dari kelas tertentu yang berada di bawah simpul tertentu dari ID yang diberikan sebagai lawan elemen dari kelas yang sama di bawah simpul yang berbeda, inilah yang akan Anda gunakan.
Joseph Marikle
1
Mungkin baik untuk mengedit jawaban ini dan perubahan .innerHtmluntuk .textContentuntuk kepentingan keamanan copy / paste coders.
codescribblr
14

Anda dapat melakukannya seperti ini:

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

atau, jika Anda ingin melakukannya dengan lebih sedikit pengecekan kesalahan dan lebih singkatnya, bisa dilakukan dalam satu baris seperti ini:

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

Dalam penjelasan:

  1. Anda mendapatkan elemen dengan id="foo".
  2. Anda kemudian menemukan objek yang ada di dalam objek yang dimiliki class="bar".
  3. Itu mengembalikan nodeList seperti array, sehingga Anda referensi item pertama di nodeList itu
  4. Anda kemudian dapat mengatur innerHTMLitem itu untuk mengubah isinya.

Peringatan: beberapa browser lama tidak mendukung getElementsByClassName(mis. Versi IE yang lebih lama). Fungsi itu dapat di-shim ke tempatnya jika tidak ada.


Di sinilah saya sarankan menggunakan perpustakaan yang memiliki dukungan pemilih CSS3 built-in daripada khawatir tentang kompatibilitas browser sendiri (biarkan orang lain melakukan semua pekerjaan). Jika Anda hanya ingin perpustakaan melakukan itu, maka Sizzle akan bekerja dengan baik. Dalam Sizzle, ini akan dilakukan seperti ini:

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

jQuery memiliki built-in library Sizzle dan di jQuery, ini akan menjadi:

$("#foo .bar").html("Goodbye world!");
pacar00
sumber
Terima kasih, saya mengalami masalah dengan document.getElementBy *. jQuery membuat segalanya jadi lebih mudah.
Tanner Babcock
7

Jika ini perlu bekerja di IE 7 atau lebih rendah Anda harus ingat bahwa getElementsByClassName tidak ada di semua browser. Karena ini, Anda dapat membuat getElementsByClassName Anda sendiri atau Anda dapat mencoba ini.

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!";
    }
}
John Hartsock
sumber
getElementsByClassNamejuga tidak berfungsi di IE8, tetapi Anda dapat menggunakannya querySelectorAllsebagai gantinya (cukup banyak).
user113716
@ Ӫ _._ Ӫ ... lol ... Anda benar, tetapi Anda baru saja membuktikan jawaban saya. Anda tidak bisa mengandalkan getElementsByClassName jika halaman Anda perlu berfungsi di banyak browser. jQuery pasti akan menjadi pilihan tetapi jadi seperti kode di atas.
John Hartsock
Ya, saya maksudkan komentar itu untuk mendukung jawaban Anda, tetapi kemudian juga untuk menunjukkan bahwa dimungkinkan untuk digunakan qSAdalam shim sehingga Anda masih dapat menggunakan kode asli di IE8. Meskipun melihat lebih dekat pada solusi Anda, Anda punya beberapa hal yang perlu diperbaiki.
user113716
@ Ӫ _._ Ӫ ... ingin tahu apa yang Anda lihat ... karena saya tidak melihatnya.
John Hartsock
var i = 0, var child = fooDiv.childNodes[i]tidak valid. i <= fooDiv.childNodestidak terlalu masuk akal. childNode.className.test("bar")Tidak ada childNodevariabel, dan string tidak memiliki test()metode.
user113716
4

Fungsi rekursif:

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);
        }
    }
}
Avi Shimshilashvili
sumber
Ada bug kecil dalam sampel di atas. Alih-alih langsung kembali ke jalur lain Anda harus memeriksa apakah ada sesuatu yang ditemukan terlebih dahulu. Kalau tidak, node anak lainnya tidak akan diulang. Sesuatu seperti ini: if (elementToReturn) {return elementToReturn; }
Jannik
3

Cara termudah untuk melakukannya adalah:

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

atau lebih baik dibaca:

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

Anda tidak boleh menggunakan document.getElementByID karena hanya berfungsi untuk kontrol sisi klien yang id diperbaiki. Anda harus menggunakan jquery sebagai gantinya seperti contoh di bawah ini.

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

Gunakan ini :

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

// do not forget to add script tags as above

jika Anda ingin menghapus operasi edit apa pun maka tambahkan saja "." di belakang dan melakukan operasi

hardik akbari
sumber
10
Menggunakan senjata termonuklir untuk membunuh rusa akan berhasil, tetapi sedikit berlebihan. Menggunakan multi-kb jQuery library untuk memilih elemen ketika Javascript menawarkan fungsionalitas dalam kode dasar itu sedikit lebih banyak pembunuhan.
Danejir