屬性操作是DOM操作很大的一塊,它包括類名操作,表單元素的value屬性操作,元素固有屬性的管理,元素自定義屬性的管理,某些元素的一些布爾屬性的操作。大多數情況下,元素屬性的值是字符串類型,我們稱之為字符串屬性,但有一些屬性的是布爾,也存在是數字類型、節點引用的情況。當前jQuery處理它們就是搞了N個鈎子對象,才擺平它們。avalon為了收拾它們也設置N多綁定,其中類名部分交由ms-class、 ms-hover、 ms-active處理,這些其他章節介紹;表單元素的value屬性之前也說過,可以用ms-value、ms-duplex;剩下還有ms-checked、 ms-selected、 ms-readonly、 ms-disabled、 ms-enabled、 ms-value、 ms-title、 ms-alt、 ms-href、 ms-src、 ms-attr-☆ 11個。其他前五個為布爾屬性綁定,后五個為字符串屬性綁定,最后一個為通用屬性綁定。不過 后來, 隨着如何判定固有屬性的技術的發掘,它們最終全部由ms-attr-☆實現。
在IE下,需要對屬性進行區分,如果是固有屬性使用elem[name] = value賦值;是自定義屬性,則直接使用elem.setAttribute(name, value);標准瀏覽器沒有這么麻煩,全部使用elem.setAttribute(name, value),比如elem.setAttribute("value", "xxx")會自動同步到elee.value = "xxx"。
下面是其源碼:
if (boolMap[attrName]) {
var bool = boolMap[attrName]
if (typeof elem[bool] === "boolean") {
return elem[bool] = !!val //處理布爾屬性
}
}
if (!W3C && propMap[attrName]) {//舊式IE下需要進行名字映射
attrName = propMap[attrName]
var isInnate = true
}
if (val === false) || (val === null) || (val === void 0) {
return elem.removeAttribute(attrName)
}
if (window.VBArray && !isInnate) {
//IE下需要區分固有屬性與自定義屬性
//固有屬性及VML元素必須使用中括號方式賦值
//SVG元素必須用setAttribute賦值
if (isVML(elem)) {
isInnate = true
} else if(window.SVGElement && !(elem instanceof SVGElement)) {
var attrs = elem.attributes || {}
var attr = attrs[attrName]
isInnate = attr ? attr.expando === false : attr === null
}
}
if (isInnate) {
elem[attrName] = val
} else {
elem.setAttribute(attrName, val)
}
有關如何判定自定義屬性或固有屬性,及其詳細推導過程,可以看我的書《javascript框架設計》的第十章。
<!DOCTYPE html>
<html>
<head>
<title>ms-attr-*</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<script src="avalon.js"></script>
<script>
avalon.define("ms-attr-*", function(vm) {
vm.aaa = true
vm.click = function() {
vm.aaa = !vm.aaa
}
vm.bbb = "@@@"
vm.ccc = "&&&"
vm.active = "active"
})
</script>
<style>
.active {
background: goldenrod;
}
.readonly{
border:1px solid blueviolet;
}
</style>
</head>
<body>
<form method="get" action="aaa.html" ms-controller="ms-attr-*">
<input ms-enabled="aaa" name="a1" value="12345"/>
<input ms-disabled="aaa" name="a2" value="67890"/>
<input ms-readonly="aaa" name="a3" ms-class="readonly: aaa" value="readonly" />
<input ms-checked="aaa" type="checkbox" value="checkbox" name="a4"/>
<select name="a5">
<option>222</option>
<option ms-selected="aaa">555</option>
</select>
<p>
<input ms-attr-value="其他內容 {{ccc}}" name="a6" value="改"/>
<input ms-attr-value="'其他內容 '+ccc" name="a7" value="改" />
<input ms-value="其他內容 {{ccc}}" name="a8" value="改"/>
</p>
<button type="button" ms-click="click" ms-attr-class="active">
點我
</button>
<input type="submit" value="提交" />
<svg width="100" height="100">
<circle ms-attr-cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
</form>
</body>
</html>
ms-enabled是ms-disabled的相反面,它根據表達式的值是否為真移除disabled屬性。
avalon的ms-attr綁定無比強大,不用像jQuery那么需要用戶判定是使用attr還是prop方法,使用自行處理。
