事件进阶
一、事件进阶
1、注册事件(又称为事件的绑定)
在JavaScript中,注册事件(绑定事件)有两种方式,即传统方式注册事件和事件监听方式注册事件。
(1)传统方式:对象.事件名 = 事件处理程序
btn.onclick = function() { }
优点:同一个对象的同一个事件只能注册一个处理程序,后面注册的程序会将前面注册的程序覆盖掉(唯一性)
(2)事件监听方式
由于不同浏览器采用的事件流实现方式不同,事件监听的实现存在兼容性问题。通常根据浏览器的内核,可以把浏览器划分为两大类,一类是早期版本的IE浏览器(如IE 6~IE 8),一类是遵循W3C标准的浏览器(以下简称标准浏览器)
该方式注册事件的特点在于可以给同一个DOM对象的同一个事件添加多个事件处理程序
①早期浏览器的事件监听方式如下
dom对象.attachEvent(type,callback)
type参数:表示事件的类型,如click、change、foucs等
callback参数:是回调函数,表示事件处理程序
②标椎浏览器包括IE8版本以上的IE浏览器,以及新版的Firefox、Chrome等浏览器,事件监听方式如下
dom对象.addEventListener(type,callback,[capture])
type参数:表示事件的类型,如click、change、foucs等
callback参数:是回调函数,表示事件处理程序
capture参数:可选参数,用来指定事件处理的方式;true表示事件在捕获阶段处理;false表明在冒泡阶段处理
2、删除事件,事件监听的移除也需要考虑兼容性问题
dom对象.事件名 = null
dom对象.detachEvent(type, callback); -->早期浏览器版本的删除
dom对象.removeEventListener(type,callback) -->标准浏览器的删除
3、DOM事件流
事件流是指当事件发生时,会在发生事件的元素节点与DOM树根节点之间按照特定的顺序进行传播,这个过程称之为事件流
- a、网景:采用事件捕获方式
- b、微软:采用事件冒泡方式
- c、w3c:先捕获,后冒泡
W3C规定的事件流的具体过程对比如下图所示
二、事件对象
1、什么是事件对象:当一个事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是event。只有有了事件event才会存在,它是系统自动创建的,不需要传递参数
2、事件对象的使用
在标准浏览器中会将一个event对象直接传入到事件处理程序中,而早期版本的IE浏览器(IE 6~IE 8)中,仅能通过window.event才能获取事件对象
var 事件对象 = window.event // 早期IE内核浏览器
DOM对象.事件 = function (event) {} // W3C内核浏览器
注意:因为在事件触发时就会产生事件对象,并且系统会以实参的形式传给事件处理函数。所以,在事件处理函数中需要用一个形参来接收事件对象event
<button id="btn">获取event对象</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function(e) {
var event = e || window.event; // 获取事件对象的兼容处理
console.log(event);
};
</script>
3、事件对象的常见属性和方法
在事件发生后,事件对象event中会包含一些所有事件都有的属性和方法。所有事件基本上都包括的常用的属性和方法如下表所示
注:表中的type属性是标准浏览器和早期版本IE浏览器的事件对象的公有属性,通过该属性可以获取发生事件的类型,如click、mouseover等(不带on)
4、对比e.target和this的区别
在事件处理函数中,e.target返回的是触发事件的对象,而this返回的是绑定事件的对象。因为e.target支持IE9以上,所以编写以下代码,处理兼容性问题
div.onclick = function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
console.log(target);
}
5、阻止默认行为
在实际开发中,为了使程序更加严谨,想要确定含有默认行为的标签符合要求后,才能执行默认行为时,可利用事件对象的preventDefault()方法和returnValue属性,禁止所有浏览器执行元素的默认行为。需要注意的是,只有事件对象的cancelable属性设置为true,才可以使用preventDefault()方法取消其默认行为
<body>
<a href="http://www.4399.com">4399</a>
<script>
//获取超链接标签
var a1 = document.querySelector('a')
//注册click事件,阻止a标签的默认事件
// a1.addEventListener('click',function(e){
// e.preventDefault()
// })
//早期浏览器写法(推荐使用)
a1.onclick = function(e){
e.preventDefault()
e.returnValue
}
</script>
</body>
6、阻止事件冒泡
可以利用事件对象调用stopPropagation()方法和设置cancelBubble属性,实现禁止所有浏览器的事件冒泡行为
if (window.event) { // 早期版本的浏览器
window.event.cancelBubble = true;
} else { // 标准浏览器
e.stopPropagation();
}
7、事件委托:不给子元素注册事件,而是给父元素注册事件。事件处理代码在父元素的事件中执行,优点是只操作一次DOM,可以提高程序的性能
<body>
<ul>
<li>西安邮电大学</li>
<li>西安理工大学</li>
<li>西安科技大学</li>
<li>西安建筑大学</li>
<li>西安石油大学</li>
</ul>
<script>
var ul1 = document.querySelector('ul')
ul1.addEventListener('click',function(e){
e.target.style.backgroundColor = 'orange'
})
</script>
</body>
三、鼠标事件
1、鼠标事件的常用方法
鼠标是计算机的一种输入设备,也是计算机显示系统纵横坐标定位的指示器,所以鼠标事件是Web开发中最常用的一类事件。常见的鼠标事件如下表所示
2、禁止鼠标右击菜单
contextmenu主要控制应该何时显示上下文菜单,主要应用于程序员取消默认的上下文菜单
document.addEventListener('selectstart', function (e) {
e.preventDefault();
})
3、禁止鼠标选中
selectstart事件是鼠标开始选择文字时就会触发,如果禁止鼠标选中,需要禁止该事件的默认行为
document.addEventListener('selectstart',function(e){
e.preventDefault()
})
4、鼠标事件对象
鼠标事件对象MouseEvent,是跟鼠标事件相关的一系列信息的集合,可以用来获取当前鼠标的位置信息,鼠标事件位置属性如下表所示
IE 6~IE 8浏览器中不兼容pageX和pageY属性,在项目开发时需要对IE 6~IE 8浏览器进行兼容处理,示例代码如下所示
var pageX = event.pageX || event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft)
var pageY = event.pageY || event.clientY + (document.body.scrollTop || document.documentElement.scrollTop)
案例1:图片跟随鼠标移动
案例分析:需要使用鼠标指针移动事件mousemove,每次鼠标移动,都会获得最新的鼠标指针坐标,把这个x和y坐标作为图片的top和left 值就可以实现图片的移动
<style>
img {
position: absolute;
top: 2px;
}
</style>
<body>
<img src="../image/1.jfif">
<script>
var pic = document.querySelector('img')
document.addEventListener('mousemove',function(e){
var x = e.pageX
var y = e.pageY
pic.style.left = x - 50 + 'px'
pic.style.top = y + 'px'
})
</script>
</body>
案例2:鼠标移动的同时显示坐标
<style>
div{
position: absolute; /*必须的,绝对定位 */
width: 100px;
height: 30px;
display: block;
}
</style>
<body>
<div></div>
<script>
var div = document.querySelector('div')
document.addEventListener('mousemove',function(e) {
var x = e.pageX
var y = e.pageY
div.style.left = x-50+'px'
div.style.top = y-40+'px'
var str= '(x:'+x+',y:'+y+')'
div.innerHTML = str
})
</script>
</body>
四、键盘事件
1、 键盘事件的常用方法
键盘事件是指用户在使用键盘时触发的事件。例如,用户按Esc键关闭打开的状态栏,按Enter键直接完成光标的上下切换等。常用的键盘事件如下表所示
注:keypress事件保存的按键值是ASCII码,keydown和keyup事件保存的按键值是虚拟键码,keydown和keypress如果按住不放的话,会重复触发该对应事件。keyup和keydown事件不区分字母大小写,而keypress区分字母大小写
2、键盘事件对象
键盘事件对象KeyBoardEvent,是跟键盘事件相关的一系列信息的集合,根据键盘事件对象中的keyCode属性可以得到相应的ASCII码值,进而可以判断用户按下了哪个键
- String.fromCharCode() : 将ASCII码值转换成字母
- String.charCodeAt(): 将字母转换成对应的ASCII码
3、案例
①检测用户是否按下了s键,如果按下s 键,就把光标定位到搜索框里面
<body>
<input type="text">
<script>
var search = document.querySelector('input');
document.addEventListener('keyup', function (e) {
if (e.keyCode === 83) {
search.focus();
}
});
</script>
</body>
②文本框提示信息
案例需求:在现实生活中,我们经常会使用快递单号查询功能,查看商品的物流信息状态。有时在用户输入单号时,网站为了让用户看清楚输入的内容,会在文本框上方显示一个提示栏,将用户输入的数字放大
<body>
<div class="search">
<div class="con"></div>
<label>快递单号:
<input type="text" placeholder="请输入您的快递单号" class="num">
</label>
</div>
</body>
<script>
var con = document.querySelector('.con');
var numInput = document.querySelector('.num');
numInput.addEventListener('keyup', function () {
if (this.value == '') { con.style.display = 'none';}
else {
con.style.display = 'block'; con.innerText = this.value;
}
});
num_input.addEventListener('blur', function() {
con.style.display = 'none';
})
num_input.addEventListener('focus', function() {
con.style.display = 'block';
})
</script>