第十六章 脚本化CSS
某些经常一起使用的样式属性可以组合起来使用一个特殊的复合属性。比如,font-family
、font-size
和font-weight
可以使用font的复合属性一次性设置:
font: bold italic 24pt helvetica;
当浏览器厂商实现非标准CSS属性时,会在属性名前加上厂商前缀。Firefox使用-moz-
,Chrome使用-webkit-
,而IE使用-ms-
,使用此类属性时可以将有前缀的属性名放在前面,没有前缀的放在后面,当浏览器认识有前缀的属性名时,就会忽略后面的。比如:
.radius{
-webkit-border-radius: 10px;
-ms-border-radius: 10px;
-o-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
脚本化内联样式
style是元素对象的属性,可以在JS中操作。但是style属性不同寻常:它的值不是字符串,而是一个CSSStyleDeclaration
对象。该style对象的JS属性代表了HTML代码中通过style指定的CSS属性。例如:
n.style.fontSize = "24px";
n.style.fontWeight = "bold";
n.style.color = "blue";
需要注意的是,很多CSS样式属性包含连字符。但是在JS中连字符是减号,所以不能使用连字符。
e.style.font-size = "24px"; //语法错误
e.style.fontSize = "24px"; //正确
所以CSSStyleDeclaration
属性名的格式应该将每个连字符后面紧接着的字母大写。和驼峰命名很相似。
另外,当一个CSS属性(比如float)在JS中对应的名字是保留字时,需要再之前加"css
"前缀来创建合法的CSSStyleDeclaration
名字。比如:
e.style.cssFloat = "left";
查询计算出的样式
元素的计算样式是一组属性值,它由浏览器通过把内联样式结合所有链接样式表中所有可应用的样式规则后导出(或计算)得到的:它就是一组在显示元素时实际实用的属性值。计算样式也是用CSSStyleDeclaration
对象来表示,但是计算样式是只读的。
用浏览器窗口对象的getComputedStyle()
方法来获取一个元素的计算样式。此方法的第一个参数就是要获取其计算样式的元素,第二个参数也是必需的,通常是null或空字符串,也可以是命名CSS伪对象的字符串,如":before
"、":after
"
let node = document.getElementById('main');
let style = window.getComputedStyle(node,null);
getComputedStyle()
方法返回值是一个CSSStyleDeclaration
对象,它代表了应用在指定元素或伪对象上的所有样式。表示计算样式的CSSStyleDeclaration
对象和表示内联样式的对象的区别如下:
- 计算样式的属性是只读的。
- 计算样式的值是绝对值。类似百分比和点之类相对的单位将全部转换为绝对值。所有指定尺寸的属性都有一个以像素为单位的值,该值是以"px"为后缀的字符串。
- 不计算复合属性,只基于最基础的属性。比如说,不要查询margin属性,应该使用
marginLeft
和marginRight
等。 - 计算样式的
cssText
属性未定义。
第十七章 事件处理
注册事件处理程序
使用addEventListener()
方法可以为事件目标注册事件处理程序。addEventListener()
接收三个参数。第一个是要注册处理程序的事件类型,是一个字符串,而且不包括前缀"on"。第二个参数是当指定类型的事件发生时调用的函数。第三个参数是布尔值(可省略)。通常传false
。传递true
意味着函数将注册为捕获事件处理程序,并在事件不同的调度阶段调用。
与addEventListener()
相对的是removeEventListener()
方法。同样有三个参数,常用于临时注册事件处理程序,然后不久删除。比如,为mousemove
和mouseup
事件注册临时捕获事件处理程序来看看用户是否拖动鼠标。
document.removeEventListener("mousemove",handleMove,true);
document.removeEventListener("mouseup",handleUp,true);
事件调用顺序
文档元素或其他对象可以为指定事件类型注册多个事件处理程序。浏览器必须按照以下规则调用所有的事件处理顺序:
- 通过设置对象属性或HTML属性注册的处理程序一直优先调用。
- 使用
addEventListener()
注册的处理程序按照它们的注册顺序调用。 - 使用
attachEvent()
注册的处理程序可能按照任何顺序调用,所以代码不应该依赖调用顺序。
鼠标事件
除了"mouseenter
"和"mouseleave
",所有的鼠标事件都可以冒泡。
类型 | 说明 |
---|---|
click | 当用户按下并释放鼠标按键或其他方式激活元素时触发 |
contextmenu | 可以取消的事件,当上下文菜单即将出现时触发。 |
dbclick | 双击鼠标 |
mousedown | 按下鼠标 |
mosueup | 释放鼠标 |
mousemove | 移动鼠标 |
mouseover | 鼠标进入元素 |
mouseout | 鼠标离开元素 |
mouseenter | 鼠标进入元素,但不冒泡。 |
mouseleave | 鼠标离开元素,但不冒泡。 |
传递给鼠标事件处理程序的事件对象有clientX
和clientY
属性,指定了鼠标指针相对于包含窗口的坐标。假如窗口的滚动偏移量就可以把鼠标位置转换为文档坐标。
altKey
、ctrlKey
、metaKey
和shiftKey
属性指定了当事件发生时是否有各种键盘辅助键按下。
键盘事件
当用户在键盘上按下或释放按键时,会发生keydown
和keyup
事件。如果用户按键事件足够长会导致开始重复,那么在keyup
事件到达之前会收到多个keydown
事件。事件一般由辅助键、功能键和字母数字键产生。
在chrome浏览器控制台中执行
monitorEvents(document.body,'keydown');
就可以在当前页面监听所有的keydown
事件,以Mac的左侧command
键盘按钮为例:
KeyboardEvent{
isTrusted: true,
key: "Meta",
code: "MetaLeft",
keyCode: 91,
altKey: false,
ctrlKey: false,
defaultPrevented:false,
metaKey:true,
shiftKey:false
}
上述属性是比较有用的几个信息,可以根据keyCode
来判断到底按的哪个键。注意,左右两侧的辅助键的keyCode
是不同的。
第二十章 客户端存储
localStorage和sessionStorage
localStorage
和sessionStorage
的区别在于存储的有效期的作用域的不同。通过localStorage
存储的数据是永久性的,除非Web应用刻意删除存储的数据,或者用户通过设置浏览器配置来删除,否则永不过期。sessionStorage
的有效期和存储数据的脚本所在的最顶层窗口或者是浏览器标签页是一样的。一旦窗口或者标签页被关闭,那么数据也被删除。
localStorage
和sessionStorage
的作用域限定在文档源级别。文档源通过协议、主机名和端口来确定。只要有一个不同,那就不算是同源。
https://www.google.com
//此例中,https是协议,www.google.com是主机名,默认端口是443
同源的文档间共享同样的localStorage
和sessionStorage
,它们可以互相读取对方的数据,甚至可以覆盖对方的数据。而且sessionStorage
的作用域还被限定在窗口中。如果同源的文档渲染在不同浏览器标签页,那么相互之间拥有各自的sessionStorage
数据,无法共享。
需要注意的是,这里提到的基于窗口作用域的sessionStorage
指的窗口只是顶级窗口。如果一个浏览器标签页包含两个<iframe>
元素,他们所包含的文档是同源的,那么可以共享sessionStorage
。
下面看下localStorage
和sessionStorage
提供的API。
// 存储和获取数值
localStorage.setItem("setKey",0);
localStorage.getItem("setKey");
//枚举所有存储的名字/值对
for(var i = 0; i < localStorage.length; i++) {
var name = localStorage.key(i);// 获取名字
var value = localStorage.getItem(name);//获取对应的数值
}
localStorage.removeItem("setKey"); //删除名字为"setKey"这个项
localStorage.clear(); //全部删除
无论什么时候存储在localStorage
或者sessionStorage
数据发生改变,浏览器都会在其他对该数据可见的窗口对象上触发存储事件。需要注意的是,只有当存储数据真正发生改变的时候才会触发存储事件。删除一个不存在的存储项是不会触发存储事件的。