上一篇講解dojo/dom-attr的文章中咱們知道在某些狀況下,attr模塊中會交給prop模塊來處理。好比:html
那這一節,咱們便來看看prop對於屬性的處理。node
首先是一個標準名稱字典,將要設置的屬性名從新命名,避免與保留字的衝突:算法
exports.names = { // properties renamed to avoid clashes with reserved words "class": "className", "for": "htmlFor", // properties written as camelCase tabindex: "tabIndex", readonly: "readOnly", colspan: "colSpan", frameborder: "frameBorder", rowspan: "rowSpan", textcontent: "textContent", valuetype: "valueType" };
相比dom-attr來講,dom-prop模塊只有兩個公共函數:prop.get與prop.set瀏覽器
prop.get方法的函數簽名爲:app
// Dojo 1.7+ (AMD) require(["dojo/dom-prop"], function(domProp){ result = domProp.get("myNode", "someAttr"); });
除了textContent屬性外,其餘直接以方括號語法從node中取值:node[prop];對於textContent屬性,若是元素不支持textContent,便以深度優先算法去獲取元素下全部文本節點的nodevalue:dom
function getText(/*DOMNode*/node){ var text = "", ch = node.childNodes; for(var i = 0, n; n = ch[i]; i++){ //Skip comments. if(n.nodeType != 8){ if(n.nodeType == 1){ text += getText(n); }else{ text += n.nodeValue; } } } return text; }
由於innerText並非標準屬性,因此這裏棄之不用;如下即是get方法的源碼:函數
exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){ node = dom.byId(node); //轉化成標準屬性 var lc = name.toLowerCase(), propName = exports.names[lc] || name; //處理textContent這種特殊屬性 if(propName == "textContent" && !has("dom-textContent")){ return getText(node); } return node[propName]; // Anything };
prop.set方法的函數簽名爲:ui
require(["dojo/dom-prop"], function(domProp){ result = domProp.set("myNode", "someAttr", "value"); });
在attr.set方法中,不少狀況都交給prop來處理,下面咱們就要看看prop中set方法的實現。spa
set方法用來爲元素的屬性賦值,在實際應用中須要處理如下幾種狀況:code
exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ node = dom.byId(node); var l = arguments.length; //分解參數 if(l == 2 && typeof name != "string"){ // inline'd type check for(var x in name){ exports.set(node, x, name[x]); } return node; // DomNode } //若是要設置style,調用dom-style來處理 var lc = name.toLowerCase(), propName = exports.names[lc] || name; if(propName == "style" && typeof value != "string"){ // inline'd type check // special case: setting a style style.set(node, value); return node; // DomNode } //若是是innerHTML,對於不支持innerHTML的節點,採用曲線救國的方式,不然直接設置innerHTML if(propName == "innerHTML"){ // special case: assigning HTML // the hash lists elements with read-only innerHTML on IE if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1, table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){ ctr.empty(node); node.appendChild(ctr.toDom(value, node.ownerDocument)); }else{ node[propName] = value; } return node; // DomNode } //若是不支持textContent,清除元素子節點後,添加文本節點 if(propName == "textContent" && !has("dom-textContent")) { ctr.empty(node); node.appendChild(node.ownerDocument.createTextNode(value)); return node; } //這一部分是經過prop來綁定事件,但並不建議用這種方式 if(lang.isFunction(value)){ // special case: assigning an event handler // clobber if we can var attrId = node[_attrId]; if(!attrId){ attrId = _ctr++; node[_attrId] = attrId; } if(!_evtHdlrMap[attrId]){ _evtHdlrMap[attrId] = {}; } var h = _evtHdlrMap[attrId][propName]; if(h){ //h.remove(); 若是曾經以相似的方式綁定過事件,則移除事件 conn.disconnect(h); }else{ try{ delete node[propName]; }catch(e){} } // ensure that event objects are normalized, etc. if(value){//prop.get函數返回node,因此把handle放到_evtHdlrMap中 //_evtHdlrMap[attrId][propName] = on(node, propName, value); _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value); }else{ node[propName] = null; } return node; // DomNode } node[propName] = value; //直接爲屬性賦值 return node; // DomNode };
若是您以爲這篇文章對您有幫助,請不吝點擊右下方「推薦」,謝謝~