事件高级
1.事件基础
1.1事件对象
- 事件处理函数:事件发生时用来处理事件的函数 obtn.onclick = function(){}
- 事件对象:当事件发生的时候,浏览器会将事件相关信息保存在内置全局对象 window.event 当中
- 取值:
- 标准 IE:window.event
- 低版本ff:事件处理函数的第一个参数
- 属性
- event.type:事件类型
- event.clientX/Y:鼠标相对于屏幕的位置
- event.target/srcElement:真正触发事件的对象
- event.altKey, event.shiftKey, event.ctrlKey:功能键 按住-true 没有按-false
document.onclick = function(ev){
// 事件对象
// console.log(window.event);
// console.log(event); // window可以省略
// console.log(e); // 低版本ff,通过事件处理函数的第一个参数
// 兼容
var e = window.event || ev;
console.log(e);
console.log(e.type); // 事件类型 click
console.log(e.clientX, e.clientY); // 鼠标位置 鼠标相对于屏幕的位置
console.log(e.pageX, e.pageY);// 鼠标位置 相对于页面的位置
// console.log(e.target, 11111); // 真正触发事件的对象
// alert(e.srcElement, 2222); // 低版本IE
// console.log(this, 'this'); // document
var target = e.target || e.srcElement;// 真正触发事件的对象
console.log(e.altKey, e.shiftKey, e.ctrlKey); // 功能键 按住-true 没有按-false
}
2.绑定事件
- 标准:标签.addEventListener(type[不加on],fun,是否捕获)
- IE:标签.attachEvent(type, fun)
- 区别
- ie事件类型要加on
- ie没有捕获
- ie绑定的事件倒序执行的
- ie的this指向window
var oBtn = document.querySelector('button');
// 绑定事件
// 标准:标签.addEventListener(type[不加on], fun, 是否捕获)
oBtn.addEventListener('click', fun1);
oBtn.addEventListener('click', fun2);
// IE: 标签.attachEvent(type, fun)
oBtn.attachEvent('onclick', fun1);
oBtn.attachEvent('onclick', fun2);
// 兼容:两个方法之间的兼容,对其中一个做判断,有这个方法就使用,没有用另外一个
if( oBtn.addEventListener ){
// 标准
oBtn.addEventListener('click', fun1);
oBtn.addEventListener('click', fun2);
}else{
// IE
oBtn.attachEvent('onclick', fun1);
oBtn.attachEvent('onclick', fun2);
}
// 绑定事件
function bind(elem, type, fun){// elem-添加事件的元素 type-事件类型 fun-事件处理函数
if( elem.addEventListener ){
// 标准
elem.addEventListener(type, fun);
}else{
// IE
elem.attachEvent('on'+type, fun);
}
}
bind(oBtn, 'click', fun1);
3.取消事件
- 普通:标签.事件 = null
- 标准:标签.removeEventListener(type[不加on], fun)
- IE:标签.detachEvent(type, fun)
// 1.普通的添加事件
oBtn.onclick = function(){
console.log('抽奖');
// 取消事件 标签.事件 = null
oBtn.onclick = null;
}
// 2.事件绑定添加的
bind(oBtn, 'click', chou);
function chou(){
console.log('抽中100块');
// 取消事件
oBtn.onclick = null; // 无效
// 标准:addEventListener() 标签.removeEventListener(type, fun)
// oBtn.removeEventListener('click', chou);
// IE: attachEvent() 标签.detachEvent(type, fun)
// oBtn.detachEvent('onclick', chou);
// 兼容
if(oBtn.removeEventListener){
oBtn.removeEventListener('click', chou);
}else{
oBtn.detachEvent('onclick', chou);
}
}
4.DOM事件流
DOM事件流:事件的发生过程
-
DOM事件流:
- 事件捕获阶段:事件发生时,丛window开始根据结构找触发事件的元素
- 确认目标阶段:确认触发事件的元素
- 事件冒泡阶段:由目标元素开始处理事件,事件完成后,会把事件根据结构依次往外传递,如果父元素有同类型的事件,触发父元素的事件
// addEventListener(type, fun, 是否捕获) // 是否捕获:true:在捕获阶段处理事件,默认false-在冒泡阶段处理事件 var oDiv = document.querySelectorAll('div'); oDiv[0].addEventListener('click', getClass, false); oDiv[1].addEventListener('click', getClass, true); // 表示在捕获阶段处理事件 oDiv[2].addEventListener('click', getClass, false); function getClass(){ alert(this.className) }
-
阻止冒泡
- 标准:e.stopPropagation()
- IE:e.cancelBubble = true
- 兼容:e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
oBtn.onclick = function(ev){ console.log('我是按钮'); // 阻止冒泡 var e = window.event || ev; // e.stopPropagation(); // 标准 // e.cancelBubble = true; // IE // 兼容 e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; } oDiv.onclick = function(){ console.log('我是div'); this.style.background = 'pink'; } document.onclick = function(){ console.log('我是document'); }
5.阻止默认行为
浏览器默认行为
submit默认提交表单
a标签默认跳转
双击默认选中文字
右击默认显示菜单
图片拖拽默认保存
- 普通:return false
- 标准:e.preventDefault()
- IE:e.returnValue = false
- 兼容:e.preventDefault ? e.preventDefault() : e.returnValue = false;
// 标签.事件
oA.onclick = function(){
console.log('哈哈哈哈哈');
// 阻止默认行为
return false;
}
bind(oA, 'click', function(ev){
console.log('今天周一');
// 阻止默认行为
// return false;
var e = window.event || ev;
// e.preventDefault(); // 标准
// e.returnValue = false;
// 兼容
e.preventDefault ? e.preventDefault() : e.returnValue = false;
});
6.键盘事件
-
onkeydown: 键盘按键按下
-
onkeypress: 键盘按键按下
keyCode区分大小写,组合按键有问题
-
onkeyup: 键盘按键抬起
var text = document.querySelector('textarea');
// 按键按下
text.onkeydown = function(ev){
var e = window.event || ev;
console.log(e);
console.log(e.key); // 具体的按键 a A区分大小写
console.log(e.keyCode); // 按键的编码 不区分大小写 大写的编码 aA-65
console.log(e.altKey,e.ctrlKey, e.shiftKey); // 功能键
// ctrl+c 进行复制
if(e.ctrlKey==true && e.keyCode == 67){
console.log('复制');
}
// 回车-13 左-37 上-38 右-39 下-40
}
// 按键按下
text.onkeypress = function(ev){
var e = window.event || ev;
console.log(e);
console.log(e.key); // 具体的按键 a A区分大小写
console.log(e.keyCode); // 按键的编码 区分大小写 大写的编码 A-65 A-97
console.log(e.altKey,e.ctrlKey, e.shiftKey); // 功能键
// 组合键有问题
if(e.ctrlKey==true && e.keyCode == 67){
console.log('复制');
}
// 回车-13 左-37 上-38 右-39 下-40
}
// 按键抬起
text.onkeyup = function(ev){
var e = window.event || ev;
console.log(e);
console.log(e.key); // 具体的按键 a A区分大小写
console.log(e.keyCode); // 按键的编码 不区分大小写 大写的编码 aA-65
console.log(e.altKey,e.ctrlKey, e.shiftKey); // 功能键
// ctrl+c 进行复制 组合键正常
if(e.ctrlKey==true && e.keyCode == 67){
console.log('复制');
}
// 回车-13 左-37 上-38 右-39 下-40
}
7.事件委托
- 事件委托(代理):把事件添加给父元素代为处理,事件发生时让父元素找到具体的子元素处理事件
- 优点:提高渲染性能,事件可以发生在未来,后期添加也有事件
- 原理:事件冒泡
// 添加点击事件
/* for(var i = 0; i<oLi.length; i++){
oLi[i].onclick = function(){
console.log('被点击了');
this.style.background = 'pink';
}
} */
oUl.onclick = function(){
console.log('被点击了');
// console.log(this);
// this.style.background = 'pink';
// 获取真正触发事件的元素
var target = event.target || event.srcElement;
console.log(target);
// 精准判断 只有是li
if(target.nodeName == 'LI'){
// 是li标签
target.style.background = 'pink';
}
}
// 问题:后期添加的标签没有事件
oUl.innerHTML += '<li>哈哈哈哈哈</li>';
8.滚轮事件
-
添加滚动事件:
- chrome IE:标签.onmousewheel = function() ff添加不上,不会报错
- ff:通过事件绑定 标签.addEventListener(“DOMMouseScroll”, fun)
-
滚动方向:
- ev.wheelDelta:上 120 下 -120
- ev.detail 上 -3 下 3
// 添加滚轮事件
function wheel(elem, upFun, downFun) {// upFun, downFun :是函数,把函数作为参数传入
// 添加滚轮事件
// 标准、IE: onmousewheel
elem.onmousewheel = scroll;
// ff:通过事件绑定添加
if (elem.addEventListener) {
elem.addEventListener('DOMMouseScroll', scroll);
}
function scroll(ev) {
console.log('滚动');
var e = window.event || ev;
// console.log(e);
// console.log(e.wheelDelta); //标准 IE: 上120 下-120
// console.log(e.detail); //ff: 上-3 下3
var tag; // true-上 fasel-下
if (e.wheelDelta) {
// 标准 IE: 上120 下-120
tag = e.wheelDelta > 0 ? true : false;
} else {
// ff: 上-3 下3
tag = e.detail < 0 ? true : false;
}
// 最后根据tag值做不同的处理
if (tag) {
// 上
upFun(); // upFun = function up(){console.log('往上进行放大'); }
} else {
// 下
downFun();//
}
}
}
wheel(oDiv, up, down); // 把函数作为参数传入
function up(){
console.log('往上进行放大');
}
function down(){
console.log('往下进行缩小');
}