1.注册事件
1.1 传统注册事件
以on开头, onclick,具有唯一性,同一个元素,同一个事件只能设置一个处理函数,后注册的处理函数会覆盖前面注册的处理函数
<body>
<button>点击</button>
<script>
var btn = document.querySelector('button');
//被覆盖
btn.onclick = function () {
alert(1);
};
btn.onclick = function () {
alert('ggg');//ggg
}
</script>
</body>
1.2 方法监听注册方式 addEventListener()
W3C推荐,IE9之前不支持,用addEvent()代替,同一元素,同一事件可以注册多个监听器,按照注册顺序依次执行
eventTarget.addEventListener(type,listener[, useCapture])
1.type 事件类型字符串,比如click,mouseover,注意不带on
2.listener 事件处理函数,事件发生时,会调用该监听函数
3.useCapture 可选参数,布尔值,默认false
<body>
<button>点击</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function () {
alert('ggxjsb');
})
btn.addEventListener('click', function () {
alert('ggxededjsb');
})
</script>
</body>
1.3 addEvent事件监听(非标准,不推荐,IE8支持)
eventTarget.attachEvent(eventNameWithOn,callback)
1.eventNameWithOn:事件类型字符串,比如onclick,onmouseover,
2.callback:事件处理函数
<body>
<button>点击</button>
<script>
var btn = document.querySelector('button');
btn.attachEvent('onclick', function () {
alert('hvn');
})
</script>
</body>
2.删除事件
2.1 删除事件的方式
传统注册方式
eventTarget.onclick=null
<body>
<button>点击</button>
<script>
var btn = document.querySelector('button');
btn.onclick = function () {
alert('jio');
//解绑事件
btn.onclick = null;
}
</script>
</body>
方法监听注册方式(注意回调函数单独写)
eventTarget.removeEventListener(type,listener[, useCapture])
<body>
<button>点击</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', fn);
function fn() {
alert('jzioan');
btn.removeEventListener('click', fn)
}
</script>
</body>
3.DOM事件流
事件流描述的时从页面中接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程就是DOM事件流
DOM事件流分为三个阶段
(1)捕获阶段
(2)当前目标阶段
(3)冒泡阶段
事件冒泡:IE最早提出,时间开始时有最具体的元素接收,然后主机向上传播到DOM最顶层节点的规程
事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到最具体元素接收的过程
注意
(1)JS代码中只能执行捕获或者冒泡其中的一个阶段
(2)onclick和attachEvent只能得到冒泡阶段
(3)addEventListener(type,listener[,useCapture]) 第三个参数是true,表示在事件捕获阶段斯调用事件处理程序,如果是false,表示事件冒泡阶段调用事件处理程序
(4)实际开发中更关注事件冒泡
(5)有些事件没有冒泡,onblur,onfocus,onmouseenter,onmouseleave
代码验证
<style>
.father {
width: 600px;
height: 600px;
background-color: green;
}
.son {
width: 400px;
height: 400px;
background-color: orange;
}
.a {
width: 200px;
height: 200px;
background-color: grey;
}
</style>
<body>
<div class="father">
father
<div class="son">
son
<div class="a">a</div>
</div>
</div>
<script>
// 事件捕获阶段,从高层向底层,document -> html -> body -> father -> son -> a
// 以下代码点击之后的弹出顺序:.father ->.son -> a
var father = document.querySelector('.father');
var son = document.querySelector('.son');
var a = document.querySelector('.a');
a.addEventListener('click', function () {
alert('a');
}, true);
son.addEventListener('click', function () {
alert('.son');
}, true);
father.addEventListener('click', function () {
alert('.father');
}, true);
// 事件冒泡阶段,从底层到高层,a -> son -> father -> body -> html -> document
// 以下代码弹出顺序 a ->.son ->.father
var father = document.querySelector('.father');
var son = document.querySelector('.son');
var a = document.querySelector('.a');
a.addEventListener('click', function () {
alert('a');
}, false);
son.addEventListener('click', function () {
alert('.son');
}, false);
father.addEventListener('click', function () {
alert('.father');
}, false);
</script>
</body>
4.事件对象
4.1 什么是事件对象
//1.event就是一个事件对象,写在侦听函数的小括号里,当形参看待
//2.事件对象有了事件才会存在,他是系统自动创建的,不需要传参
//3.事件对象是时间的一系列相关数据的集合
//4.事件对象可以自己命名,例如 function(e)
//5.事件对象有兼容性问题,ie678用window.event
//6.其中有很多属性和方法
<body>
<div>123</div>
<script>
var div = document.querySelector('div');
div.onmouseover = function (event) {
console.log(event);
}
//1.event就是一个事件对象,写在侦听函数的小括号里,当形参看待
//2.事件对象有了时间才会存在,他是系统自动创建的,不需要传参
//3.事件对象是时间的一系列相关数据的集合
//4.事件对象可以自己命名,例如 function(e)
//5.事件对象有兼容性问题,ie678用window.event
</script>
</body>
4.2 事件对象常见属性和方法
方法 | 说明 |
e.target | 返回触发事件的对象,标准 |
e.srcElement | 返回触发事件的对象,非标准,ie678 用 |
e.type | 返回事件类型,比如click,mouseover |
e.cancelBubble | 阻止冒泡,ie6-8用 |
e.returnValue | 阻值默认事件,比如不让连接跳转,ie6-8用 |
e.preventDefault() | 阻止默认事件,标准 |
e.stopPropagation() | 阻止冒泡,标准 |
4.2.1 返回触发事件的对象
区分e.target和this
<body>
<div>123</div>
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
<script>
var div = document.querySelector('div');
//注意:e.target返回的是触发事件的对象,this返回的是绑定事件的对象
div.onclick = function (e) {
console.log(e.target);//<div>123</div>
console.log(this);//<div>123</div>
}
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
//在这里,ul绑定了事件,因此,this指向ul
console.log(this);// <ul></ul>
//点击li,是li触发了事件,e.target就返回li
console.log(e.target)//<li></li>
//e.currentTarget与this相似
console.log(e.currentTarget);//<ul></ul>
})
</script>
</body>
4.2.2 获取事件类型和阻止默认行为
<body>
<div>124</div>
<a href="http://www.baidu.com">百度</a>
<form action="http://www.baidu.com">
<input type="submit" value="提交" name="sub">
</form>
<script>
var div = document.querySelector('div');
div.addEventListener('click', fn);
function fn(e) {
console.log(e.type)//click
}
//阻止默认行为
var a = document.querySelector('a');
a.addEventListener('click', function (e) {
e.preventDefault();
})
//传统方式
a.onclick = function (e) {
//普通浏览器
e.preventDefault();
//低版本浏览器ie6-8
e.returnValue;
//return false也能阻止默认行为,没有兼容性问题,但是后面的代码也不执行,也仅限于传统方式
return false;
}
</script>
</body>
4.2.3 阻止冒泡
结果只弹出a->son
<body>
<div class="father">
<div class="son">
<div class="a"></div>
</div>
</div>
<script>
var father = document.querySelector('.father');
var son = document.querySelector('.son');
var a = document.querySelector('.a');
father.addEventListener('click', function () {
alert('father');
});
son.addEventListener('click', function () {
alert('son');
})
a.addEventListener('click', function (e) {
alert('a')
//阻止冒泡,想阻止谁就给谁加
e.stopPropagation();
});
</script>
</body>
5.事件委托(代理,委托)
原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
<body>
<ul>
<li>点我事件代理</li>
<li>点我事件代理</li>
<li>点我事件代理</li>
<li>点我事件代理</li>
<li>点我事件代理</li>
<li>点我事件代理</li>
</ul>
<script>
//事件代理核心:给父节点添加侦听器,利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
alert('点我事件代理')
//e.target可以获得当前点击的对象
for (var i = 0; i < ul.children.length; i++) {
ul.children[i].style.backgroundColor = '';
}
e.target.style.backgroundColor = 'green'
})
</script>
</body>
6.常用鼠标事件
事件 | 触发条件 |
onclick | 鼠标左键点击 |
onmouseover | 鼠标经过离开 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点 |
onblur | 失去鼠标焦点 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
6.1禁止鼠标右键菜单,主要控制应该合适显示上下文菜单,用于取消程序默认的上下文菜单
contextmenu
6.2 禁止鼠标选中
selectstart
<body>
不能复制这句话
<script>
//contextmenu禁止右键
document.addEventListener('contextmenu', function (e) {
e.preventDefault()
});
document.addEventListener('selectstart', function (e) {
e.preventDefault()
})
</script>
</body>
6.3鼠标事件对象
event对象代表事件的状态,跟事件相关的一系列信息的集合,目前主要用到MouseEvent和KeyboardEvent
鼠标事件对象 | 说明 |
e.clientY | 返回鼠标相对于窗口可视区的X坐标 |
e.clientY | 返回鼠标相对于窗口可视区的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标,ie9支持 |
e.pageY | 返回鼠标相对于文档页面的Y坐标,ie9支持 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
<body>
<script>
document.addEventListener('mousemove', function (e) {
console.log(e);
//1.Client鼠标在可视区的X和Y坐标
console.log(e.clientX);
console.log(e.clientY);
//2.page鼠标在页面文档的X和Y坐标
console.log(e.pageX);
console.log(e.pageY);
})
</script>
</body>
鼠标跟随案例
<body>
<img src="https://img1.baidu.com/it/u=10729751,2293405087&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500" alt="">
<script>
var pic = document.querySelector('img')
document.addEventListener('mousemove', function (e) {
//获取鼠标坐标
var x = e.pageX;
var y = e.pageY;
//将鼠标的坐标赋值给图片,这里一定记得加px
pic.style.left = x - 75 + 'px';
pic.style.top = y - 75 + 'px';
})
</script>
</body>
7.常用键盘事件
事件 | 说明 |
onkeyup | 键盘按键松开时触发 |
onkeydown | 键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发,不识别功能键 |
<body>
<script>
document.onkeyup = function () {
alert('键盘弹起')
}
document.addEventListener('keydown', function () {
alert('按下键盘')
})
document.addEventListener('keypress', function () {
alert('按下键')
})
</script>
</body>
事件执行顺序:keydown-->keypress-->keyup
keyCode判断按下哪个键,返回ASCII码
keyup和keydown事件不区分字母大小写,a和A获得的都是65
keypress区分大小写
<body>
<script>
document.addEventListener('keyup', function (e) {
console.log(e);
//获取按下的键的ASCII码
console.log(e.keyCode);//68
})
document.addEventListener('keypress', function (e) {
console.log(e);
console.log(e.keyCode);
})
</script>
</body>
8.模仿京东按键输入内容案例
//检测用户是否按下了s键,如果按下,就把光标定位到搜索框里面,使用keyCode判断用户按下的是否是s键,使用js的focus()方法获得搜索框的焦点
<body>
<input type="text">
<script>
var search = document.querySelector('input');
//若用keydown,还会将s键输入内容框
document.addEventListener('keyup', function (e) {
if (e.keyCode === 83) {
search.focus();
}
})
</script>
</body>