DOM 中的事件

事件

事件是什么

所谓事件,就是浏览器告知 JavaScript 程序用户的行为。例如用户点击了 HTML 页面中的某个按钮,或者用户输入用户名或密码等操作。

如下示例代码,演示了如何通过事件完成用户点击按钮后的逻辑:

<div class="button-group">
	<button id="btn" class="button">按钮</button>
</div>
<script>
	// 获取按钮元素
	var btn = document.getElementById('btn');
	// 事件绑定
	btn.onclik = function(){
			console.log('你终于点中我了...');
	}
</script>

事件解析图:
https://gitee.com/project_almanac/change/raw/master/DOM/WvFdkb@S6Y5r.png

事件类型

事件根据场景不同,可以分为如下几种:

  • 依赖于设备的输入事件:键盘事件和鼠标事件,这些事件都是直接和设备相关的。
  • 独立于设备的输入事件:例如click事件等,这些事件并没有直接与设备相关。
  • 用户界面的相关事件:用户界面事件属于较高级的事件,一般多用于表单中的组件。
  • 状态变化的相关事件:这些事件与用户行为无关,而是由网络或浏览器触发的。
  • 特定 API 事件:这些事件多用于特定场景的实现,例如 HTML5 中提供的拖放 API 中的事件等。
  • 与错误处理的相关事件。

事件的实现的步骤

如事件部分示例的代码所示:

  1. 定位页面中指定的元素
var btn = document.getElementById('btn');
  1. 为指定元素绑定事件 - 具有一个事件监听器(监听用户的相应行为)
btn.onclik = function(){
             // console.log('你终于点中我了...');
            }
  1. 为绑定的事件编写相应的处理函数(用户触发相应的行为时,函数做出响应)
console.log('你终于点中我了...'); // 函数体

注册事件是什么

所谓注册事件,就是将 JavaScript 函数与指定的事件相关联,被绑定的函数称为该事件的句柄。该事件被触发时,绑定的函数会被调用。

注册事件具有以下三种方式实现:

  • HTML 页面元素提供的事件属性
  • DOM 标准规范中 HTML 相关对象提供的事件属性
  • 通过向 HTML 页面中指定元素添加事件监听器

如图所示:

https://gitee.com/project_almanac/change/raw/master/DOM/9AvUFnUF*grK.png

DOM 对象的事件属性

通过 DOM 标准规范中的 Document 对象定位 HTML 页面的元素,所返回的 DOM 对象提供了一系列的事件属性,通过这些事件属性可以实现注册事件的功能。

<div class="button-group">
	<button id="btn" class="button">按钮</button>
</div>
<script>
	var btn = document.getElementById('btn');
	btn.onclik = myClick;
	function myClick() {
			console.log('你终于点中我了...');
	}
</script>

通过 DOM 对象的事件属性方式注册事件,是不允许重复注册的。如果以这种方式为某个元素注册相同事件多次的话,只有最后一次注册的函数有效。

事件监听器

DOM 标准规范提供的 addEventListener() 方法,调用该方法表示向指定元素添加事件监听器。

element.addEventListener(eventName,functionName.capture)
参数名称描述
eventName为元素指定具体的事件名称(例如单击事件是 click 等)
functionName注册事件的句柄
capture设置事件是捕获阶段还是冒泡阶段。false 为默认值,表示冒泡阶段
<div class="button-group">
	<button id="btn" class="button">按钮</button>
</div>
<script>
	var btn = document.getElementById('btn');
	btn.onclik = function(){
			console.log('你终于点中我了...');
	}
</script>

为指定元素添加事件监听器:addEventListener(eventName,callback)
参数:

  • eventName - 表示绑定的事件名称(注意:没有 on)
  • callback - 表示事件的处理函数(回调函数)

DOM 对象提供的事件属性,无法同时为一个指定元素绑定相同事件多次

btn.onclick = function() {
    console.log('test');
}
btn.onclick = function() {
    console.log('test2');
}

但是 DOM 允许相同元素绑定相同事件多次

btn.addEventListener('click',function(){
            comsole.log('test3');
        });
        btn.addEventListener('click',function(){
            comsole.log('test4');
        });

事件监听器在浏览器中存在兼容问题(IE8 以下浏览器版本不支持)

可以利用attachEvent(eventName,functionName) 方法

  • eventName 表示事件名称(注意:必须有 on )
  • functionName 表示事件的处理函数

用法示例:

btn.attachEvent('onclik',function(){
            console.log('text5');
        });

浏览器兼容解决方案:

function bind(element,eventName,functionName){
    if (element.addEventListener){
        element.addEventListener(eventName,functionName);
    } else {
        element.attachEvent('on' + eventName,functionName);             
    };
};

事件监听器中的 this

当使用 addEventListener() 方法为某个HTML页面元素注册事件的时候,this 就指代注册事件的元素。

btn.addEventListener('click',function(){
		console.log(this.text.Content);
})

当使用 attachEvent() 方法为某个 HTML 页面元素注册事件的时候,this 指代的是 window 对象,而不是注册事件的元素。

var btn = document.getElementById('btn');
btn.addachEvent('onclick',function(){
		console.log(this);  // 输出 [Object window]
})

由于 addEventListener() 方法中的 this 与 attachEvent() 方法中的 this 的含义不同,我们需要将监听器的浏览器兼容方案进行优化:

function bind(elem,event,callbcak){
		 // 判断是否存在 addEventListener
         if (elem.addEventListener){
             elem.addEventListener(event,callback,false);
         } else {
             elem.attachEvent('on' + event,function(){
             	 // 将 this 的指向修改为注册事件的元素
                 callback.call(elem);
             });   
         };
};

移除注册事件

DOM 标准规范提供的 removeEventListener() 方法,调用该方法表示向指定元素移除事件监听器。

elentName.removeEventListener(eventName,functionName,capture)
参数名称描述
eventName表示移除的事件名称(例如单击事件是 click 等)
functionName注册事件的句柄(之前使用 addEventListener() 方法定义的)
capture设置事件是捕获阶段还是冒泡阶段。false 为默认值,表示冒泡阶段
var btn = document.getElementById('btn');
function listener(){
		console.log('你终于点中了我');
}
btn.addEventListener('click',listener);
btn.removeEventListener('click',listener);

detachEvent() 方法

移除事件在 IE8 及之前版本的浏览器都不支持 removeEventListener() 方法,而是单独提供了 detachEvent 方法。

element.detachEvent(eventName,functionName)
参数名称描述
eventName表示移除的事件名称(例如单击事件是 click 等)
functionName注册事件的句柄(之前使用 addEventListener() 方法定义的)
var btn = document.getElementById('btn');
function listener(){
		console.log('你终于点中了我');
}
btn.attachEvent('click',listener);
btn.detachEvent('click',listener);

浏览器兼容

与注册事件相似,移除注册事件在实际开发中,同样需要兼容各大浏览器,具体解决方案如下:

function unbind(element,eventName,functionName) {
    if (element.removeEventListener){
        element.removeEventListener(eventName,functionName);
    } else {
        element.detachEvent('on' + eventName,functionName);
    } 
}

事件对象是什么

为 HTML 页面中的元素注册事件时,事件的处理函数具体一个 参数,该参数就是 Event 事件对象。 Event 事件对象中包含了该事件的信息,以及该事件发生在哪个元素上。

element.addEventListener(eventName,function(event){
		// event 就是事件对象
},capture)

注意:

  • 当事件发生时,Event 事件对象会被创建井依次传递给事件监听器。
  • 由于 Event 事件对象是事件处理函数的参数,所以参数名允许自定义的。

事件对象:事件的处理函数中接收一个参数。

Event 事件对象作为所有事件对象的父级

  • MouseEvent 事件对象 - 表示鼠标事件
  • KeyboardEvent 事件对象 - 表示键盘事件
  • TouchEvent 事件对象 - 表示触摸事件
<script>
    var btn = document.getElementById('btn');
    // 事件的处理函数中接收一个参数 - 事件对象
    btn.addEventListener('click',function(event){
        console.log(event);
    })
</script>

浏览器兼容

IE8 及之前版本的浏览器,HTML 页面元素注册事件时,Event 事件对象并不是作为事件的处理函数的参数,而是作为 window 对象的属性存在的。

<div class="button-group">
	<button id="btn" class="button">按钮</button>
</div>
<script>
	var btn = document.getElementById('btn');
	btn.attachEvent('onclick',function(){
			console.log(window.event);
	})
</script>

事件对象的 button 属性

鼠标右键功能案例

<script>
    // document对象和<html>标签绑定鼠标点击事件有效
    var html = document.documentElement;
    var body = document.body;
    html.addEventListener('mousedown',function(event){

        if(event.button === 2 ){
            //提供一个自定义菜单
        }
    });
</script>
  1. click事件 - 表示鼠标点击事件(鼠标左键)
  2. mousedown事件 - 表示鼠标事件被按下事件
  3. mouseup事件 - 表示鼠标按键被释放事件
  4. event事件对象提供了button属性:用于表示鼠标按键
  • 0 = 表示鼠标左键
  • 1 - 表示鼠标滚轮
  • 2 - 表示鼠标右键

获取目标元素

结构代码:

<ul id="phone">
    <li>苹果</li>
    <li id="smartisan"><a href="#">锤子</a></li>
    <li>小米</li>
</ul>

tarfet 属性

Event 事件对象提供了 target 属性,用于获取触发当前事件的 HTML 元素。

phone.addEventListener('click',function(event){
    // target属性 - 获取触发当前事件的目标元素
    console.log(event.target);
});
tarfet 属性的浏览器兼容问题

IE8 及之前版本浏览器并不支持 target 属性,而是提供了与 target 属性作用相同的 srcElement 属性。

var phone = document.getElementById('phone');
phone.addEventListener('onclick',function(event){
    event = event || window.event;
    console.log(event.srcElement);
});

currentTarget 属性与 this

事件处理函数中的 this ,作用与事件对象的 currentTarget 属性相同,可以获取注册当前事件的 HTML 元素。

phone.addEventListener('click',function(event){
    // currentTarget属性 - 获取绑定当前事件的目标元素
    console.log(event.currentTarget);
    // this等同于currentTarget属性 - 获取绑定当前事件的目标元素
    console.log(this);
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值