by addy 原创文章,欢迎转载,但希望全文转载,注明本文地址。

本文地址:http://www.iamaddy.net/2016/09/javascript-set-style/

今天犯了一个错误:设置dom元素的style

<!DOCTYPE html>
<html>
<head>
<title>text</title>
</head>
<body>
  <div id="content" style="width:200px;height:200px"></div>
<script>
document.querySelector('#content').style = 'background-color:red;width:200px;height:200px'
</script>
</body>
</html>

在Windows chrome下调试页面,背景色能够变红,但在iOS的Safari上却不生效。

element.style // 返回CSSStyleDeclaration对象

但是如果将字符串赋值给style,当然是不行的。只是chrome自动将字符串转换成style的cssText属性值了。在chrome下,以下代码效果是一样的。

element.style= 'background-color:red;width:200px;height:200px'

element.style.cssText = 'background-color:red;width:200px;height:200px'

但其他的浏览器(如Safari)却没有做转换,只能通过element.style.cssText设置才生效。另外还有一种方式则是设置dom元素的attribue属性。

element.setAttribue('style', 'background-color:red;width:200px;height:200px')

attribute 与 property

In HTML, most attributes have two faces: the content attribute and the IDL attribute.

官方的说法html的attributes包含content attribute 和 IDL attribute两种, IDL attribute就是javascript中对象的property。下文说的property都指的是 IDL attribute。

由以上问题,扩展开来谈谈html中的attribute 与 property。

element.setAttribue('style', 'background-color:red;width:200px;height:200px')

element.getAttribue('style') // attribute ,return string

element.style // property, return object

上面这段是毫无疑问的,在每个浏览器的表现都是如此。通过.操作来获取property,通过getAttribue来获取attribute值,但两者在html中,经常被混淆,大概是有的属性既可以是attribute,也可以是property,第二是不同dom元素表现不一样。

通过element.setAttribute(),element.getAttribute()设置或获取attribute,获取到的attribute返回的类型是string,即使在设置的时候为int类型。

在chrome下通过以下代码,我们可以得知attributes是存放到NamedNodeMap这个类数组中。

document.body.attributes
/*
NamedNodeMap
{
    1: onload
    2: class
    length:2
}
*/

如果attribute的name,是dom元素标准中的,其实attribute与property一一映射的,修改attribute,也会使得property变化,如id,className。

document.body.id = '111'
document.body.getAttribute('id') // '111'

document.body.setAttribute('id', '22') 
document.body.id // '22'

而如果是自定义的attribute,则不会反应到property上,同理,反过来也成立。

document.body.a_id = '111'
document.body.getAttribute('a_id') // null

document.body.setAttribute('a_id', '22') 
document.body.a_id // undefined,可以理解为JavaScript的属性,dom对象同样是JavaScript中的对象。

但是有些元素有特例:如<input type="text">

input.type // 'text'
input.type="foobar"
input.type // 'text'

input.getAttribute('type') // 'foobar'

通过属性设置,不一定会生效,因为foobar对input的type属性来说是非法的。大多数时候,property获取到的值是那些真正被用到的。

最奇特的怕是checkbox和radio这两个控件了。

<input type="checkbox" id="checkall">

// 第一种情况,读取attribute 与 property
document.querySelector('#checkall').checked //false
document.querySelector('#checkall').getAttribute('checked') // null

// 第二种情况 选中,设置property,读取attribute
document.querySelector('#checkall').checked = true; 
document.querySelector('#checkall').getAttribute('checked') // null

// 第三种情况 选中,设置attribute,读取property
document.querySelector('#checkall').setAttribute('checked', true) 
document.querySelector('#checkall').checked // true

// 第四种情况 选中,设置attribute,读取property
document.querySelector('#checkall').setAttribute('checked', 'checked') // 'checked'或者其他任何值
document.querySelector('#checkall').checked // true

我们发现无论给checkbox,setAttribute任何值,都能选中,value会转换为string,所以对于到property是true,则选中。设置property时,只要类型转换后为false,则取消选中,但getAttribute的时候,却不受property的影响。

总结就是:checkbox的checked属性,attribute影响property的bool类型,property不影响attribute。

不同元素得不同对待,最好查看标准的文档,免得踩坑。以下是参考文档:

http://weibo.com/p/1001603859879528949427
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
https://html.spec.whatwg.org/multipage/infrastructure.html#reflecting-content-attributes-in-idl-attributes

本文为原创文章,可能会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,谢谢合作

本文地址:http://www.iamaddy.net/2016/09/javascript-set-style/

想要打赏?你的鼓励是我前进的动力! addy打赏二维码

关注个人公众号web_lab,不定期更新一些干货~ web_lab公众号