.prop () vs .attr ()

2301

Jadi jQuery 1.6 memiliki fungsi baru prop().

$(selector).click(function(){
    //instead of:
    this.getAttribute('style');
    //do i use:
    $(this).prop('style');
    //or:
    $(this).attr('style');
})

atau dalam hal ini apakah mereka melakukan hal yang sama?

Dan jika saya tidak harus beralih menggunakan prop(), semua lama attr()panggilan akan pecah jika saya beralih ke 1.6?

MEMPERBARUI

selector = '#id'

$(selector).click(function() {
    //instead of:
    var getAtt = this.getAttribute('style');
    //do i use:
    var thisProp = $(this).prop('style');
    //or:
    var thisAttr = $(this).attr('style');

    console.log(getAtt, thisProp, thisAttr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id='id' style="color: red;background: orange;">test</div>

(lihat juga biola ini: http://jsfiddle.net/maniator/JpUF2/ )

Konsol mencatat getAttributesebagai string, dan attrsebagai string, tetapi propsebagai CSSStyleDeclaration, Mengapa? Dan bagaimana hal itu mempengaruhi pengkodean saya di masa mendatang?

Naftali alias Neal
sumber
17
Ini akan sangat menarik: books.google.ca/…
28
@Neal, itu karena perubahan ini melampaui jQuery. Perbedaan antara atribut HTML dan properti DOM sangat besar.
7
Itu membuat saya sedih melihat jQuery mengembalikan perubahan. Mereka menuju ke arah yang salah.
4
@Neal. Ya, dan itu hanya memperumit masalah lebih lanjut daripada memisahkan kedua metode.
6
@BritishDeveloper jawabannya lebih rumit daripada hanya menyatakan selalu menggunakan x atau y karena itu tergantung pada apa yang ingin Anda dapatkan. Apakah Anda ingin atributnya, atau Anda ingin properti itu? mereka adalah dua hal yang sangat berbeda.
Kevin B

Jawaban:

1876

Pembaruan 1 November 2012

Jawaban asli saya berlaku khusus untuk jQuery 1.6. Saran saya tetap sama tetapi jQuery 1.6.1 mengubah sedikit hal: dalam menghadapi tumpukan situs web yang diprediksi, tim jQuery kembali attr()ke sesuatu yang dekat dengan (tetapi tidak persis sama dengan) perilaku lamanya untuk atribut Boolean . John Resig juga membuat blog tentang hal itu . Saya bisa melihat kesulitan yang mereka hadapi tetapi masih tidak setuju dengan rekomendasi yang lebih disukai attr().

Jawaban asli

Jika Anda hanya pernah menggunakan jQuery dan bukan DOM secara langsung, ini bisa menjadi perubahan yang membingungkan, meskipun ini jelas merupakan perbaikan secara konseptual. Tidak begitu baik untuk bazillions situs yang menggunakan jQuery yang akan rusak karena perubahan ini.

Saya akan merangkum masalah utama:

  • Anda biasanya menginginkan prop()daripada attr().
  • Dalam sebagian besar kasus, prop()lakukan apa yang attr()biasa dilakukan. Mengganti panggilan dengan attr()dengan prop()dalam kode Anda umumnya akan berfungsi.
  • Properti umumnya lebih mudah ditangani daripada atribut. Nilai atribut hanya dapat berupa string sedangkan properti dapat dari jenis apa pun. Misalnya, checkedproperti adalah Boolean, styleproperti adalah objek dengan properti individual untuk setiap gaya, sizeproperti adalah angka.
  • Di mana kedua properti dan atribut dengan nama yang sama ada, biasanya memperbarui satu akan memperbarui yang lain, tetapi ini bukan kasus untuk atribut input tertentu, seperti valuedan checked: untuk atribut ini, properti selalu mewakili keadaan saat ini sementara atribut (kecuali dalam versi IE lama) sesuai dengan nilai default / kesesuaian input (tercermin dalam defaultValue/ defaultCheckedproperti).
  • Perubahan ini menghilangkan beberapa lapisan jQuery ajaib yang terjebak di depan atribut dan properti, artinya pengembang jQuery harus belajar sedikit tentang perbedaan antara properti dan atribut. Ini hal yang baik.

Jika Anda seorang pengembang jQuery dan bingung dengan seluruh bisnis ini tentang properti dan atribut, Anda perlu mengambil langkah mundur dan belajar sedikit tentang itu, karena jQuery tidak lagi berusaha begitu keras untuk melindungi Anda dari hal-hal ini. Untuk kata otoritatif tapi agak kering pada subjek, ada spesifikasi: DOM4 , HTML DOM , DOM Level 2 , DOM Level 3 . Dokumentasi DOM Mozilla ini valid untuk sebagian besar browser modern dan lebih mudah dibaca daripada spesifikasi, sehingga Anda dapat menemukan referensi DOM mereka bermanfaat. Ada bagian tentang properti elemen .

Sebagai contoh bagaimana properti lebih mudah ditangani daripada atribut, pertimbangkan kotak centang yang awalnya diperiksa. Berikut adalah dua kemungkinan HTML yang valid untuk melakukan ini:

<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">

Jadi, bagaimana Anda mengetahui jika kotak centang dicentang dengan jQuery? Lihatlah Stack Overflow dan Anda biasanya akan menemukan saran berikut:

  • if ( $("#cb").attr("checked") === true ) {...}
  • if ( $("#cb").attr("checked") == "checked" ) {...}
  • if ( $("#cb").is(":checked") ) {...}

Ini sebenarnya adalah hal paling sederhana di dunia untuk dilakukan dengan checkedproperti Boolean, yang telah ada dan bekerja dengan sempurna di setiap browser skrip utama sejak 1995:

if (document.getElementById("cb").checked) {...}

Properti juga membuat memeriksa atau menghapus centang pada kotak centang sepele:

document.getElementById("cb").checked = false

Di jQuery 1.6, ini menjadi jelas

$("#cb").prop("checked", false)

Gagasan untuk menggunakan checkedatribut untuk skrip kotak centang tidak membantu dan tidak perlu. Properti adalah yang Anda butuhkan.

  • Tidak jelas apa cara yang benar untuk mencentang atau menghapus centang pada kotak centang menggunakan checkedatribut
  • Nilai atribut mencerminkan standar daripada keadaan yang terlihat saat ini (kecuali dalam beberapa versi IE yang lebih lama, sehingga membuat segalanya lebih sulit). Atribut tidak memberi tahu Anda tentang apakah kotak centang pada halaman dicentang. Lihat http://jsfiddle.net/VktA6/49/ .
Tim Down
sumber
2
@ TJCrowder, lalu yang mana?
Naftali alias Neal
9
@Neal: Jika Anda ingin tahu properti apa yang dimiliki elemen DOM dan bagaimana atribut dapat menyemai nilainya, simpan tautan berikut: Spesifikasi DOM2 HTML , spesifikasi DOM2 , dan spesifikasi DOM3 . Indeks dalam setiap kasus sangat baik dan menghubungkan Anda langsung ke deskripsi menyeluruh dari properti, dari mana nilainya berasal, dll.
TJ Crowder
4
@Neal: Apa yang membuatnya berbeda: Sumber dan sifat informasi. Lihatlah valuecontoh Tim , misalnya. Fungsi yang dipanggil attryang mengambil properti value daripada atribut "nilai" tidak masuk akal (dan mereka bisa berbeda). Ke depan, attrmelakukan atribut dan propmelakukan properti akan lebih jelas, meskipun transisi akan menyakitkan bagi sebagian orang. Jangan salah paham, tidak ada yang seperti melangkah mundur dan membaca spesifikasi untuk mendapatkan gambaran tentang apa itu properti.
TJ Crowder
54
@Neal: Elemen DOM adalah objek. Properti adalah properti dari objek itu, sama seperti objek pemrograman lainnya. Beberapa alat peraga tersebut mendapatkan nilai awal dari atribut di markup, yang juga disimpan pada objek DOM dalam peta atribut yang terpisah . Dalam kebanyakan kasus, menulis ke prop hanya mengubah prop, meskipun sayangnya ada beberapa props yang menulis perubahan melalui attr yang mendasarinya ( valuemisalnya), tetapi mari kita coba untuk mengabaikannya. 99% dari waktu, Anda ingin bekerja dengan alat peraga. Jika Anda perlu bekerja dengan atribut yang sebenarnya, Anda mungkin akan tahu itu.
TJ Crowder
4
@Tim: "Mengubah valueproperti input tidak mengubah valueatributnya di peramban modern" Saya tidak berpikir itu terjadi, itulah sebabnya saya mulai menggunakannya sebagai contoh, tetapi ketika saya mulai mengkodekan contoh, terkutuk jika tidak diperbarui di Chrome, Firefox, Opera, IE ... - jsbin.com/ahire4 Ternyata itu karena saya menggunakan input[type="button"]untuk percobaan saya. Itu tidak memperbarui atribut pada input[type="text"]- jsbin.com/ahire4/2 Bicara tentang berbelit-belit !! Bukan hanya unsurnya, tetapi jenisnya ...
TJ Crowder
664

Saya pikir Tim mengatakannya dengan cukup baik , tapi mari kita mundur:

Elemen DOM adalah objek, benda di memori. Seperti kebanyakan objek di OOP, ia memiliki properti . Ini juga, secara terpisah, memiliki peta atribut yang ditentukan pada elemen (biasanya berasal dari markup yang dibaca browser untuk membuat elemen). Beberapa properti elemen mendapatkan nilai awal mereka dari atribut dengan nama yang sama atau mirip ( valuemendapatkan nilai awal dari atribut "nilai"; hrefmendapatkan nilai awal dari atribut "href", tetapi itu bukan nilai yang sama persis; classNamedari atribut "class"). Properti lain mendapatkan nilai awalnya dengan cara lain: Misalnya, parentNodeproperti mendapatkan nilainya berdasarkan elemen induknya;style properti, apakah itu memiliki atribut "style" atau tidak.

Mari kita pertimbangkan jangkar ini di halaman di http://example.com/testing.html:

<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>

Beberapa seni ASCII gratis (dan meninggalkan banyak hal):

+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +
| HTMLAnchorElement |
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +
| href: "http://example.com/foo.html" |
| nama: "fooAnchor" |
| id: "fooAnchor" |
| className: "test one" |
| atribut: |
| href: "foo.html" |
| nama: "fooAnchor" |
| id: "fooAnchor" |
| class: "test one" |
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +

Perhatikan bahwa sifat dan atributnya berbeda.

Sekarang, meskipun mereka berbeda, karena semua ini berkembang alih-alih dirancang dari bawah ke atas, sejumlah properti menulis kembali ke atribut yang mereka berasal dari jika Anda mengaturnya. Tetapi tidak semua melakukannya, dan seperti yang Anda lihat dari hrefatas, pemetaan tidak selalu berupa "meneruskan nilai", terkadang ada interpretasi yang terlibat.

Ketika saya berbicara tentang properti yang merupakan properti dari suatu objek, saya tidak berbicara secara abstrak. Ini beberapa kode non-jQuery:

var link = document.getElementById('fooAnchor');
alert(link.href);                 // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"

(Nilai-nilai itu sesuai dengan kebanyakan browser; ada beberapa variasi.)

The linkobjek adalah hal yang nyata, dan Anda dapat melihat ada perbedaan nyata antara mengakses properti di atasnya, dan mengakses sebuah atribut .

Seperti yang dikatakan Tim, sebagian besar waktu, kami ingin bekerja dengan properti. Sebagian karena nilai-nilai mereka (bahkan nama mereka) cenderung lebih konsisten di seluruh browser. Kami sebagian besar hanya ingin bekerja dengan atribut ketika tidak ada properti yang terkait dengannya (atribut khusus), atau ketika kami tahu bahwa untuk atribut tertentu, atribut dan properti bukan 1: 1 (seperti dengan hrefdan "href" di atas) .

Properti standar disajikan dalam berbagai spesifikasi DOM:

Spesifikasi ini memiliki indeks yang sangat baik dan saya sarankan menyimpan tautan ke dalamnya; Saya menggunakannya sepanjang waktu.

Atribut khusus akan mencakup, misalnya, data-xyzatribut apa pun yang mungkin Anda masukkan ke elemen untuk memberikan meta-data ke kode Anda (sekarang itu berlaku pada HTML5, selama Anda tetap menggunakan data-awalan). (Versi terbaru jQuery memberi Anda akses ke data-xyzelemen melalui datafungsi, tetapi fungsi itu bukan hanya pengakses untuk data-xyzatribut [ia melakukan keduanya lebih banyak dan lebih sedikit dari itu]; kecuali jika Anda benar-benar membutuhkan fitur-fiturnya, saya akan menggunakan attrfungsi untuk berinteraksi dengan data-xyzatribut.)

The attrfungsi yang digunakan untuk memiliki beberapa berbelit-belit logika sekitar mendapatkan apa yang mereka pikir Anda inginkan, bukan secara harfiah mendapatkan atribut. Itu menyatukan konsep. Pindah ke propdan attrdimaksudkan untuk menghapus konfigurasi mereka. Sebentar di v1.6.0 jQuery pergi terlalu jauh dalam hal itu, tapi fungsi dengan cepat ditambahkan kembali ke attruntuk menangani situasi umum di mana orang menggunakan attrketika teknis mereka harus menggunakan prop.

TJ Crowder
sumber
Wow. pembaruan 1.6.1 yang baru benar-benar membatalkan pertanyaan ini sedikit .. (tetapi tidak banyak) tetapi tautan itu pada dasarnya menjawabnya sekarang
Naftali alias Neal
Itu tidak membatalkannya untuk saya, saya baru saja memperbaiki bug menggunakan jquery1.7 di mana saya mengatur .attr ('class', 'bla') dan tidak berfungsi di mana .prop ('className', 'bla' ) bekerja
PandaWood
@ PandaWood: .attr('class', 'bla')berfungsi seperti yang diharapkan untuk saya di 1.7.0 , 1.7.1 , dan 1.7.2 di Chrome 17, Firefox 11, Opera 11, IE6, IE8, IE9, dan Safari 5.
TJ Crowder
Terima kasih, pasti ada sesuatu yang spesifik dalam kasus saya, biarkan saya periksa ini & kembali dengan test case. Tetapi mengubah kode seperti yang kita miliki sekarang, untuk sekadar "menopang / className", alih-alih "attr" memperbaiki bug besar-besaran untuk kami yang menerpa ketika kami pindah dari jquery1.4 ke 1.7 - di semua browser
PandaWood
3
@TJCrowder re: .data- ia akan membaca nilai default atribut, jika ada, tetapi jika Anda menulisnya, itu akan mengubah properti tersembunyi dari elemen, dan tidak memperbarui atribut.
Alnitak
250

Perubahan ini sudah lama terjadi untuk jQuery. Selama bertahun-tahun, mereka sudah puas dengan fungsi bernama attr()yang sebagian besar mengambil properti DOM, bukan hasil yang Anda harapkan dari nama. Pemisahan attr()dan prop()harus membantu mengurangi beberapa kebingungan antara atribut HTML dan properti DOM. $.fn.prop()meraih properti DOM yang ditentukan, sementara $.fn.attr()mengambil atribut HTML yang ditentukan.

Untuk sepenuhnya memahami cara kerjanya, berikut penjelasan panjang lebar tentang perbedaan antara atribut HTML dan properti DOM .:

Atribut HTML

Sintaksis:

<body onload="foo()">

Tujuan: Mengizinkan markup memiliki data yang terkait dengannya untuk acara, rendering, dan tujuan lain.

Visualisasi: Atribut HTML Atribut kelas ditunjukkan di sini di badan. Ini dapat diakses melalui kode berikut:

var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");

Atribut dikembalikan dalam bentuk string dan dapat tidak konsisten dari browser ke browser. Namun, mereka dapat menjadi vital dalam beberapa situasi. Seperti dicontohkan di atas, IE 8 Quirks Mode (dan di bawah) mengharapkan nama properti DOM di get / set / removeAttribute alih-alih nama atribut. Ini adalah salah satu dari banyak alasan mengapa penting untuk mengetahui perbedaannya.

Properti DOM

Sintaksis:

document.body.onload = foo;

Tujuan: Memberikan akses ke properti yang dimiliki oleh elemen node. Properti ini mirip dengan atribut, tetapi hanya dapat diakses melalui JavaScript. Ini adalah perbedaan penting yang membantu memperjelas peran properti DOM. Harap perhatikan bahwa atribut sama sekali berbeda dari properti , karena penugasan event handler ini tidak berguna dan tidak akan menerima acara (badan tidak memiliki acara yang memuat, hanya atribut yang memuat).

Visualisasi: Properti DOM

Di sini, Anda akan melihat daftar properti di bawah tab "DOM" di Firebug. Ini adalah properti DOM. Anda akan segera melihat beberapa dari mereka, karena Anda akan menggunakannya sebelumnya tanpa menyadarinya. Nilai-nilainya adalah apa yang akan Anda terima melalui JavaScript.

Dokumentasi

Contoh

HTML: <textarea id="test" value="foo"></textarea>

JavaScript: alert($('#test').attr('value'));

Di versi jQuery sebelumnya, ini mengembalikan string kosong. Di 1.6, ini mengembalikan nilai yang tepat foo,.

Tanpa melirik kode baru untuk salah satu fungsi, saya dapat mengatakan dengan yakin bahwa kebingungan lebih berkaitan dengan perbedaan antara atribut HTML dan properti DOM, daripada dengan kode itu sendiri. Mudah-mudahan, ini membereskan beberapa hal untuk Anda.

-Matt

K.
sumber
7
$.prop()mendapat properti DOM, $.attr()mendapat atribut HTML. Saya mencoba menjembatani kesenjangan secara psikologis sehingga Anda dapat memahami perbedaan antara keduanya.
10
Wah, aku juga bingung sekarang. Jadi $('#test').prop('value')tidak mengembalikan apa pun? Juga tidak .attr('checked')untuk kotak centang? Tapi dulu? Sekarang Anda harus mengubahnya prop('checked')? Saya tidak mengerti perlunya perbedaan ini - mengapa penting untuk membedakan antara atribut HTML dan properti DOM? Apa kasus penggunaan umum yang membuat perubahan ini "lama datang" ? Apa yang salah dengan mengabstraksikan perbedaan antara keduanya, karena sepertinya kasus penggunaan mereka sebagian besar tumpang tindih?
BlueRaja - Danny Pflughoeft
5
@ BlueRaja: karena ada perbedaan mendasar yang serius antara dua konsep yang, jika Anda menyikatnya di bawah karpet seperti jQuery dulu, menghasilkan kegagalan yang tak terduga. valueadalah salah satu kasus yang paling jelas, karena valueproperti akan memberi Anda nilai saat ini dari suatu bidang, tetapi valueatribut akan memberi Anda nilai asli yang dideklarasikan dalam value="..."atribut, yang sebenarnya adalah defaultValueproperti. (Meskipun kasus khusus ini menjadi bingung lagi oleh bug di IE <9.)
bobince
4
@BlueRaja: Jawabannya bahkan lebih rumit. :-) Pengaturan attr('value', ...)di jQuery <1.6 menyetel properti, sehingga nilai saat ini berubah dan nilai default tidak. Dalam 1.6 itu menetapkan atribut, jadi dalam teori nilai default berubah dan nilai saat ini tidak. Namun, ada (lebih banyak) ketidakkonsistenan peramban tentang apa sebenarnya pengaturan valueatribut. Di IE ia menetapkan nilai saat ini juga; di beberapa browser hanya menetapkan nilai saat ini jika nilai saat ini belum ditetapkan sebelumnya. [menangis]
bobince
1
Sama seperti @Quentin berkata, "Atribut didefinisikan oleh HTML. Properti ditentukan oleh DOM." Versi paling sederhana yang pernah saya baca.
Alan Dong
241

Properti berada di DOM; atribut dalam HTML yang diuraikan ke dalam DOM.

Detail lebih lanjut

Jika Anda mengubah atribut, perubahan akan tercermin dalam DOM (kadang-kadang dengan nama yang berbeda).

Contoh: Mengubah classatribut tag akan mengubah classNameproperti tag itu di DOM. Jika Anda tidak memiliki atribut pada tag, Anda masih memiliki properti DOM yang sesuai dengan nilai kosong atau default.

Contoh: Sementara tag Anda tidak memiliki class atribut, properti DOM classNamememang ada dengan nilai string kosong.

sunting

Jika Anda mengubah yang satu, yang lain akan diubah oleh controller, dan sebaliknya. Pengontrol ini bukan di jQuery, tetapi di kode asli browser.

Yunzen
sumber
Jadi apakah ini berarti lebih baik memperbarui atribut karena Anda memastikan bahwa atribut dan properti diperbarui dan selaras?
Lukas
1
@ Lukas DOM adalah representasi teknis bagian dalam, model. Atribut HTML adalah representasi luar, sebuah tampilan. Jika Anda mengubah yang satu, yang lain akan diubah oleh controller, dan sebaliknya.
yunzen
@ HerrSerker Jadi mereka berdua tetap sinkron melalui pengontrol? Saya menganggap ini hanya dalam attr dan prop metode jQuery? Berikut ini adalah modifikasi biola Anda di mana saya menjelajahi lebih banyak ini - jsfiddle.net/v8wRy - dan sejauh ini mereka sepertinya setara.
Luke
3
"Jika Anda mengubah yang satu, yang lain akan diubah oleh controller, dan sebaliknya. Kontroler ini bukan di jQuery, tetapi di kode asli browser." Ini tidak benar untuk sebagian besar atribut / properti. Bagi mayoritas itu hanya terjemahan satu arah di mana atribut menentukan nilai awal dari properti yang sesuai. Dua jawaban teratas menjelaskan ini secara rinci.
ᴠɪɴᴄᴇɴᴛ
@Incent. Saya tidak melihat, di mana dua jawaban teratas mengatakan sesuatu yang bertentangan dengan jawaban saya. Tentu saja sebagian besar atribut adalah nilai awal dari properti DOM yang sesuai. Tetapi mereka saling tergantung. Cobalah sesuatu seperti jQuery('p').prop('className', 'foo');di konsol Chrome dan Anda akan melihat, bagaimana setiap paragraf mendapatkan classatribut dari 'foo'. Tentu saja tidak dalam kode sumber, yang berasal dari server. Itu konstan.
yunzen
140

Hanya saja perbedaan antara atribut HTML dan objek DOM yang menyebabkan kebingungan. Bagi mereka yang nyaman bertindak pada elemen asli DOM elemen seperti this.src this.value this.checkeddll,.prop adalah sambutan yang sangat hangat untuk keluarga. Bagi yang lain, itu hanya lapisan kebingungan tambahan. Mari kita perjelas.

Cara termudah untuk melihat perbedaan antara .attrdan .propadalah contoh berikut:

<input blah="hello">
  1. $('input').attr('blah'): mengembalikan 'hello'seperti yang diharapkan. Tidak ada kejutan di sini.
  2. $('input').prop('blah'): mengembalikan undefined- karena itu coba lakukan [HTMLInputElement].blah- dan tidak ada properti seperti itu pada objek DOM ada. Itu hanya ada dalam ruang lingkup sebagai atribut elemen yaitu[HTMLInputElement].getAttribute('blah')

Sekarang kita mengubah beberapa hal seperti:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): mengembalikan 'apple'eh? Mengapa tidak "pir" karena ini ditetapkan terakhir pada elemen itu. Karena properti diubah pada atribut input, bukan elemen input DOM itu sendiri - mereka pada dasarnya hampir bekerja secara independen satu sama lain.
  2. $('input').prop('blah'): pengembalian 'pear'

Hal yang Anda benar-benar harus berhati-hati adalah jangan campur penggunaan ini untuk properti yang sama di seluruh aplikasi Anda karena alasan di atas.

Lihat biola mendemonstrasikan perbedaan: http://jsfiddle.net/garreh/uLQXc/


.attrvs .prop:

Babak 1: gaya

<input style="font:arial;"/>
  • .attr('style') - Mengembalikan gaya sebaris untuk elemen yang cocok yaitu "font:arial;"
  • .prop('style') - Mengembalikan objek pernyataan gaya yaitu CSSStyleDeclaration

Babak 2: nilai

<input value="hello" type="text"/>   

$('input').prop('value', 'i changed the value');
  • .attr('value')- pengembalian 'hello'*
  • .prop('value') - pengembalian 'i changed the value'

* Catatan: jQuery karena alasan ini memiliki .val()metode, yang secara internal setara dengan.prop('value')

Gary Green
sumber
@Neal Karena itu memberikan referensi ke struktur fungsi jquery yang lebih baik. "$ ('input'). prop ('blah'): mengembalikan tidak terdefinisi - karena ia berusaha melakukan [HTMLInputElement] .blah - dan tidak ada properti seperti itu pada objek DOM yang ada. Ia hanya ada dalam lingkup sebagai atribut dari elemen itu yaitu [HTMLInputElement] .getAttribute ('blah') "
Uğur Gümüşhan
2
Tampak berbeda dari doc, api.jquery.com/prop : "Metode .prop () harus digunakan untuk mengatur dinonaktifkan dan diperiksa daripada metode .attr (). Metode .val () harus digunakan untuk mendapatkan dan nilai pengaturan. "
angsa
53

TL; DR

Gunakan prop()lebih attr()dalam sebagian besar kasus.

Sebuah properti adalah keadaan saat elemen input. Sebuah atribut adalah nilai default.

Properti dapat berisi hal-hal dari tipe yang berbeda. Atribut hanya dapat berisi string

agjmills
sumber
1
jika memungkinkan untuk datang dengan beberapa contoh mudah dari apa yang Anda katakan dan juga menunjukkan kapan harus digunakan prop() and when to go for attr(). menunggu jawaban :)
Mou
36

Keterbukaan kotor

Konsep ini memberikan contoh di mana perbedaan dapat diamati: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty

Cobalah:

  • klik tombolnya. Kedua kotak centang diperiksa.
  • hapus centang pada kedua kotak centang.
  • klik tombol lagi. Hanya propkotak centang yang dicentang. BANG!

$('button').on('click', function() {
  $('#attr').attr('checked', 'checked')
  $('#prop').prop('checked', true)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>attr <input id="attr" type="checkbox"></label>
<label>prop <input id="prop" type="checkbox"></label>
<button type="button">Set checked attr and prop.</button>

Untuk beberapa atribut seperti disabledpada button, menambahkan atau menghapus atribut konten disabled="disabled"selalu mengubah properti (disebut atribut IDL di HTML5) karena http://www.w3.org/TR/html5/forms.html#attr-fe-disabled mengatakan:

Atribut IDL yang dinonaktifkan harus mencerminkan atribut konten yang dinonaktifkan.

jadi Anda mungkin lolos begitu saja, meskipun jelek karena memodifikasi HTML tanpa perlu.

Untuk atribut lain seperti checked="checked"pada input type="checkbox", hal-hal rusak, karena begitu Anda mengkliknya, itu menjadi kotor, dan kemudian menambahkan atau menghapus checked="checked"atribut konten tidak beralih keseksian lagi .

Inilah sebabnya mengapa Anda harus menggunakan sebagian besar .prop, karena hal itu mempengaruhi properti efektif secara langsung, daripada mengandalkan efek samping kompleks dari memodifikasi HTML.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
Untuk kelengkapan juga coba variasi ini: 1) Sebelum mengklik tombol centang dan kemudian hapus centang pada kotak centang pertama 2) (Untuk yang ini Anda perlu mengubah cuplikan) Berikan masukan pertama checkedatribut:checked="checked"
ᴠɪɴᴄᴇɴᴛ
33

Semua ada dalam dokumen :

Perbedaan antara atribut dan properti dapat menjadi penting dalam situasi tertentu. Sebelum jQuery 1.6, metode .attr () kadang-kadang memperhitungkan nilai properti ketika mengambil beberapa atribut, yang bisa menyebabkan perilaku tidak konsisten. Pada jQuery 1.6, metode .prop () menyediakan cara untuk secara eksplisit mengambil nilai properti, sementara .attr () mengambil atribut.

Jadi, gunakan prop!

Arnaud F.
sumber
2
Jadi itu berarti ketika saya beralih ke 1.6, banyak hal akan pecah ??
Naftali alias Neal
Tidak, itu hanya perilaku yang tidak konsisten, jika berhasil sebelumnya, ia akan selalu bekerja dengan jQuery 1.6, hanya saja prop lebih aman;)
Arnaud F.
6
Saya ingat. $.attr()mengambil properti sebagian besar waktu saya bekerja dengannya, bukan "kadang-kadang". Kebingungan yang disebabkan olehnya masih bergema sampai sekarang. Sayangnya, saya mengalami banyak kesulitan menemukan bacaan pasti pada atribut HTML vs properti DOM, jadi saya mungkin menulis jawaban di sini sedikit.
3
@ Arnaud-f Tidak benar. Semua kode sebelum 1.6 yang menggunakan attr ('dicentang') untuk memeriksa kotak centang sekarang akan rusak.
CaptSaltyJack
3
@Matt McDonald: Apa jenis "... kesulitan menemukan pembacaan definitif pada atribut HTML vs properti DOM ..." yang Anda maksud? Properti (tercermin dan sebaliknya) dijelaskan dalam spesifikasi DOM2 HTML ; Anda mungkin juga perlu mengacu pada DOM2 dan DOM3 spesifikasi.
TJ Crowder
28

atribut ada dalam dokumen / file teks HTML Anda (== bayangkan ini adalah hasil dari markup html Anda diurai), sedangkan
properti berada di pohon HTML DOM (== pada dasarnya merupakan properti aktual dari beberapa objek dalam arti JS).

Yang penting, banyak dari mereka yang disinkronkan (jika Anda memperbarui classproperti, classatribut dalam html juga akan diperbarui; dan jika tidak). Tetapi beberapa atribut mungkin disinkronkan ke properti yang tidak terduga - misalnya, atribut checked sesuai dengan properti defaultChecked , sehingga

  • memeriksa kotak centang secara manual akan mengubah .prop('checked')nilai, tetapi tidak akan berubah .attr('checked')dan .prop('defaultChecked')nilai
  • pengaturan $('#input').prop('defaultChecked', true)juga akan berubah .attr('checked'), tetapi ini tidak akan terlihat pada elemen.

Aturan praktisnya adalah : .prop()metode harus digunakan untuk atribut / properti boolean dan untuk properti yang tidak ada dalam html (seperti window.location). Semua atribut lainnya (yang dapat Anda lihat di html) dapat dan harus terus dimanipulasi dengan .attr() metode ini. ( http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/ )

Dan ini adalah tabel yang menunjukkan di mana .prop()lebih disukai (meskipun .attr()masih dapat digunakan).

tabel dengan penggunaan pilihan


Mengapa Anda terkadang ingin menggunakan .prop () alih-alih .attr () di mana yang terakhir disarankan secara resmi?

  1. .prop()dapat mengembalikan semua tipe - string, integer, boolean; sementara .attr()selalu mengembalikan string.
  2. .prop()dikatakan sekitar 2,5 kali lebih cepat dari .attr().
danau
sumber
sesuatu telah berubah, seperti ini: $('#myImageId').prop('src', 'http://example.com/img.png'), var class = $('.myDivClass').prop('class'), atau $('#myTextBox').prop('type', 'button'). Dan seterusnya ...
@ Mr. Wolf, maaf, saya masih belum mengerti maksud Anda. apa yang telah 'berubah'? sintaks selalu seperti itu.
lakesare
Saya pikir tabel dalam jawaban Anda tidak perlu. Karena .prop()berfungsi baik dengan semua properti. Anda tidak ingin menandai semua properti di .prop()kolom, bukan?
@ Mr.Wolf, saya pikir itu perlu, karena, seperti yang sudah disebutkan, itu 'menunjukkan di mana .prop()lebih disukai (meskipun .attr()masih dapat digunakan)'
lakesare
Saya biasanya menggunakan .attr()untuk mendefinisikan suatu peristiwa apa yang .prop()tidak bisa. Seperti ini: $('.myDiv').attr('onclick', 'alert("Hello world!")'). Jika Anda mengubah .attr()ke .prop(), tidak akan bekerja. Benar-benar, saya pikir tidak ada alasan untuk digunakan .attr()untuk mengatur atau mendapatkan nilai id/class/href/checked/src...... Perhatikan bahwa saya tidak mengatakan Anda salah.
20

.attr():

  • Dapatkan nilai atribut untuk elemen pertama di set elemen yang cocok.
  • Memberi Anda nilai elemen seperti yang didefinisikan dalam html saat memuat halaman

.prop():

  • Dapatkan nilai properti untuk elemen pertama di set elemen yang cocok.
  • Memberikan nilai yang diperbarui dari elemen yang dimodifikasi melalui javascript / jquery
Kgn-web
sumber
13

Biasanya Anda ingin menggunakan properti. Gunakan atribut hanya untuk:

  1. Mendapatkan atribut HTML khusus (karena tidak disinkronkan dengan properti DOM).
  2. Mendapatkan atribut HTML yang tidak disinkronkan dengan properti DOM, mis. Dapatkan "nilai asli" dari atribut HTML standar, misalnya <input value="abc">.
naor
sumber
7

attributes -> HTML

properties -> DOM

NkS
sumber
8
Saya tahu apa yang ingin Anda katakan, tetapi HTML adalah bahasa markup, dan representasi DOM dibuat dari HTML. DOMElement memiliki atribut dan properti .
t.niese
@ t.niese, attirbutesjuga salah satu propertiDOM
NkS
Jawaban singkatnya sederhana.
Nabi KAZ
6

Sebelum jQuery 1.6, attr()metode terkadang - mengambil nilai properti ke dalam akun ketika mengambil atribut, ini menyebabkan perilaku yang agak tidak konsisten.

Pengenalan prop()metode ini menyediakan cara untuk secara eksplisit mengambil nilai properti, sambil .attr()mengambil atribut.

The Documents:

jQuery.attr() Dapatkan nilai atribut untuk elemen pertama di set elemen yang cocok.

jQuery.prop() Dapatkan nilai properti untuk elemen pertama di set elemen yang cocok.

Gothburz
sumber
3

Pengingat lembut tentang penggunaan prop(), contoh:

if ($("#checkbox1").prop('checked')) {
    isDelete = 1;
} else {
    isDelete = 0;
}

Fungsi di atas digunakan untuk memeriksa apakah checkbox1 dicentang atau tidak, jika dicentang: return 1; jika tidak: return 0. Function prop () digunakan di sini sebagai fungsi GET.

if ($("#checkbox1").prop('checked', true)) {
    isDelete = 1;
} else {
    isDelete = 0;
}

Fungsi di atas digunakan untuk mengatur checkbox1 untuk diperiksa dan SELALU kembali 1. Sekarang fungsi prop () digunakan sebagai fungsi SET.

Jangan mengacau.

P / S: Ketika saya memeriksa properti Image src . Jika src kosong, sangga kembalikan URL halaman saat ini (salah), dan attr kembalikan string kosong (kanan).

pengguna2657778
sumber
Anda salah dalam contoh ini: <img src="smiley.gif" alt="Smiley face" width="42" height="42" onclick="alert($(this).prop('src'))">. Seharusnya berfungsi dan mengembalikan lokasi gambar.
2

Satu hal yang .attr()dapat dilakukan adalah .prop(): mempengaruhi pemilih CSS

Ini masalah yang tidak saya lihat di jawaban yang lain.

Pemilih CSS [name=value]

  • akan merespons .attr('name', 'value')
  • tapi tidak selalu demikian .prop('name', 'value')

.prop() hanya memengaruhi beberapa penyeleksi atribut

.attr() mempengaruhi semua pemilih-atribut

Bob Stein
sumber
0

1) Properti berada di DOM; atribut dalam HTML yang diuraikan ke dalam DOM.

2) $ (elem) .attr ("dicentang") (1.6.1+) "dicentang" (String) Akan berubah dengan keadaan kotak centang

3) $ (elem) .attr ("dicentang") (pra-1.6) true (Boolean) Diubah dengan keadaan kotak centang

  • Sebagian besar kita ingin menggunakan untuk objek DOM daripada atribut kustom suka data-img, data-xyz.

  • Juga ada beberapa perbedaan ketika mengakses checkboxnilai dan href dengan attr()dan prop()sebagai hal berubah dengan output DOM dengan prop()tautan penuh dari origindan Booleannilai untuk kotak centang (pre-1.6)

  • Kami hanya dapat mengakses elemen DOM dengan yang proplain dari yang diberikannyaundefined

Bagian Trivedi
sumber
0

Ada beberapa pertimbangan lain dalam prop () vs attr ():

  • selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, dan defaultSelected..etc harus diambil dan diatur dengan metode .prop (). Ini tidak memiliki atribut yang sesuai dan hanya properti.

  • Untuk kotak centang ketik input

       .attr('checked') //returns  checked
       .prop('checked') //returns  true
       .is(':checked') //returns true
  • metode prop mengembalikan nilai Boolean untuk diperiksa, dipilih, dinonaktifkan, readOnly..etc sementara attr mengembalikan string yang ditentukan. Jadi, Anda bisa langsung menggunakan .prop ('dicentang') dalam kondisi if.

  • .attr () memanggil .prop () secara internal sehingga metode .attr () akan sedikit lebih lambat daripada mengaksesnya secara langsung melalui .prop ().

Rishu Ranjan
sumber
-2

Jawaban Gary Hole sangat relevan untuk menyelesaikan masalah jika kode ditulis sedemikian rupa

obj.prop("style","border:1px red solid;")

Karena fungsi prop mengembalikan CSSStyleDeclarationobjek, kode di atas tidak akan berfungsi dengan baik di beberapa browser (diuji denganIE8 with Chrome Frame Plugin dalam kasus saya).

Jadi mengubahnya menjadi kode berikut

obj.prop("style").cssText = "border:1px red solid;"

memecahkan masalah.

zawhtut
sumber