JavaScript特性(attribute)、属性(property)和样式(style)
最近在研读一本巨著《JavaScript忍者秘籍》,里面有一篇文章提到了这3个概念。
书中的源码可以在此下载。我将源码放到了线上,如果不想下载,可以直接访问在线网址,修改页面名就能访问到相应示例代码。
一、DOM特性和DOM属性
attribute(特性),是我们赋予某个事物的特质或对象,attribute是HTML标签上的特性,它的值只能够是字符串
property(属性),是早已存在的不需要外界赋予的特质,property是DOM中的属性,是JavaScript里的对象
在访问元素特性值时有两种方式:
1. 传统DOM方法getAttribute和setAttribute。
2. 使用DOM对象上与之对应的属性。
例如通过两种方式获取id的值:
e.getAttribute('id');
e.id;
1)跨浏览器命名
特性和属性命名之间的差异会更多。
在大多数浏览器中可以用class获取到class特性,但IE却要使用className。
2)命名限制
特性表示为传递给DOM方法的字符串,其命名规范是非常自由的。
而属性名称,由于可以作为标识符使用点表示法进行访问,所以其命名规范更受限制。
3)HTML和XML之间的差异
在处理一个XML DOM的时候,不会在元素上自动创建属性值来表示特性值。
因此,我们需要使用传统的DOM特性方法获取特性的值。
elem.ownerDocument只读属性会返回当前节点的顶层的 document 对象。
function isXML(elem) {
return (elem.ownerDocument || elem.documentElement).nodeName.toLowerCase() !== 'html';
}
4)自定义特性的行为
要想访问自定义特性值,需要使用DOM方法getAttribute()与setAttribute()。
在HTML5中,对所有的自定义特性使用“data-”前缀。
5)性能注意事项
总的来说,属性的访问速度比相应DOM特性方法的访问速度要快,特别是在IE浏览器中。
下面做个测试,分别用两种方式读取和设置500W次。可以在不同浏览器中点开这个地址来查看测试结构。
下面的截图是在Chrome中的结果:
二、跨浏览器的Attribute问题
1)DOM中的id/name膨胀
5大浏览器都会将表单input元素的id和name特性作为<form>元素的属性值进行引用。
产生的这些属性,会主动覆盖form元素上已经存在的同名属性。
此外,IE浏览器不仅会替换属性值,甚至还会替换该属性值上的特性值。
<form id="testForm" action="/">
<input type="text" id="id"/>
<input type="text" name="action"/>
</form>
var form = document.getElementById('testForm');
assert(form.id === 'testForm', "the id property is untouched");
assert(form.action === '/', "the action property is untouched");
assert(form.getAttribute('id') === 'testForm', "the id attribute is untouched");
assert(form.getAttribute('action') === '/', "the action attribute is untouched");
在所有的现代浏览器中,由于这些input定义的id和name的值,表单的id和action属性都会被input元素的引用所替代。
解决方法是获取描述元素特性本身的原始DOM节点,该节点没有被浏览器修改:
var action = element.getAttributeNode('action').nodeValue;
2)URL规范化
在访问一个引用了URL属性时(例如src、href或action),该URL值会自动将原始值转换成完整规范的URL。
<a href="listing-11.5.html" id="testSubject">Self</a>
var link = document.getElementById('testSubject');
var linkHref = link.getAttributeNode('href').nodeValue; //#1 assert(linkHref === 'listing-11.5.html', 'link node value is ok');
assert(link.href === 'listing-11.5.html', 'link property value is ok');
assert(link.getAttribute('href') == linkHref, 'link attribute not modified');
3)style特性
HTML DOM元素有一个style属性,通过该属性我们能获取元素的样式信息,例如element.style.color。
<span style="color:red"></span>
如果要获取“color:red”字符串,那么style属性没用,得用getAttribute('style')方法获取。
但IE中得用element.style.cssText获取。
4)节点名称
在HTML文档中,nodeName属性返回的名称将是大写(例如HTML、BODY)。
在XML或XHTML文档中,nodeName返回的名称是用户指定的名称,可以大写、小写或混合。
三、令人头疼的样式特性
1)样式在何处
<style>
div { font-size: 1.8em; border: 0 solid gold; }
</style>
<div style="color:#000;" title="Ninja power!">
忍者
</div>
var div = document.getElementsByTagName("div")[0]; assert(div.style.color == 'rgb(0, 0, 0)' || div.style.color == '#000','color was recorded'); assert(div.style.fontSize == '1.8em', 'fontSize was recorded');
assert(div.style.borderWidth == '0', 'borderWidth was recorded');
div.style.borderWidth = "4px"; //#6
assert(div.style.borderWidth == '4px', 'borderWidth was replaced');
1. 大多数颜色都会转换成RGB颜色符号,有一些会转换为颜色的名称。
2. font-size和border都被记录在了style标签内,样式是继承获取的,但div.style属性中没有获取到。
3. 一个元素的style属性中的任何一个样式的优先级都要高于样式表所继承的样式(即便使用了“!important”注解规则)。
2)样式属性命名
CSS特性将多余一个单词的用连字符分隔,例如font-size、font-weight等。
在JS中可以用带有连字符的样式名称,但不能使用点运算符来访问样式了。
var size = element.style['font-size'];//允许
var size = element.style.font-size;//不允许
var size = element.style.fontSize;//允许
在JS中多个单词的CSS样式名称用驼峰的方式命名,例如fontSize、fontWeight。
具体的CSS样式表对应属性可以参考《CSS Properties Reference》
3)设置多个样式属性
不能通过直接给style属性设置字符串(如:elt.style = "color: blue;")来设置style,因为style应被当成是只读的。
设置多个属性可以用cssText或setAttribute,其中cssText会将重复属性覆盖屌。
elt.style.cssText = "color: blue"; // 设置多个样式属性 当带前缀的时候-webkit-transform:rotate(0deg),会过滤掉-webkit,只能用下面的方式
elt.setAttribute("style", "color: blue"); // 设置多个样式属性
4)float样式属性
float是JS中的保留关键字,浏览器需要提供另外一个替代名称。
大部分浏览器使用cssFloat,但IE使用styleFloat。
5)像素值的转换过程
为style属性设置数字时,必须要指定单位,以便在所有的浏览器上都能使用。
element.style.height = '10px';//安全
element.style.height = 10;//不安全
6)测量元素的高度和宽度
offsetHeight和offsetWidth可以获取元素的高度和宽度,不过这两个属性值包括了padding值,更多元素尺寸属性可以参考《JavaScript中尺寸、坐标》
但如果元素隐藏(例如display:none),获取到的数值都是0。对于隐藏元素可以用如下的方法:
可以查看在线demo实例:
“Pole”是显示的图片,就是那个忍者。
而“Shuriken”是隐藏的图片,一开始是获取不到宽度的,在使用了上面的技巧后就能获取到了。
7)通过opacity看透明度
所有现代浏览器,包括IE9支持opacity属性,但IE9之前的版本需要使用专用的alpha过滤法。
opacity: .5;
filter: alpha(opacity=50)
支持opacity的浏览器,总会将值规范为小于1.0且以0开头的值。
例如“opacity:.5”,那么支持的将返回“0.5”,不支持的将返回“.5”。
通过特性仿真,可以判断浏览器是否支持opacity。
//特性仿真检测
var div = document.createElement("div"); //#1
div. setAttribute('style','opacity:.5');
var OPACITY_SUPPORTED = div.style.opacity === "0.5"; assert(OPACITY_SUPPORTED, "Opacity is supported.");
8)颜色属性
通过不同的计算样式方法访问这些颜色值的时候,各种浏览器的返回值几乎都不一致。
下面是一个在线demo,在不同浏览器中展示的颜色值:
IE8 |
Firefox | Chrome |
![]() |
![]() |
![]() |
IE8不支持RGBA和HSL格式 |
Firefox不仅保留了颜色名称, 而且标准颜色是RGB和RGBA格式 |
Webkit浏览器(Chrome、Safari) 标准颜色是RGB和RGBA格式 |
四、获取计算样式
1)window.getComputedStyle()与element.currentStyle
一个元素的计算样式(computed style)都是应用在该元素上的所有样式组合。
这些样式包括样式表、元素的style特性,以及脚本对style属性的各种操作。
现代浏览器(包括IE9)的实现方法为:window.getComputedStyle(),返回接口提供了一个getPropertyValue()的方法。
IE9之前的版本,通过附加到所有元素上的currentStyle属性,表现和style属性一样。
/**
* property可以传入驼峰或分隔符方式
*/
function fetchComputedStyle(element, property) { //#3
//现代浏览器 包括IE9
if (window.getComputedStyle) {
var computedStyles = window.getComputedStyle(element); //#4
if (computedStyles) { //#5
property = property.replace(/([A-Z])/g, '-$1').toLowerCase();
return computedStyles.getPropertyValue(property);//getPropertyValue中需要传入分隔符字符串,例如font-size
}
} else if (element.currentStyle) { //IE9以下
property = property.replace(
/-([a-z])/ig,
function(all, letter) {
return letter.toUpperCase();
});
return element.currentStyle[property];
}
}
JavaScript特性(attribute)、属性(property)和样式(style)的更多相关文章
- JavaScript的attribute和property辨析
1.Attribute Attribute是HTML上设置的属性,在html中显式地设置,或者通过setAttribute()方法设置. <input type='text' id='txt' ...
- javascript之attribute 和 property
首先看看这两个单词的英文释义(来自有道词典).先是property: property ['prɔpəti] n. 性质,性能:财产:所有权 英英释义: any area set aside for ...
- javascript 读取内联之外的样式(style、currentStyle、getComputedStyle区别介绍) (转载)
样式表有三种方式: 内嵌样式(inline Style) :是写在Tag里面的,内嵌样式只对所有的Tag有效. (也称作“内联样式”) 内部样式(internal Style Sheet):是写在 ...
- javascript中attribute和property的区别详解
DOM元素的attribute和property很容易混倄在一起,分不清楚,两者是不同的东西,但是两者又联系紧密.很多新手朋友,也包括以前的我,经常会搞不清楚. attribute翻译成中文术语为“特 ...
- 理解特性attribute 和 属性property的区别 及相关DOM操作总结
查一下英语单词解释,两个都可以表示属性.但attribute倾向于解释为特质,而property倾向于解释私有的.这个property的私有解释可以更方便我们下面的理解. 第一部分:区别点 第一点: ...
- 区分元素特性attribute和对象属性property
× 目录 [1]定义 [2]共有 [3]例外[4]特殊[5]自定义[6]混淆[7]总结 前面的话 其实attribute和property两个单词,翻译出来都是属性,但是<javascript高 ...
- DOM对象属性(property)与HTML标签特性(attribute)
HTML中property与attribute是极易混淆的两个概念.大多数时候这两个单词都翻译为"属性",为了区分二者,一般将property翻译为"属性",a ...
- 深入理解JavaScript中的属性和特性
深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...
- javascript DOM 操作 attribute 和 property 的区别
javascript DOM 操作 attribute 和 property 的区别 在做 URLRedirector 扩展时,注意到在使用 jquery 操作 checkbox 是否勾选时,用 at ...
随机推荐
- python核心编程第二版练习题答案
2-5 #写一个while循环,输出整型为0~10 a=0while a<11: print a a+=1 #写一个for循环重复以上操作 for i in range(11): print i ...
- 恋爱虽易,相处不易:当EntityFramework爱上AutoMapper
剧情开始 为何相爱? 相处的问题? 女人的伟大? 剧情收尾? 有时候相识即是一种缘分,相爱也不需要太多的理由,一个眼神足矣,当EntityFramework遇上AutoMapper,就是如此,恋爱虽易 ...
- 谈一下关于CQRS架构如何实现高性能
CQRS架构简介 前不久,看到博客园一位园友写了一篇文章,其中的观点是,要想高性能,需要尽量:避开网络开销(IO),避开海量数据,避开资源争夺.对于这3点,我觉得很有道理.所以也想谈一下,CQRS架构 ...
- WebApi基于Token和签名的验证
最近一段时间在学习WebApi,涉及到验证部分的一些知识觉得自己并不是太懂,所以来博客园看了几篇博文,发现一篇讲的特别好的,读了几遍茅塞顿开(都闪开,我要装逼了),刚开始读有些地方不理解,所以想了很久 ...
- java web学习总结(五) -------------------servlet开发(一)
一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...
- centos安装nodejs
1.下载安装nodejs wget http://nodejs.org/dist/v0.10.25/node-v0.10.25.tar.gz compat--c++ tar -xf node-v0.1 ...
- [原创]Macbook Pro Retina 15吋安装Windows 7和Windows 8.1方法
前言 本以为有Bootcamp神器在手,Macbook装Win系统应该是不在话下,没想到着实折腾了一番.期间因为误操作导致OSX也挂掉进不去只得磁盘全部抹掉网络恢复安装.为了让大家少走弯路,提供个人安 ...
- 【腾讯Bugly干货分享】微信热补丁Tinker的实践演进之路
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ad7a70eaed47bb2699e68e Dev Club 是一个交流移动 ...
- 从淘宝 UWP 的新功能 -- 比较页面来谈谈 UWP 的窗口多开功能
前言 之前在 剁手党也有春天 -- 淘宝 UWP ”比较“功能诞生记 这篇随笔中介绍了一下 UWP 淘宝的“比较”新功能呱呱坠地的过程.在鲜活的文字背后,其实都是程序员不眠不休的血泪史(有血有泪有史) ...
- DevExpress学习系列(控件篇):GridControl的基本应用
一般属性设置 不显示分组框:Gridview->Option View->Show Group Panel=false 单元格不可编辑:gridcontrol -->gridview ...