持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情
就是当你触发了一个事件以后,对该事件的一些描述信息
例如:
- 你触发一个点击事件的时候,你点在哪个位置了,坐标是多少
- 你触发一个键盘事件的时候,你按的是哪个按钮
• 每一个事件都会有一个对应的对象来描述这些信息,我们就把这个对象叫做 事件对象
• 浏览器给了个 window.event ,就是对事件信息的所有描述
• 我们就得用另一种方式来获取 事件对象,在每一个事件处理函数的行参位置,默认第一个就是 事件对象
事件对象
1.什么是事件对象
任何事件触发后将会产生一个事件对象,跟事件相关的一系列信息数据的集合都放到这个对象里面。比如: ①谁绑定了这个事件。 ②如果是鼠标触发事件,会得到鼠标的相关信息,如鼠标位置。(对应的事件对象叫鼠标事件对象) ③如果是键盘触发事件,会得到键盘的相关信息,如按了哪个键。(对应的事件对象叫键盘事件对象)
2.事件对象的获取
事件触发时就会产生一个事件对象,系统会以实参的形式将这个事件对象传给事件处理函数。 所以,在事件处理函数中需要声明一个形参用来接收事件对象。
var btn2 = document.getElementById('btnId2');
btn2.onclick = function(event) { //这个event就是事件对象,也经常写成e或evt。
alert('捉老鼠二号');
}
var btn4 = document.getElementById('btnId4');
btn4.addEventListener('click', function(event) { //这个event就是事件对象,也经常写成e或evt。
alert('捉老鼠四号');
})
btn4.addEventListener('click', catchFunc);
function catchFunc(event) { //这个event就是事件对象,也经常写成e或evt。
alert('捉老鼠');
}
事件对象的获取存在的兼容问题:
a.标准浏览器中是浏览器给方法传递的参数,只需要定义形参 e 就可以获取到。
标准浏览器泛指对W3C所定义的CSS2.1规范提供了优秀支持并能完美呈现的浏览器。
目前的标准浏览器包括:Opera 10.10、Safari 4.0.4、Intelnet Explorer 9、Firefox 3、Chrome。
您也可以对自己的浏览器进行验证,方法如下:
在浏览器的地址栏中复制以下地址 http://www.webstandards.org/files/acid2/test.html#top,
若能看到一张笑脸,则您的浏览器是标准浏览器。
b.在 IE6~8 中,浏览器不会给方法传递参数,我们需要通过 window.event 获取。
注意,对于标准浏览器, window.event也能获取到事件对象。
兼容问题的解决方案:
<div style="height: 25px;width: 300px;background-color: pink;">我是一个div</div>
<script>
var div = document.querySelector('div');
div.onclick = function(e) {
//只要“||”前面为false, 不管“||”后面是true 还是 false,都返回 “||” 后面的值。
//只要“||”前面为true, 不管“||”后面是true 还是 false,都返回 “||” 前面的值。
e = e || window.event; // 事件对象
console.log(e);
}
</script>
3.事件对象的属性和方法
| 属性和方法 | 说明 |
|---|---|
| e.target | 返回事件源(标准浏览器) |
| e.srcElement | 返回事件源(非标准浏览器,在 IE6~8 中) |
| e.type | 返回事件类型 |
| e.stopPropagation() | 阻止事件冒泡(标准浏览器) |
| e.cancelBubble | 阻止事件冒泡(非标准浏览器,在 IE6~8 中,true) |
| e.preventDefault() | 阻止默认事件(标准浏览器) 默认事件==默认行为,比如不让链接跳转。 |
| e.returnValue | 阻止默认事件(非标准浏览器,在 IE6~8 中,false) 默认事件==默认行为,比如不让链接跳转。 |
1.e.target 和 this 的区别
1.e.target 是事件触发的元素,即事件源。this 是事件绑定的元素(绑定这个事件处理函数的元素) 。一般情况下二 者是一致的。
<div style="height: 25px;width: 300px;background-color: pink;">我是一个div</div>
<script>
var div = document.querySelector('div');
div.onclick = function(e) {
e = e || window.event; // 事件对象
console.log(e.target); //div元素
console.log(this); //div元素
}
</script>
2.在事件冒泡时(父子元素有相同事件,单击子元素,父元素的事件处理函数也会被触发执行),二者不一致。 这时候e.target指向的是子元素,因为他是触发事件的那个具体元素对象。 这时候this指向的是父元素,因为它是绑定事件的元素对象。
<div style="height: 25px;width: 300px;background-color: pink;">我是一个div
<button type="button">我是一个button</button>
</div>
<script>
var div = document.querySelector('div');
div.onclick = function(e) {
e = e || window.event; // 事件对象
console.log(e.target); //button元素
console.log(this); //div元素
}
</script>
2.阻止事件冒泡
<div class="father">大盒子
<div class="son">小盒子</div>
</div>
<script>
var son = document.querySelector('.son');
son.onclick = function(e) {
alert('您点击了小盒子');
// 1.以下这种写法对标准浏览器起作用
//e.stopPropagation(); //阻止事件冒泡(标准浏览器)
// 2.以下这种写法对非标准浏览器起作用
//window.event.cancelBubble = true; //阻止事件冒泡(非标准浏览器,在 IE6~8 中)
/* 3.阻止事件冒泡的兼容性处理 */
if (e && e.stopPropagation) {
e.stopPropagation(); //阻止事件冒泡(标准浏览器)
} else {
window.event.cancelBubble = true;//阻止事件冒泡(非标准浏览器,在 IE6~8 中)
}
// 4.注意以下这种写法不能阻止事件冒泡。
// return false;
/* 5.测试发现以下两种写法对标准浏览器也起作用 */
//e.cancelBubble = true;
//window.event.cancelBubble = true; //阻止事件冒泡(非标准浏览器,在 IE6~8 中)
// 6.测试发现以下这种写法对非标准浏览器不起作用,运行到这一行报错了。
e.stopPropagation(); //阻止事件冒泡(标准浏览器)
}
var father = document.querySelector('.father');
father.onclick = function() {
alert('您点击了大盒子');
}
</script>
3.阻止默认行为
1.HTML中一些标签有默认行为,例如a标签被单击后,默认会进行页面跳转。
<a href="http://www.baidu.com">百度</a>
<script>
var a = document.querySelector('a');
a.onclick = function(e) {
// 1.以下这种写法对标准浏览器起作用
// e.preventDefault(); //阻止默认事件(标准浏览器)
// 2.以下这种写法对非标准浏览器起作用
// window.event.returnValue = false; //阻止默认事件(非标准浏览器,在 IE6~8 中,false)
/* 3.阻止默认行为的兼容性处理 */
// if (e && e.preventDefault) {
// e.preventDefault(); //阻止默认事件(标准浏览器)
// } else {
// window.event.returnValue = false;//阻止默认事件(非标准浏览器,在 IE6~8 中,false)
// }
// 4.以下这种写法也能阻止默认行为,且没有兼容性问题。
return false;
/* 5.测试发现以下两种写法对除IE以外的标准浏览器也起作用 */
// e.returnValue = false;
// window.event.returnValue = false; //阻止默认事件(非标准浏览器,在 IE6~8 中,false)
// 6.测试发现以下这种写法对非标准浏览器不起作用。
// e.preventDefault(); //阻止默认事件(标准浏览器)
}
</script>
2.网页中的鼠标的一些默认行为,例如鼠标右键菜单、鼠标选中。
<h1>1.本网页禁用了鼠标右键菜单</h1>
<h1>2.本网页禁止了鼠标选中文字</h1>
<script>
/* 1.oncontextmenu 主要控制何时显示上下文菜单,主要用于程序员取消默认的上下文菜单。 */
document.oncontextmenu = function(e) {
// 1.以下这种写法对标准浏览器起作用
// e.preventDefault(); //阻止默认事件(标准浏览器)
// 2.以下这种写法对非标准浏览器起作用
// window.event.returnValue = false; //阻止默认事件(非标准浏览器,在 IE6~8 中,false)
/* 3.阻止默认行为的兼容性处理 */
// if (e && e.preventDefault) {
// e.preventDefault(); //阻止默认事件(标准浏览器)
// } else {
// window.event.returnValue = false; //阻止默认事件(非标准浏览器,在IE6~8中false)
// }
// 4.以下这种写法也能阻止默认行为,且没有兼容性问题。
return false;
/* 5.测试发现以下两种写法对除IE以外的标准浏览器也起作用 */
// e.returnValue = false;
// window.event.returnValue = false; //阻止默认事件(非标准浏览器,在 IE6~8 中,false)
// 6.测试发现以下这种写法对非标准浏览器不起作用,运行到这一行报错了。
// e.preventDefault(); //阻止默认事件(标准浏览器)
}
/* 2.onselectstart 触发时间为目标对象被开始选中时(即选中动作刚开始,尚未实质性被选中)。 */
document.onselectstart = function(e) {
// 1.以下这种写法对标准浏览器起作用
// e.preventDefault(); //阻止默认事件(标准浏览器)
// 2.以下这种写法对非标准浏览器起作用
// window.event.returnValue = false; //阻止默认事件(非标准浏览器,在 IE6~8 中,false)
/* 3.阻止默认行为的兼容性处理 */
// if (e && e.preventDefault) {
// e.preventDefault(); //阻止默认事件(标准浏览器)
// } else {
// window.event.returnValue = false; //阻止默认事件(非标准浏览器,在IE6~8中false)
// }
// 4.以下这种写法也能阻止默认行为,且没有兼容性问题。
return false;
/* 5.测试发现以下两种写法对除IE以外的标准浏览器也起作用 */
// e.returnValue = false;
// window.event.returnValue = false; //阻止默认事件(非标准浏览器,在 IE6~8 中,false)
// 6.测试发现以下这行对非标准浏览器也起作用(与上面oncontextmenu情况相反),运行到这一行报错了。
// e.preventDefault(); //阻止默认事件(标准浏览器)
}
</script>
3.网页中禁止通过F12按键打开开发者工具(注意,仍然可以通过鼠标点击的相应菜单的操作来打开)
document.onkeydown = function(e) {
var currKey = 0,e = e || window.event;
//获取按下的按键,兼容性的写法,不同的浏览器有不同的支持。有些浏览器不支持e.keyCode,则用e.which。
currKey = e.keyCode || e.which || e.charCode;
console.log(currKey);//按下F12之后,将获取到123(F12键的ASCII码值)。
//HbuilderX内置浏览器:123-谷歌:123-火狐:123-Edg:123-IE11:123-IE8:123
console.log(e.keyCode);
//HbuilderX内置浏览器:123-谷歌:123-火狐:123-Edg:123-IE11:123-IE8:undefined
console.log(e.which);
//HbuilderX内置浏览器:0---谷歌:0---火狐:0---Edg:0---IE11:0---IE8:undefined
console.log(e.charCode);
if (currKey == 123) {
window.event.cancelBubble = true; //阻止事件冒泡(非标准浏览器,在 IE6~8 中)
window.event.returnValue = false; //阻止默认事件(非标准浏览器,在 IE6~8 中,false)
//e.stopPropagation();
//e.preventDefault();
}
}
4.鼠标事件对象的属性
以下列举了鼠标事件对象中,获取鼠标在页面的坐标的相关属性。
| 鼠标事件对象属性 | 说明 |
|---|---|
| e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
| e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
| e.pageX | 返回鼠标相对于文档页面的X坐标(IE9+支持) |
| e.pageY | 返回鼠标相对于文档页面的Y坐标(IE9+支持) |
| e.ScreenX | 返回鼠标相对于电脑屏幕的X坐标 |
| e.ScreenY | 返回鼠标相对于电脑屏幕的Y坐标 |
1.通过事件对象获取鼠标的坐标
document.onclick = function(e) { //e此时是事件对象的细类——鼠标事件对象
e = e || window.event;
console.log('1.鼠标在浏览器窗口可视区的x和y坐标:');
console.log(e.clientX);
console.log(e.clientY);
console.log('2.鼠标在文档页面的x和y坐标:');
console.log(e.pageX); //IE9+支持
console.log(e.pageY); //IE9+支持
console.log('3.鼠标在电脑屏幕的x和y坐标:');
console.log(e.screenX);
console.log(e.screenY);
}
注:IE9+表示IE9及其以上。
2.跟随鼠标案例
<style>
img {
position: absolute;
top: 3px;
}
</style>
<img src="img/bee.gif" alt="">
<script>
var img = document.querySelector('img');
/* onmousemove:鼠标移动触发,只要鼠标移动1px,就会触发该事件。*/
document.onmousemove = function(e) {
/* 1.获取最新的鼠标坐标 */
var x = e.clientX;
var y = e.clientY;
console.log('x坐标是' + x, 'y坐标是' + y);
/* 2.根据鼠标坐标设置图片的位置 */
img.style.left = x - 20 + 'px';
img.style.top = y - 30 + 'px';
}
</script>
5.键盘事件对象的属性
以下列举了键盘事件对象中,获取按键的相关属性。
| 键盘事件对象属性 | 说明 |
|---|---|
| keyCode | 返回按键的ASCII码值 |
1.通过事件对象获取用户按下的按键
<script>
/* 利用keycode返回的ASCII码值来判断用户按下了那个键 */
document.onkeyup = function(e) {
console.log('onkeyup:' + e.keyCode); //不区分大小写字母,返回大写字母的ASCII码值。
}
document.onkeypress = function(e) {
console.log('onkeypress:' + e.keyCode); //区分大小写字母,返回大小写字母的ASCII码值。
}
document.onkeydown = function(e) {
console.log('onkeydown:' + e.keyCode); //不区分大小写字母,返回大写字母的ASCII码值。
}
</script>
2.搜索框获得鼠标焦点案例
<input type="text">
<button type="button">搜索</button>
<script>
var input = document.querySelector('input');
document.onkeyup = function(e) {
console.log(e.keyCode);
if (e.keyCode === 81) { //Q键
input.focus(); // 触发输入框的获得焦点事件
} else if (e.keyCode === 27) { //Esc键
input.blur(); // 触发输入框的失去焦点事件
}
}
</script>
事件委托
1.什么是事件委托
事件委托就是把事情委托给别人,代为处理。 事件委托说白了就是,不给子元素注册事件,给父元素注册事件,把处理代码在父元素的事件中执行。 事件委托是事件冒泡本身的特性,会带来的坏处,也会带来的好处。 事件委托也称为事件代理,在JQuery 里面称为事件委派。
举个简单的例子:
事件代理’就是把原本需要绑定的事件委托给父元素,让父元素负责事件监听。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能
多个事件同时发生,有两种方法,一种是每个人同时执行不同的事情,另一种是将所有的事情分配给他的父元素,委托给父级去办事
2.事件委托的作用
使用事件委托可以节约工作量并提高程序的性能。 比如一个ul下有多个li,现要求点击每个li都弹出对话框, 以前需要给每个li注册事件,相应地就要多次访问DOM,就会延长整个页面的交互就绪时间。 现在我们只要给ul注册事件,从而只需要操作一次 DOM ,这样就大大提高了程序的性能。
3.事件委托的使用
给父元素注册事件,利用事件冒泡,当子元素的事件触发,会冒泡到父元素,然后去控制相应的子元素。 具体如何去控制子元素呢,我们只要使用 e.target,就可以获取到事件源(比如点击的那个子元素),从而就可以对这个子元素进行操作了。
<ul>
<li>第一个列表项</li>
<li>第二个列表项</li>
<li>第三个列表项</li>
<li>第四个列表项</li>
<li>第五个列表项</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
e.target.style.backgroundColor = 'green';
})
</script>