上一篇讲解dojo/dom-attr的文章中我们知道在某些情况下,attr模块中会交给prop模块来处理。比如:

  • textContent、innerHTML、className、htmlFor、value
  • disabled、checked等无状态特性对应于属性中的布尔变量
  • 事件的处理

  那这一节,我们便来看看prop对于属性的处理。

  首先是一个标准名称字典,将要设置的属性名重新命名,避免与保留字的冲突:

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方法的函数签名为:

// Dojo 1.7+ (AMD)
require(["dojo/dom-prop"], function(domProp){
result = domProp.get("myNode", "someAttr");
});

  除了textContent属性外,其他直接以方括号语法从node中取值:node[prop];对于textContent属性,如果元素不支持textContent,便以深度优先算法去获取元素下所有文本节点的nodevalue:

function getText(/*DOMNode*/node){
var text = "", ch = node.childNodes;
for(var i = , n; n = ch[i]; i++){
//Skip comments.
if(n.nodeType != ){
if(n.nodeType == ){
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方法的函数签名为:

require(["dojo/dom-prop"], function(domProp){
result = domProp.set("myNode", "someAttr", "value");
});

  在attr.set方法中,很多情况都交给prop来处理,下面我们就要看看prop中set方法的实现。

  set方法用来为元素的属性赋值,在实际应用中需要处理以下几种情况:

  • 参数分解,如果一次设置多个属性,为每个属性分别设置
  • 如果someAttr是“style”,则交给dom-style模块处理
  • 如果someAttr是innerHTML,因为有的元素(tbody、thead、tfoot、tr、td、th、caption、colgroup、col)不支持innerHTML属性,所以需要曲线救国,这里首先将元素的子节点清除掉,然后利用dom-construct的toDom方法,将html片段转化成dom节点,作为子节点插入元素中
  • 如果someAttr是textContent,同样因为有的浏览器并不支持该属性,曲线救国的方式是先清除元素的子节点,然后创建文本节点作为子节点插入元素中
  • 如果value是function,则看做添加事件;对于event的处理最好不要使用prop模块还是推荐使用on模块来绑定事件
    exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
node = dom.byId(node);
var l = arguments.length;
//分解参数
if(l == && 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: , colgroup: ,
table: , tbody: , tfoot: , thead: , tr: , title: }){
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
};

  如果您觉得这篇文章对您有帮助,请不吝点击右下方“推荐”,谢谢~

上层建筑——DOM元素的特性与属性(dojo/dom-prop)的更多相关文章

  1. 上层建筑——DOM元素的特性与属性(dojo/dom-attr)

    上一篇返本求源中,我们从DOM基础的角度出发,总结了特性与属性的关系.本文中,我们来看看dojo框架是如何处理特性与属性的.dojo框架中特性的处理位于dojo/dom-attr模块属性的处理为与do ...

  2. 返本求源——DOM元素的特性与属性

    抛砖引玉 很多前端类库(比如dojo与JQuery)在涉及dom操作时都会见到两个模块:attr.prop.某天代码复查时,见到一段为某节点设置文本的代码: attr.set(node, 'inner ...

  3. js便签笔记(2)——DOM元素的特性(Attribute)和属性(Property)

    1.介绍: 上篇js便签笔记http://www.cnblogs.com/wangfupeng1988/p/3626300.html最后提到了dom元素的Attribute和Property,本文简单 ...

  4. 使用jQuery匹配文档中所有的li元素,返回一个jQuery对象,然后通过数组下标的方式读取jQuery集合中第1个DOM元素,此时返回的是DOM对象,然后调用DOM属性innerHTML,读取该元素 包含的文本信息

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. JavaScript Dom基础-9-Dom查找方法; 设置DOM元素的样式; innerHTML属性的应用; className属性的应用; DOM元素上添加删除获取属性;

    JavaScript Dom基础 学习目标 1.掌握基本的Dom查找方法 domcument.getElementById() Domcument.getElementBy TagName() 2.掌 ...

  6. dom元素上添加断点(使用dom breakpoint找到修改属性的javascript代码)

    使用dom breakpoint能快速找到修改了某一个dom element的JavaScript code位于何处.在Chrome development tool里,选中想要inspect的dom ...

  7. DOM元素的Attribute(特性)和Property(属性) 【转载】

    1.介绍: 上篇js便签笔记http://www.cnblogs.com/wangfupeng1988/p/3626300.html最后提到了dom元素的Attribute和Property,本文简单 ...

  8. jQuery 数据 DOM 元素 核心 属性

    jQuery 参考手册 - 数据 .clearQueue() 从序列中删除仍未运行的所有项目 .clearQueue(queueName) $("div").clearQueue( ...

  9. 获取或操作DOM元素特性的几种方式

    1. 通过元素的属性 可以直接通过元素属性获取或操作特性,但是只有公认的特性(非自定义的特性),例如id.title.style.align.className等,注意,因为在ECMAScript中, ...

随机推荐

  1. 异步I/O操作

    今天在看boost库的时候注意到异步I/O操作时,缓冲区有效性问题. 如何实现异步操作:以异步读操作为例async_read(buffer, handler): void handler() {} v ...

  2. odoo10 费用报销

    odo10 对费用报销进行了改进,恢复了 8.0 及之前版本具有的 单个报销包含多个 明细内容的功能. 使用步骤大致如下: 根据管理需要设立 相应的科目和分析帐户 科目 分析帐户 建立费用目录 员工录 ...

  3. oracle数据库升级记(记一次10.2.0.3版本升级到11.2.0.1版本的过程)

    操作系统:windows xp 已有数据库版本:10.2.0.3 升级目标版本:11.2.0.1 步骤大纲: 在源操作系统(安装有10.2.0.3数据库的操作系统)上安装11.2.0.1数据库软件,然 ...

  4. 如何查看apache,php,mysql的编译参数

    查看nginx编译参数:/usr/local/nginx/sbin/nginx -V 查看apache编译参数:cat /usr/local/apache2/build/config.nice 查看m ...

  5. oracle创建用户并导入dmp文件

    SQL命令行执行以下命令:SQL> conn sys/111111 as sysdba; SQL> CREATE USER TEST11 IDENTIFIED BY "11111 ...

  6. LeetCode(97) Interleaving String

    题目 Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example, Given: ...

  7. 读写SD

    public class SD_Files_RW extends Activity implements OnClickListener{ private String Text_of_input; ...

  8. python模块及包的导入

    一.模块 通常模块为一个文件,直接使用import来导入就好了.可以作为module的文件类型有".py".".pyo".".pyc".&q ...

  9. [fortify] preg_replace命令注入

    慎用preg_replace危险的/e修饰符(一句话后门常用) 作者: 字体:[增加 减小] 类型:转载 时间:2013-06-19我要评论 要确保 replacement 构成一个合法的 PHP 代 ...

  10. allegro中焊盘的设置

    用Cadence的pad designer制作pad的时候会遇到为thermal relief和anti pad设计尺寸的问题 Thermal relief:正规的中文翻译应该叫做防散热PAD.它主要 ...