javascript - disabled - property vs attribute
.prop()vs.attr() (12)
所以jQuery 1.6有新的函數prop()
。
$(selector).click(function(){
//instead of:
this.getAttribute('style');
//do i use:
$(this).prop('style');
//or:
$(this).attr('style');
})
或者在這種情況下,他們做同樣的事情?
如果我必須切換到使用prop()
,如果我切換到1.6,所有舊的attr()
調用都將中斷?
UPDATE
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>
(另見這個小提琴: http://jsfiddle.net/maniator/JpUF2/ : http://jsfiddle.net/maniator/JpUF2/ )
控制台將getAttribute
記錄為字符串,將attr
為字符串,但將prop
為CSSStyleDeclaration
,為什麼? 這對我未來的編碼有何影響?
1)屬性在DOM中; HTML中的屬性被解析為DOM。
2)$(elem).attr(“checked”)(1.6.1+)“checked”(字符串)將隨複選框狀態而變化
3)$(elem).attr(“checked”)(pre-1.6)true(布爾值)更改為複選框狀態
我們通常希望使用DOM對象而不是自定義屬性
data-img, data-xyz
。在訪問
checkbox
值時也有一些區別href
,attr()
並且prop()
隨著DOM輸出的變化,prop()
以及完整鏈接origin
和Boolean
復選框的值(pre-1.6)
我們只能使用
prop
其他方式訪問DOM元素undefined
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>prop demo</title>
<style>
p {
margin: 20px 0 0;
}
b {
color: blue;
}
</style>
</head>
<body>
<input id="check1" type="checkbox" checked="checked">
<label for="check1">Check me</label>
<p></p>
<script>
$("input").change(function() {
var $input = $(this);
$("p").html(
".attr( \"checked\" ): <b>" + $input.attr("checked") + "</b><br>" +
".prop( \"checked\" ): <b>" + $input.prop("checked") + "</b><br>" +
".is( \":checked\" ): <b>" + $input.is(":checked")) + "</b>";
}).change();
</script>
</body>
</html>
jQuery已經有很長一段時間了。 多年來,他們一直滿足於一個名為attr()
的函數,該函數主要檢索DOM屬性,而不是您期望從名稱中獲得的結果。 attr()
和prop()
的隔離應該有助於緩解HTML屬性和DOM屬性之間的一些混淆。 $.fn.prop()
獲取指定的DOM屬性,而$.fn.attr()
獲取指定的HTML屬性。
為了完全理解它們是如何工作的,這裡是對HTML屬性和DOM屬性之間差異的擴展解釋:
HTML屬性
句法:
<body onload="foo()">
目的:允許標記為事件,呈現和其他目的提供與之關聯的數據。
可視化: class屬性顯示在正文中。 它可以通過以下代碼訪問:
var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");
屬性以字符串形式返回,並且從瀏覽器到瀏覽器可能不一致。 但是,它們在某些情況下至關重要。 如上所示,IE 8 Quirks Mode(及以下)需要get / set / removeAttribute中DOM屬性的名稱而不是屬性名稱。 這是了解差異的重要原因之一。
DOM屬性
句法:
document.body.onload = foo;
目的:提供對屬於元素節點的屬性的訪問。 這些屬性與屬性類似,但只能通過JavaScript訪問。 這是一個重要的區別,有助於闡明DOM屬性的作用。 請注意,屬性與屬性完全不同 ,因為此事件處理程序分配是無用的,並且不會接收事件(正文沒有onload事件,只有onload屬性)。
可視化:
在這裡,您將注意到Firebug中“DOM”選項卡下的屬性列表。 這些是DOM屬性。 你會立即註意到它們中的一些,因為你以前在不知情的情況下使用過它們。 他們的價值觀是你通過JavaScript獲得的。
文檔
例
HTML: <textarea id="test" value="foo"></textarea>
JavaScript: alert($('#test').attr('value'));
在早期版本的jQuery中,這將返回一個空字符串。 在1.6中,它返回正確的值foo
。
在沒有瀏覽任何一個函數的新代碼的情況下,我可以充滿信心地說,混淆更多地與HTML屬性和DOM屬性之間的差異有關,而不是與代碼本身有關。 希望這能為你解決一些問題。
-Matt
attributes
- > HTML
properties
- > DOM
2012年11月1日更新
我的原始答案特別適用於jQuery 1.6。 我的建議仍然相同,但jQuery 1.6.1略有改變:面對預測的一堆破碎的網站,jQuery團隊將attr()
恢復為接近(但不完全相同)布爾屬性的舊行為 。 John Resig也在博客上寫了這篇文章 。 我可以看到他們遇到的困難,但仍然不同意他更喜歡attr()
建議。
原始答案
如果您只使用過jQuery而不是直接使用DOM,那麼這可能是一個令人困惑的變化,儘管它在概念上肯定是一種改進。 對於使用jQuery的網站來說,這不太好,但是由於這種變化會破壞。
我將總結一下主要問題:
- 你通常需要
prop()
而不是attr()
。 - 在大多數情況下,
prop()
執行attr()
過去做的事情。 在代碼中用prop()
替換對attr()
調用通常會起作用。 - 屬性通常比屬性更容易處理。 屬性值可以只是一個字符串,而屬性可以是任何類型。 例如,
checked
屬性是一個布爾值,style
屬性是一個對象,每個樣式都有各自的屬性,size
屬性是一個數字。 - 如果存在屬性和具有相同名稱的屬性,通常更新一個將更新另一個,但輸入的某些屬性不是這種情況,例如
value
和checked
:對於這些屬性,該屬性始終表示當前狀態而屬性(IE的舊版本除外)對應於輸入的默認值/ checkedness(反映在defaultValue
/defaultChecked
屬性中)。 - 這個更改刪除了一些在屬性和屬性前面停留的魔法jQuery層,這意味著jQuery開發人員必須學習一些關於屬性和屬性之間的區別。 這是件好事。
如果你是一個jQuery開發人員並且對整個業務的屬性和屬性感到困惑,那麼你需要退後一步並學習一點,因為jQuery不再那麼努力地保護你不受這些東西的影響。 對於關於這個主題的權威但有點幹的詞,有規格: DOM4 , HTML DOM , DOM Level 2 , DOM Level 3 。 Mozilla的DOM文檔對大多數現代瀏覽器都有效,並且比規範更容易閱讀,因此您可能會發現他們的DOM參考有用。 有一個關於元素屬性的部分 。
作為屬性如何比屬性更易於處理的示例,請考慮最初檢查的複選框。 以下是兩個可能的有效HTML片段:
<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">
那麼,你怎麼知道是否用jQuery檢查了複選框? 查看,您通常會找到以下建議:
-
if ( $("#cb").attr("checked") === true ) {...}
-
if ( $("#cb").attr("checked") == "checked" ) {...}
-
if ( $("#cb").is(":checked") ) {...}
這實際上是世界上最簡單的事情,使用經過checked
布爾屬性,自1995年以來,該屬性在每個主要的可編寫腳本的瀏覽器中都存在並且完美無缺:
if (document.getElementById("cb").checked) {...}
該屬性還可以檢查或取消選中復選框:
document.getElementById("cb").checked = false
在jQuery 1.6中,這毫不含糊地變成了
$("#cb").prop("checked", false)
使用checked
屬性為複選框編寫腳本的想法是無益的,也是不必要的。 該物業是您所需要的。
- 檢查或取消選中復選框的正確方法是使用
checked
屬性,這一點並不明顯 - 屬性值反映默認值而不是當前可見狀態(除了IE的某些舊版本,因此使事情變得更加困難)。 該屬性不會告訴您是否選中了頁面上的複選框。 見http://jsfiddle.net/VktA6/49/ 。
。支柱()
.prop( propertyName ) propertyName Type: String The name of the property to get.
.prop()方法僅獲取匹配集中第一個元素的屬性值。它為尚未設置的屬性的值返回undefined,或者匹配的set沒有元素。要單獨獲取每個元素的值,請使用循環結構,例如jQuery的.each()或.map()方法。
<html>
<head>
<meta charset="utf-8">
<title>prop demo</title>
<style>
p {
margin: 20px 0 0;
}
b {
color: blue;
}
</style>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<input id="check1" type="checkbox" checked="checked">
<label for="check1">Check me</label>
<p></p>
<script>
$( "input" ).change(function() {
var $input = $( this );
$( "p" ).html(
".attr( \"checked\" ): <b>" + $input.attr( "checked" ) + "</b><br>" +
".prop( \"checked\" ): <b>" + $input.prop( "checked" ) + "</b><br>" +
".is( \":checked\" ): <b>" + $input.is( ":checked" ) + "</b>" );
}).change();
</script>
</body>
</html>
.attr()
.attr( attributeName ) attributeName Type: String The name of the attribute to get.
.attr()方法僅獲取匹配集中第一個元素的屬性值。要單獨獲取每個元素的值,請使用循環結構,例如jQuery的.each()或.map()方法。
使用jQuery的.attr()方法獲取元素屬性的值有兩個主要好處:
方便:它可以直接在jQuery對像上調用,並鏈接到其他jQuery方法。跨瀏覽器一致性:某些屬性的值在瀏覽器之間報告不一致,甚至在單個瀏覽器的版本中也是如此。.attr()方法減少了這種不一致。
<html>
<head>
<meta charset="utf-8">
<title>attr demo</title>
<style>
em {
color: blue;
font-weight: bold;
}
div {
color: red;
}
</style>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<p>Once there was a <em title="huge, gigantic">large</em> dinosaur...</p>
The title of the emphasis is:<div></div>
<script>
var title = $( "em" ).attr( "title" );
$( "div" ).text( title );
</script>
</body>
</html>
屬性在HTML 文本文檔/文件中 (==想像這是解析html標記的結果),而
屬性在HTML DOM樹中 (==基本上是JS意義上某個對象的實際屬性)。
重要的是,它們中的許多都是同步的(如果更新class
屬性,html中的class
屬性也將被更新;否則)。 但是某些屬性可能會同步到意外的屬性 - 例如,已checked
屬性對應於屬性 defaultChecked
,因此
- 手動檢查復選框將更改
.prop('checked')
值,但不會更改.attr('checked')
和.prop('defaultChecked')
值 - 設置
$('#input').prop('defaultChecked', true)
也會改變.attr('checked')
,但這在元素上是不可見的。
經驗法則是 :
.prop()
方法應該用於布爾屬性/屬性以及html中不存在的屬性(例如window.location)。 所有其他屬性(您可以在html中看到的屬性)可以並且應該繼續使用.attr()
方法進行操作。 ( http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/ )
這裡有一個表格,顯示.prop()
的首選位置(儘管仍然可以使用.attr()
)。
你為什麼有時會想要使用.prop()代替.attr(),後者是官方建議的?
-
.prop()
可以返回任何類型 - 字符串,整數,布爾值; 而.attr()
總是返回一個字符串。 -
.prop()
比.attr()
快約2.5倍。
jQuery 1.6引入了.prop()函數並分離了DOM屬性和屬性,它引發了很多關於.attr和.prop函數之間差異的問題。
見下面的例子:
例如:1)
<input id="demo" type="text" dbvalue="Kansagara" />
$("#demo").attr("dbvalue"); // returns Kansagara
$("#demo").prop("dbvalue"); // returns undefined
.prop()只返回HTML DOM屬性的值,它沒有返回自定義屬性的值,而.attr()也返回如上所示的自定義屬性值。
實施例:2)
<input id="demo" type="text" value="Kansagara" />
現在,我在文本框中將文本'Kansagara'更改為'Hitesh'。
$("#demo").attr("value"); // returns Kansagara
$("#demo").prop("value"); // returns Hitesh
現在你已經知道這意味著什麼。只更改了元素的屬性,因為它在DOM中是動態的。但元素的屬性是HTML文本,無法更改。從廣義上講,屬性總是表示當前狀態,而屬性(IE的舊版本除外)表示初始狀態或者是html屬性,因為它們是嚴格定義的。該屬性不會告訴您當前狀態。
一個複選框(jquery 1.6+)
<input id="check1" checked="checked" type="checkbox" />
.attr('checked') //returns checked
.prop('checked') //returns true
.is(':checked') //returns true
prop方法返回checked,selected,disabled,readOnly..etc的布爾值,而attr返回已定義的字符串。因此,您可以在if條件下直接使用.prop('checked')。
.attr()在內部調用.prop(),因此.attr()方法比直接通過.prop()訪問它們要慢一些。
對於jQuery 1.6+,將主要使用prop,因為它比attr簡單且寬泛。在大多數舊項目中,attr用於獲取元素的當前狀態信息。但是現在道具已經完成了這項工作,並且attr將被替換為道具。
希望能幫助到你。
一切都在文檔中:
在特定情況下,屬性和屬性之間的差異可能很重要。 在jQuery 1.6之前,.attr()方法有時在檢索某些屬性時會考慮屬性值,這可能會導致行為不一致。 從jQuery 1.6開始,.prop()方法提供了一種顯式檢索屬性值的方法,而.attr()只檢索屬性。
所以使用道具!
如果代碼以這種方式編寫,Gary Hole的答案與解決問題非常相關
obj.prop("style","border:1px red solid;")
由於prop函數返回CSSStyleDeclaration
對象,上面的代碼在某些瀏覽器中無法正常工作(IE8 with Chrome Frame Plugin
在我的情況下測試)。
從而將其更改為以下代碼
obj.prop("style").cssText = "border:1px red solid;"
解決了這個問題。
屬性在DOM中; HTML中的屬性被解析為DOM。
更多細節
如果更改屬性,則更改將反映在DOM中(有時使用不同的名稱)。
示例:更改標記的class
屬性將更改DOM中該標記的className
屬性。 如果標記上沒有屬性,則仍具有相應的DOM屬性,其屬性為空或默認值。
示例:雖然您的標記沒有class
屬性,但DOM屬性className
確實存在,其字符串值為空。
編輯
如果更改一個,另一個將由控制器更改,反之亦然。 這個控制器不在jQuery中,而是在瀏覽器的本機代碼中。
在jQuery 1.6之前,該attr()
方法有時在檢索屬性時會考慮屬性值,這會導致相當不一致的行為。
該prop()
方法的引入提供了一種顯式檢索屬性值的方法,同時.attr()
檢索屬性。
文件:
jQuery.attr()
獲取匹配元素集中第一個元素的屬性值。
jQuery.prop()
獲取匹配元素集中第一個元素的屬性值。
輕輕提醒使用prop()
,例如:
if ($("#checkbox1").prop('checked')) {
isDelete = 1;
} else {
isDelete = 0;
}
上面的函數用於檢查checkbox1是否被選中,如果選中:return 1; 如果不是:返回0.函數prop()在這裡用作GET函數。
if ($("#checkbox1").prop('checked', true)) {
isDelete = 1;
} else {
isDelete = 0;
}
上面的函數用於設置要檢查的checkbox1並始終返回1.現在函數prop()用作SET函數。
別搞砸了。
P / S:當我檢查Image src屬性時。如果src為空,則prop返回頁面的當前URL(錯誤),attr返回空字符串(右)。