getAttribute () versus properti objek Elemen?

92

Ekspresi menyukai Element.getAttribute("id")dan Element.idmengembalikan hal yang sama.

Manakah yang harus digunakan saat kita membutuhkan atribut objek HTMLElement?

Apakah ada masalah lintas browser dengan metode seperti getAttribute()dan setAttribute()?

Atau dampak apa pun pada kinerja antara mengakses langsung properti objek vs menggunakan metode atribut ini?

PK
sumber
1
Pertanyaan serupa: Properti dan Atribut dalam HTML
sleske

Jawaban:

126

getAttributemengambil atribut dari elemen DOM, sementara el.idmengambil properti dari elemen DOM ini. Mereka tidaklah sama.

Seringkali, properti DOM disinkronkan dengan atribut.

Namun, sinkronisasi tidak menjamin nilai yang sama . Contoh klasik adalah antara el.hrefdan el.getAttribute('href')untuk elemen jangkar.

Sebagai contoh:

<a href="/" id="hey"></a>
<script>
var a = document.getElementById('hey')
a.getAttribute('href') // "/"
a.href // Full URL except for IE that keeps '/'
</script>

Perilaku ini terjadi karena menurut W3C , properti href harus berupa tautan yang dibentuk dengan baik. Kebanyakan browser menghormati standar ini (coba tebak siapa yang tidak?).

Ada kasus lain untuk input's checkedproperti. Properti DOM mengembalikan trueatau falsesaat atribut mengembalikan string "checked"atau string kosong.

Lalu, ada beberapa properti yang hanya disinkronkan satu arah . Contoh terbaik adalah valueproperti sebuah inputelemen. Mengubah nilainya melalui properti DOM tidak akan mengubah atribut (edit: periksa komentar pertama untuk lebih presisi).

Karena alasan ini, saya sarankan Anda tetap menggunakan properti DOM , dan bukan atributnya, karena perilakunya berbeda di antara browser.

Pada kenyataannya, hanya ada dua kasus di mana Anda perlu menggunakan atribut:

  1. Atribut HTML khusus, karena tidak disinkronkan ke properti DOM.
  2. Untuk mengakses built-in HTML atribut, yang tidak disinkronkan dari properti, dan Anda yakin Anda membutuhkan atribut (misalnya, asli valuedari sebuah inputelemen).

Jika Anda menginginkan penjelasan yang lebih detail, saya sangat menyarankan Anda membaca halaman ini . Ini hanya akan memakan waktu beberapa menit, tetapi Anda akan senang dengan informasi (yang saya simpulkan di sini).

Florian Margaine
sumber
9
1 untuk nasihat yang umumnya baik. Masalah sinkronisasi sedikit meleset: valueproperti input mendapatkan nilai awalnya dari atribut tetapi sebaliknya tidak terikat sama sekali. The valueatribut sepenuhnya disinkronkan bukan dengan defaultValueproperti. Demikian juga checkeddan defaultChecked. Kecuali di IE lama (<= 7 dan mode kompatibilitas nanti), yang telah rusak getAttribute()dan setAttribute().
Tim Down
Menambahkan komentar Anda sebagai "penjelasan lebih lanjut" :-)
Florian Margaine
2
Saya pikir contoh pertama Anda salah. a.hrefmengembalikan URL lengkap, a.getAttribute("href")mengembalikan atribut persis seperti defiend di sumber HTML.
Salman A
Jika Anda mencoba untuk mencari tahu apakah suatu nilai bukan default, Anda lebih baik menggunakan atribut. Banyak browser modern akan mengembalikan nilai default (misalnya input.formAction) atau string kosong (misalnya a.download), yang membuat segalanya menjadi ambigu. Satu-satunya pengecualian adalah nilai yang tidak disinkronkan 2 arah, seperti value.
Kevin Li
Jika id tidak disetel sama sekali di dom, getAttribute akan mengembalikan null dan element.id akan mengembalikan string kosong. Apakah ini standar?
Maciej Krawczyk
11

getAttribute('attribute') biasanya mengembalikan nilai atribut sebagai string, persis seperti yang ditentukan dalam sumber HTML halaman.

Namun, element.attributedapat mengembalikan nilai atribut yang dinormalisasi atau dihitung. Contoh:

  • <a href="https://stackoverflow.com/foo"></a>
    • a.href akan berisi URL lengkap
  • <input type="checkbox" checked>
    • input.checked akan menjadi true (boolean)
  • <input type="checkbox" checked="bleh">
    • input.checked akan menjadi true (boolean)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • img.width akan menjadi 0 (angka) sebelum gambar dimuat
    • img.width akan menjadi 64 (angka) saat gambar (atau beberapa byte pertama) dimuat
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img.width akan dihitung 50%
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img.width akan menjadi 50 (angka)
  • <div style='background: lime;'></div>
    • div.style akan menjadi objek
Salman A
sumber
3

Menurut pengujian jsPerf getAttribute ini lebih lambat daripada idproperti.

PS

Anehnya, kedua pernyataan tersebut berkinerja sangat buruk di IE8 (dibandingkan dengan peramban lain).

mamoo
sumber
3

Selalu gunakan properti kecuali Anda memiliki alasan khusus untuk tidak melakukannya.

  • getAttribute()dan setAttribute()rusak di IE lama (dan mode kompatibilitas di versi yang lebih baru)
  • properti lebih nyaman (khususnya, yang sesuai dengan atribut boolean)

Ada beberapa pengecualian :

  • mengakses atribut <form> elemen
  • mengakses atribut khusus (meskipun saya sama sekali tidak menyarankan menggunakan atribut khusus)

Saya telah menulis tentang subjek ini beberapa kali di SO:

Tim Down
sumber
Sebelum IE 8, properti dan atribut diperlakukan secara identik . Seperti yang Anda singgung sebelumnya, properti adalah cara terbaik.
@MattMcDonald: Ya, itulah kehancuran yang saya singgung. Saya tidak memperluasnya dalam jawaban ini karena saya merasa telah melakukannya cukup banyak dalam jawaban lain yang saya tautkan :)
Tim Down
3

.idmenghemat overhead panggilan fungsi. (yang sangat kecil, tetapi Anda bertanya.)

gdoron mendukung Monica
sumber
Hai gdoron, hanya demi rasa ingin tahu: Saya mencoba menemukan penjelasan 'resmi' tentang ini (di luar uji empiris, yang cukup jelas;)) tetapi tidak berhasil. Apakah Anda punya link tentang itu?
mamoo
0

Coba contoh di bawah ini untuk memahami ini sepenuhnya. Untuk DIV di bawah ini

<div class="myclass"></div>

The Element.getAttribute('class')akan kembali myclasstetapi Anda harus menggunakan Element.classNameyang mengambil dari properti DOM.

Hrushikesh
sumber
0

Satu area di mana hal ini membuat perbedaan besar adalah dengan gaya css berdasarkan atribut.

Pertimbangkan hal berikut:

const divs = document.querySelectorAll('div');

divs[1].custom = true;
divs[2].setAttribute('custom', true);
div {
  border: 1px solid;
  margin-bottom: 8px;
}

div[custom] {
  background: #36a;
  color: #fff;
}
<div>A normal div</div>
<div>A div with a custom property set directly.</div>
<div>A div with a custom attribute set with `setAttribute`</div>

Div dengan set properti khusus secara langsung tidak mencerminkan nilai ke atribut, dan tidak dipilih oleh pemilih atribut kami (div[custom] ) di css.

Namun, div dengan atribut khusus yang ditetapkan setAttributedapat dipilih menggunakan pemilih atribut css, dan diberi gaya yang sesuai.

Jsilvermist
sumber