JS 事件

事件

1. Event 对象

event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。

  • 事件通常与函数结合使用,函数不会在事件发生前被执行!

4. 事件委托

1. 定义

事件委托就是利用事件冒泡,指定一个事件处理程序,就可以管理某一类型的所有事件

2. 基本实现

js 原生实现事件委托

1. 需求给li添加同样效果的事件

<ul id="ul">
    <li>111</li>
	<li>222</li>
	<p>p标签</p>
	<li>333</li>
	<li>444</li>
</ul>

# 传统(首先要找到ul,然后遍历li,然后点击li的时候,又要找一次目标的li的位置,才能执行最后的操作,每次点击都要找一次li)
var oUl = document.getElementById('ul')
var aLi = oUl.getElementsByTagName('li')
for(var i=0; i<aLi.length; i++){
    aLi[i].onclick = function() {
        alert(1)
    }
}

# 事件委托(不过有个缺点,当点击ul的时候,也会触发)
var oUl = document.getElementsByClassName('box')[0]
oUl.onclick = function() {
    alert(1)
}

# 解决(Event对象提供了一个target属性,返回事件的目标节点,也就是说,target就可以表示为当前事件操作的dom,但是不是真正的dom,不过有兼容性问题)
var oUl = document.getElementById('ul')
oUl.onclick = function(ev) {
    var ev = ev || window.event // 写法等价于(var ev = ev ? ev || window.event)window.event 是兼容ie8及以下的
    var target = ev.target || ev.srcElement // ev.srcElement是兼容ie的
    if(target.nodeName.toLowerCase() == 'li') {
        alert(1)
    }
}
复制代码

2. 需求每个li被点击的效果都不一样

<div id="box">
    <input type="button" id="add" value="添加" />
    <input type="button" id="remove" value="删除" />
    <input type="button" id="move" value="移动" />
    <input type="button" id="select" value="选择" />
</div>

var box = document.getElementById('box')
box.onclick = function(ev) {
    var ev = ev || window.event
    var target = ev.target || ev.srcElement
    switch(target.id) {
        case 'add' : 
            console.log('添加')
            break
        case 'remove' :
            console.log('删除')
            break
        case 'move' :
            console.log('移动')
            break
        case 'select' :
            console.log('选择')
            break
    }
}
复制代码

3. 需求动态添加事件

<ul id="ul">
    <li>111</li>
	<li>222</li>
	<p>p标签</p>
	<li>333</li>
	<li>444</li>
</ul>

var oUl = document.getElementById('ul')
oUl.onmouseover = function (ev) {
    var ev = ev || window.event
    var target = ev.target || ev.srcElement
    if(target.nodeName.toLowerCase() == 'li') {
        target.style.background = 'red'
    }
}

oUl.onmouseout = function (ev) {
    var ev = ev || window.event
    var target = ev.target || ev.srcElement
    if(target.nodeName.toLowerCase() == 'li') {
        target.style.background = 'white'
    }
}

var num = 4
function addNode() {
    num++
    var li = document.createElement('li')
    li.innerHTML = num * 111
    oUl.appendChild(li)
}
复制代码

4. 需求无论事件第一事件源是谁,最后都统一到li才执行(统一事件源)

<ul id="test">
    <li>
    <p>11111111111</p>
    </li>
    <li>
        <div>
        22222222
    </div>
    </li>
    <li>
        <span>3333333333</span>
    </li>
    <li>4444444</li>
</ul>

var oUl = document.getElementById('test');
oUl.addEventListener('click',function(ev){
    var target = ev.target;
    while(target != oUl) {
        if(target.tagName.toLowerCase() == 'li') {
            console.log('li')
            break
        }
        target = target.parentNode
    }
})
复制代码

3. 什么事件可以用事件委托

适合用事件委托的事件:click、mousedown、mouseup、keydown、keyup、keypress

不适合的:mousemove、mouseout(这两种有事件冒泡,但是经常需要计算它们的位置,处理起来不太容易)focus、blur(这类没有事件冒泡的)

5. 事件流

1. 事件冒泡

1.定义:

一个事件触发后,会在子元素和父元素之间传播。这种传播分为三个阶段。

事件传播分成三个阶段:

  • 捕获阶段:从window 对象传导到目标节点(上层传到底层)称为 捕获阶段(capture phase),捕获阶段不会响应任何事件
  • 目标阶段:在目标节点上触发,称为 目标阶段
  • 冒泡阶段:从目标节点传导回window 对象(从底层传回上层),称为 冒泡阶段。事件代理既是利用事件冒泡的机制把里层所需要响应的事件绑定到外层。

2. 阻止事件冒泡方法

  1. event.stopPropagation() 阻止事件冒泡

  2. return false 阻止事件冒泡和默认行为

  3. event.preventDefault() 阻止默认行为

6. 浏览器在事件处理程序上的5种形式

1. HTML 事件处理程序

<input id="btn" value="click me" onclick="alert('clicked')" />
  
<script type="text/javascript"> 
  function showMessage(){
  	alert("clicked");
  }
</script>
<input id="btn" value="click me" onclick="showMessage()" />
复制代码

2. DOM0 级事件处理程序

var btn = document.getElementById("btn");
//指定事件处理程序
btn.onclick = function(){
   alert("Clicked"); 
};

//想要取消事件处理程序的话,只需将事件处理程序属性设为null即可
btn.onclick = null;

btn.onclick=function(){
  alert(this.id);//btn
}
复制代码

3. DOM2 级事件处理程序

指定和取消的参数必须完全相同才有效,为了能够取消,最好函数采用命名函数

var handler = function(){
   alert("clicked"); 
};
//添加事件处理程序
btn.addEventListener("click",handler,false);
//取消事件处理程序
btn.removeEventListener("click",handler,false);//有效
//取消事件处理程序
btn.removeEventListener("click",a,false);//无效
复制代码

onclick 和addEventListener 的区别:

box.onclick = function(){ console.log('1') }
box.onclick = function(){ console.log('2') }   //会覆盖1

box.addEventListener('click',function(){ console.log('1') })
box.addEventListener('click',function(){ console.log('2') })  //不会覆盖
复制代码

4. IE 事件处理程序

let box = document.querySelector('.box')
function xxx(){console.log('box clicked...')}
box.attachEvent('onclick',xxx)
复制代码

5. 跨浏览器的事件处理程序(兼容)

var EventUtil = {
  addHandler:function(element,type,handler){
    if(element.addEventListener){
      element.addEventListener(type,handler,false);
    }else if(element.attachEvent){
      element.attachEvent("on"+type,handler);
    }else{
      element["on"+type] = handler;
    }
  },
  removeHandler:function(element,type,handler){
    if(element.removeEventListener){
      element.removeEventListener(type,handler,false);
    }else if(element.detachEvent){
      element.detachEvent("on"+type,handler);
    }else{
      element["on"+type] = null;
    }
  }

};
var handler = function(){
  alert("Clicked");
};
//指定
EventUtil.addHandler(btn,"click",handler);
//移除事件处理程序
EventUtil.removeHandler(btn,"click",handler);
复制代码

附上关系图

转载于:https://juejin.im/post/5ce21f39e51d4510a25d1a9c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值