day11 事件高级
1.回顾
- 表单事件
- 表单域事件
- 提交事件 onsubmit
- 重置事件 onreset
- 表单元素事件
- 获得焦点事件 onfocus
- 失去焦点事件 onblur
- onchange:失去焦点时内容和之前有变化时触发
- oninput/onpropertychange:输入框内容发生变化时触发(实时)
- 表单域事件
- window和document?
- window–窗口
- document–文档
- location
- location.href : 获取设置当前窗口显示的url
- location.hash:哈希 #
- location.seach搜索内容
- location.protocol:协议
- client
- 元素的可视宽高:元素.clientWidth/Height : content+padding
- 屏幕的可视宽高:document.documentElement.clientWidth/Height
- offset
- 元素的占位宽高:元素.offsetWidth/Height : content+padding+border
- 元素的位置:元素.offfsetTop/Left:从当前元素顶部/左边到定位父元素的位置,如果没有定位父元素到body的距离
- scroll
- 滚动事件 window.onscroll
- 屏幕的滚动距离:document.documentElement.scrollTop||document.body.scrollTop
2.事件高级
2.1 事件对象
-
事件处理函数:事件发生的时候调用的函数,事件处理函数
-
事件对象:window.event 在事件处理函数中使用的一个特殊对象,当事件发生的时候,浏览器会将所有和当前事件相关的信息存储在事件对象event(事件类型,鼠标位置,事件目标。。。。)
chrome/ie:window.event ff:通过事件处理函数的第一个参数传入 兼容:var ev = window.event||ev document.onclick = function(ev){ console.log(window.event); console.log(event); console.log(ev); //ff //兼容 var ev = window.event || ev; console.log(ev); }
-
事件对象常用属性
-
type:事件类型
-
target||srcElement:事件目标
-
clientX,clientY:鼠标位置,相对于屏幕的左上角
-
shiftkey,ctrlKey,altKey:事件发生的时候有没有按住这个键,有-true,没有false
console.log(ev.type); //事件类型 click console.log(ev.target || ev.srcElement);//事件目标 真正触发事件的对象 console.log(ev.clientX + "----------"+ev.clientY); //鼠标位置 相对于屏幕左上角 console.log(ev.pageX + "----------"+ev.pageX); //鼠标位置 相对于页面左上角 console.log(ev.shiftKey,ev.ctrlKey,ev.altKey);//事件发生的时候有没有按住这些功能键,按了-true 没按-false }
-
2.2 事件绑定与取消
2.2.1 事件绑定
-
标准浏览器:标签.addEventListener(事件类型[不加on],事件处理函数,是否捕获)
-
ie浏览器:标签.attachEvent(事件类型[加on],事件处理函数)
-
区别:
- 标准浏览器不加on,ie加on
- 标准浏览器有捕获,ie没有捕获
- 标准浏览器按添加顺序执行,ie低版本倒序执行
- 标准浏览器this指触发事件的对象,ie this指window
//1.标准浏览器绑定:标签.addEventListener(事件类型[不加on],事件处理函数,是否捕获) oDiv.addEventListener("click",fun1); oDiv.addEventListener("click",fun2); //2.ie浏览器绑定:标签.attachEvent(事件类型[加on],事件处理函数) 没有捕获 oDiv.attachEvent("onclick",fun2); oDiv.attachEvent("onclick",fun1); //3.兼容 if(oDiv.addEventListener){ oDiv.addEventListener("click",fun1); }else{ oDiv.attachEvent("onclick",fun1); }
2.2.2 事件取消
不同的添加方式需要使用不同的取消方式
添加方式 | 取消方式 |
---|---|
标签.事件 | 标签.事件=null |
标签.addEventListener(类型,处理函数) | 标签.removeEventListener(类型,处理函数) |
标签.attachEvent(类型,处理函数) | 标签.detachEvent(类型,处理函数) |
//1.简单事件的添加
oBtn.onclick = function(){
console.log(arr[getRandom(0,arr.length-1)]);
oBtn.onclick = null; //取消
}
//2.绑定的添加
function fun1(){
console.log(arr[getRandom(0,arr.length-1)]);
//oBtn.removeEventListener("click",fun1); 标准浏览器取消
//oBtn.detachEvent("onclick",fun1);//ie浏览器取消
if(oBtn.removeEventListener){
oBtn.removeEventListener("click",fun1);
}else{
oBtn.detachEvent("onclick",fun1);
}
}
2.2.3 DOM事件流
标签.addEventListener(“click”,fun,是否捕获);
是否捕获:默认是false false:冒泡 true:捕获
DOM事件流:两个机制
- 事件捕获机制:事件发生的时候,事件从window开始,根据结构一层一层往里查找,一直到目标元素位置(不处理事件)
- 事件冒泡机制:由目标元素开始处理事件,处理完成以后将事件根据结构依次传递给父元素,一直到window
window–document–body–标签
var oDiv = document.getElementsByTagName("div");
function fun(){
alert(this.id);
}
oDiv[0].addEventListener("click",fun,false);
oDiv[1].addEventListener("click",fun,false);
oDiv[2].addEventListener("click",fun,false);
<div style="padding: 30px;background:teal" id="box1">
<div style="padding: 30px;background:tan" id="box2">
<div style="padding: 30px;background:pink;position: absolute;top:300px" id="box3" ></div>
</div>
</div>
-
阻止事件冒泡
-
标准浏览器: event.stopPropagation();
-
ie浏览器:event.cancelBubble = true;
oBtn.onclick = function(ev){ var ev = window.event||ev; //兼容 ev.stopPropagation ? ev.stopPropagation():ev.cancelBubble = true; console.log("点击按钮"); } oDiv.onclick = function(){ console.log("点击div"); }
2.2.4阻止事件默认行为
-
默认行为:标签,浏览器自带的默认的操作
- a的默认跳转、双击默认选中文字、拖拽图片默认保存、submit默认提交、右击默认显示菜单等
-
阻止默认行为:
添加事件的方式 阻止默认行为 标签.事件 return false 标签.addEventListener ev.preventDefault() 标签.attachEvent ev.returnValue = false
2.3 其他事件
2.3.1 键盘事件
- onkeydown:按键按下
- onkeyup:按键抬起
- onkeypress:按键按下
属性值:keycode:获取按键编码
document.onkeydown = function(ev){
var ev = window.event || ev;
console.log(ev.key); //获取到具体的按键信息,ie获取不到undefined
console.log(ev.keyCode);//按键编码不区分大小写,都是大写编码 “0”--48 “A”--65 “a"--97
console.log(ev.shiftKey,ev.ctrlKey,ev.altKey);//按了--true 没按--false
//按ctrl+c打印复制
//console.log(ev.keyCode);
if(ev.keyCode == 67 && ev.ctrlKey==true){
console.log("复制");
}
}
2.3.2 滚轮事件
2.4 事件代理(委托)
例:给100000个li添加点击事件,大量的循环会卡顿,性能不好
事件代理原理:把事件添加给父元素(事件冒泡,子元素能触发父元素的事件),当事件发生的时候,通过ev.target找到具体触发事件的子元素去处理事件
特点:提高性能,事件可以发生在未来
实现:
//将事件添加给父元素
oUl.onclick = function(ev){
var ev = window.event || ev;
//当事件发生的时候,可以通过target获取到具体触发事件的子元素
var target = ev.target || ev.srcElement;
//精确的判断 必须是li标签才可以
if(target.nodeName == "LI"){
target.style.background = "red";
}
}
oUl.innerHTML += "<li>11</li>";