11、JavaScript-事件
每天一句:一个人现在某一个领域达到极致,往往需要一万小时的积累。现在的你就是需要努力先让自己成为一个领域的高手,然后去获取更好的机会。[10时/天 * 30 = 300时/月 * 12 = 3600时/年 * 3 = 10800小时]
元素.style.width: 样式宽
元素.clientWidth: 可视宽度(样式宽 + padding)
元素.offsetWidth: 占位宽(样式宽 + padding + border)
一、获取元素CSS大小
- 通过style内联获取元素的大小
oBox.style.width // 空
oBox.style.height // 空
注: style只能获取到内联style属性的CSS中的宽度和高度,如果有即获取到;如果没有则返回空;
- 通过计算获取元素的大小
var width = window.getComputedStyle ? getComputedStyle(oBox).width : oBox.currentStyle.width; // width: 100px; => 100px
var height = window.getComputedStyle ? getComputedStyle(oBox).height : oBox.currentStyle.height; // height: 100px; => 100px
注: 通过计算获取元素的大小,不管是内联、内部、外部样式,它都经过计算后得到结果。如果本身设置有大小,即返回元素的大小;如果没有设置,非IE会返回默认大小,IE返回auto;
二、获取元素实际大小
- clientWidth和clientHeight 【可视区域大小: width+padding】
获取元素可视区域的大小,可以得到元素内容以及内边距的空间大小,即width+padding(height+padding);
oBox.clientWidth; // width: 100px; + padding: 10px; => 120
oBox.clientHeight; // height: 100px; + padding: 10px; => 120
注: 返回元素大小是没有单位的,默认单位就是px
- offsetWidth和offsetHeight 【实际大小即占位大小: width + padding + border】
oBox.offsetWidth // width: 100px; + padding: 10px; + border: 5px; => 130
oBox.offsetHeight // height: 100px; + padding: 10px; + border: 5px; => 130
- scrollWidth和scrollHeight 【滚动内容大小】
oBox.scrollWidth // 120
oBox.scrollHeight // 滚动内容的大小
三、获取元素周边大小
- clientLeft和clientTop 【元素边框大小】
oBox.clientLeft // border-left: 5px; => 5
oBox.clientTop // border-top: 5px; => 5
注: 目前只提供left和top,如果四条边框大小不一,可以通过计算得到;
右边框: oView.offsetWidth - oView.clientWidth - oView.clientLeft
- offsetLeft和offsetTop 【相对于父元素的位置】
oBox.offsetLeft // left:30 + margin-left:10 => 40
oBox.offsetTop // top:30 + margin-top:10 => 40
注: 获取元素当前相对于父元素的位置,最好设置有定位position: absolute;否则不同的浏览器会有不同的解释; 加上边框和边距不会影响它的位置,但加上外边界会累加;
四、焦点事件
焦点,使浏览器能够区分用户输入的对象,当元素有焦点时,就可以接受用户的输入,不是所有元素都能够接收焦点的,能响应用户操作的元素才有焦点;
// onfocus: 当元素获取焦点时触发
oText.onfocus = function(){
this.value = '';
}
// onblur: 当元素失去焦点时触发
oText.onblur = function(){
this.value = '请输入密码';
}
oText.focus(); // 获取焦点
oText.blur(); // 获取焦点
五、事件对象
- event对象
Event对象,当一个事件发生的时,和当前对象发生的相关信息,都会临时保存在这个对象中;
IE/谷歌: event是一个内置全局对象;
火狐: 事件对象是通过事件函数的第一个参数传入;
function fn2(ev){
// 兼容的写法
ev = ev || event;
// 遍历事件对象
for (att in ev){
document.write(att + '=' + ev[att] +'<br/>');
}
}
foo = foo || bar ,这行代码是什么意思?为什么要这样写?
这种写法称之为短路表达式
答案:if(!foo) foo = bar; //如果foo存在,值不变,否则把bar的值赋给foo。
- 事件源: 即触发该事件的节点
IE: event对象只有srcElement属性,而没有target属性;
火狐: event对象只有target属性,而没有srcElement属性;
谷歌/Safari: target和srcElement都可以使用;
oBox.onclick = function(ev){
ev = ev || event;
// 兼容的写法(在此表示的就是oBox对象)
var self = ev.target || ev.srcElement;
alert(ev.srcElement.id);
};
注意: 获取对应事件源后,最好要判断类型是否匹配;例如if(self.tagName.toLowerCase() === 'li'){...} ;
- offsetX和offsetY 【鼠标相对于事件源的位置】
ev.offsetX // 水平方向,距离事件源的左边位置
ev.offsetY // 垂直方向,距离事件源的顶部位置
- clientX和clientY 【鼠标相对于浏览器页面的位置】
ev.clientX // 水平方向,距离左边的位置
ev.clientY // 垂直方向,距离顶部的位置
案例: 跟随鼠标移动效果
六、事件类型
- onclick: 单击事件
- ondbclick: 双击事件
- onmousedown: 鼠标按下事件
- onmouseup: 鼠标释放(弹起)事件
- onmousemove: 鼠标移动事件
- onmouseover: 鼠标移入事件
- onmouseout: 鼠标移出事件
- onfocus: 获取焦点事件
- onblur: 失去焦点事件
注: onclick是鼠标点击弹起之后触发的事件,即一次完整的鼠标点击过程;而onmousedown是鼠标按下后触发,无需等待鼠标释放;即onclick = onmousedown + onmouseup;
七、事件冒泡
- 事件冒泡
当一个元素接收到事件以后,会将接收到的事件传递给父级元素,一直传递给顶层window;可以利用事件冒泡,可以减少事件的绑定,有利于性能优化
注意: 事件传递给某个元素,并不一会触发该事件;会不会触发该事件,和你是否添加该事件有关;

- 阻止事件冒泡
非IE: stopPropagation()
IE: ev.cancelBubble = true;
// 兼容写法
ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true;
案例: 输入框的提示列表 (事件冒泡的使用)
案例: 下拉菜单效果(阻止事件冒泡)
案例: 分享到 效果 (事件冒泡的使用)
案例: 表格的编辑(冒泡的利用-性能优化)
作业: 模拟select控件效果