5-9、JS事件

什么是事件?

事件是可以被JavaScript 侦测到的行为,通俗的讲就是当用户与Web页面进行某些交互时,解释器就会创建响应的event对象以描述事件信息。

常见的事件有:

用户点击页面上的某项内容
鼠标经过特定的元素
用户按下键盘上的某个按键
用户滚动窗口或改变窗口大小
页面元素加载完成或加载失败

什么是事件句柄?

事件句柄(又称事件处理函数、事件监听函数),指用于响应某个事件而调用的函数。每一个事件均对应一个事件句柄,在程序执行时,将相应的函数或语句指定给事件句柄,则在该事件发生时,浏览器便执行指定的函数或语句。

addEventListener 添加绑定事件
js进行事件绑定:

  <button id="dianji">点击我</button>

    var div = document.getElementById('dianjia');
    //绑定事件1
    div.addEventListener('click',function(){
      //执行内容
    });
    //绑定事件2,与1实现的效果一模一样。
    var bangding = function(){
      //执行内容
    }
    div.addEventListener('click',bangding);

为特定事件定义监听函数有三种方式:

理解事件,拆分三步(下例):
1)事件对象 ( button )
2)事件对象绑定一个事件类型(鼠标、按键事件…)
3)事件句柄
也可以根据这三点验证事件是否完整。


直接在HTML中定义元素的事件相关属性
<button onclick="alert("hello)">按钮</button>
<body onload="init()">..</body>

缺点:违反了“内容与行为相分离”的原则,应尽可能少用。

Dom0级事件 第二种事件绑定方式
  <button id="dianji">Dom0</button>   <!-- 事件对象 -->

    var but = document.getElementById('dianji');
    console.log(but);
    var Dom0 = function(){    //句柄
      console.log(but);  
    }
    but.onclick = Dom0;   //绑定事件类型

这里注意,先写句柄后绑定,因为文档解析是自上而下,

Dom2级事件

高级事件处理方式,一个事件可以绑定多个监听函数:

⭐⭐⭐
btn.addEventListener("click",function(){},false;//DOM 
btn.attachEvent("onclick",function(){};//IE 
document.body.addEventListener("load",init);
document.body.attachEvent("onload",init);function init(){//...}

此语法可以为一个元素绑定多个监听函数,但需要注意浏览器兼容性问题
// .addEventListener
// 句柄可以直接写function(){},也可以先定义后引入
but2.addEventListener('事件类型', 事件句柄() ,false|true);
//⭐第三个参数是控制事件冒泡、事件捕获,默认false事件冒泡,true事件捕获
// 事件定义
<button id="but2">Dom0</button>   <!-- 事件对象 -->

    var but = document.getElementById('but2');
    var but22 = function(){}
    but2.addEventListener('click',but22,false|true);

⭐⭐⭐这里的事件类型,不加on,直接写click,其他事件类型也是一样!!!


以上就是三种定义事件方式,为什么需要这么多呢?
三种:

  1. htm1中定义
  2. DOMe级事件,事件对象的属性添加绑定事件
  3. DOM2级事件,通过addEventListener函数绑定事件

第一种方法再html中写js,强耦合性,不利于复用,绝对不能这么写
第二种方法,优点:html和js分离,松耦合性,缺点也很明显:有且只能绑定一个事件,如果绑定两个onlick,那么后面的覆盖掉前面的
第三种方法:Dom2级方法,松耦合,绑定多个事件,事件捕获和事件冒泡

Dom0事件,兼容所有浏览器。
Dom2事件,兼容较新的浏览器,包括IE


DOMO级与DOM2级区别:
1、DOM2支持同一dom元素注册多个同种事件。
2、DOM2新增了捕获冒泡的概念。


事件解绑

移除事件: removeEventListener ()
语法:element.removeEventListener (event , funtion , useCapture )
功能:移除addEventListener() 方法添加的事件句柄。
参数:
event:必须。字符串,要移除的事件名称。
function:必须。指定要移除的函数。
useCapture:可选。布尔值,指定移除事件句柄的阶段。

<button id="but2">Dom0</button>   <!-- 事件对象 -->

    var but = document.getElementById('but2');
    var but22 = function(){alert("tan");}
    but.addEventListener('click',but22);	//绑定
    but.removeEventListener('click',but22)	//解绑

直接在addEventListener,句柄中写的funtion(){},这种函数叫做匿名函数,在匿名函数中this指向的是window,this===window;
注意,如果绑定事件时,用的是匿名函数,那么不能在removeEventListener中也写匿名函数,那样并不会生效,因为绑定和解绑的函数并不一致,因为他们都是匿名函数。
事件解绑成功主要原因就是:保证addEventListener与removeEventListener中的参数保持一致。

IE事件处理程序

IE8及一下,需要使用一下事件:

添加事件attachEvent ()
语法:element.attachEvent(event , function)
功能:用于向指定元素添加事件句柄
参数:
event:必须。字符串,指定事件名,必须加“on"前缀。
function:必须。指定要事件触发时执行的函数。
IE浏览器不支持事件捕获,默认也只能是冒泡,所以没有第三个参数。

可以绑定多个事件类型,先弹出后绑定的,后弹出先绑定的。

移除事件detachEvent ( )
语法:element.detachEvent(event , function)
功能:移除attachEvent ()方法添加事件句柄
参数:
event:必须。字符串,要移除的事件名称
function:必须。指定要移除的函数。

  <button id="but2">Dom0</button>   <!-- 事件对象 -->
  
    var but = document.getElementById('but2');
    var but22 = function(){alert("tan");}
    but.attachEvent('onclick',but22);
    but.detachEvent('onclick',but22)
跨浏览器事件处理程序
  <button id="but2">Dom0</button>   <!-- 事件对象 -->


    //定义  (用的时候可以直接拷贝)
    var butsj = {
      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] = null;
        }
      },
      removeHandler : function(element,type,handler){	//解除
        if(element.removeEventListener){
          element.removeEventListener(type,handler,false);
        }else if(element.attachEvent){
          element.datachEvent('on'+type,handler);
        }else{
          element["on"+type] = null;
        }
      }
    }
    //使用 
    var but = document.getElementById('but2');
    var handler = function(){console.log("123");}
    butsj.addHandler(but,"click",handler);
    butsj.removeHandler(but,"click",handler);
事件捕获与事件冒泡⭐

事件冒泡:事件冒泡:直系亲属树结构中,点击某个元素,由于冒泡作用,亲属树上的元素凡是添加的事件的,都会被触发。
事件捕获:
在这里插入图片描述
IE的事件模型中没有“事件捕获”阶段。

事件周期:
解释器创建一个event对象后,会按如下过程将其在HTML元素间进行传播
第一阶段:事件捕获,事件对象沿DOM树向下传播
第二阶段:目标触发,运行事件监听函数
第三阶段:事件冒泡,事件沿DOM树向上传播

//	事件冒泡案例
//在这个例子中,先触发zi事件,后触发父事件。
<div id="fu">
    <div id="zi">点击儿子</div>
  </div>

  //事件冒泡
    document.getElementById('fu').addEventListener("click", function (e) {
      alert('父元素事件被触发' + this.id);
    },false)
    document.getElementById('zi').addEventListener('click', function () {
      alert('子元素事件被触发' + this.id);
    },false)
//	事件捕获案例
//在这个例子中,先触发fu事件,后触发zi事件。
<div id="fu">
    <div id="zi">点击儿子</div>
  </div>

  //事件冒泡
    document.getElementById('fu').addEventListener("click", function (e) {
      alert('父元素事件被触发' + this.id);
    },true)
    document.getElementById('zi').addEventListener('click', function () {
      alert('子元素事件被触发' + this.id);
    },true)
事件委托

原理就是事件冒泡。

  <ul id="ul">
    <li id="li1">我是第一个</li>
    <li id="li2">我是第二个</li>
    <li id="li3">我是第三个</li>
    <li id="li4">我是第四个</li>
  </ul> 

    var ul = document.getElementById('ul');
    ul.addEventListener("click",function(event){
      if(event.target.id == "li1"){
        alert("1");
      }else if(event.target.id == "li2"){
        alert("2");
      }else if(event.target.id == "li3"){
        alert("3");
      }else if(event.target.id == "li4"){
        alert("4");
      }
    },false);

li的事件,委托给了ul来进行添加,原理就是冒泡机制。

event对象常用的属性和方法

w3school的描述
下面列出了 2 级 DOM 事件标准定义的属性。

属性			描述
bubbles	   		返回布尔值,指示事件是否是起泡事件类型。
cancelable		返回布尔值,指示事件是否可拥可取消的默认动作。
currentTarget	返回其事件监听器触发该事件的元素。
eventPhase		返回事件传播的当前阶段。
target			返回触发此事件的元素(事件的目标节点)。
timeStamp		返回事件生成的日期和时间。
type			返回当前 Event 对象表示的事件的名称。

type:事件的类型;
srcElement/target:事件源,就是发生事件的元素;
cancelBubble:布尔属性,设为true的时候,将停止事件进一步起泡到包容层次的元素;(e.cancelBubble=true;相当于e.stopPropagation()😉;
returnValue:布尔属性,设置为false的时候可以组织浏览器执行默认的事件动作;(e.returnValue=false;相当于e.preventDefault)😉;
clientX/clientY:事件发生的时候,鼠标相对于浏览器窗口可视文档区域的左上角的位置;
offsetX,offsetY:事件发生的时候,鼠标相对于事件源元素左上角的位置;说明:events诞象的所有属性列表可以在浏览器控制台中输出查看。

event.type

//案例一  event.type
  <button id="but">点击我</button>

    var but = document.getElementById('but');
    var buts = function(event){
      if(event.type == "click"){
        console.log(event.type);
      }
      if(event.type == 'mouseout'){
        console.log(event.type);
      }
    }
    but.addEventListener('click',buts);
    but.addEventListener('mouseout',buts);

在案例一里,通过获取event.type,判断事件类型,决定执行哪个函数。同一个函数可以触发不同的时间类型,就可以执行不同的事件逻辑。

target 和 currentTarget
target 点击谁返回谁
currentTarget 不管点击谁,返回事件绑定对象

  <div id="fu">
    <div id="zi">点击子div</div>
  </div>

    var fu = document.getElementById('fu');
    //事件绑定在父元素上
    fu.addEventListener('click',function(event){
      //事件绑定在父元素上,点击的是子元素,返回子元素
      console.log(event.target); 
      //事件绑定在父元素上,点击的是子元素,返回父元素
      console.log(event.currentTarget); 
    })

在这里插入图片描述
如果在这个例子中绑定的都是zi元素,那么两个返回的都是子元素

preventDefault
阻止默认行为

	//案例,阻断a标签默认行为(跳转),只执行函数里的逻辑
	  <a id="a" href="baidu.com">执行函数,不执默认行为</a>

    var a = document.getElementById('a');
    a.addEventListener('click',function(event){
       event.preventDefault();
       console.log('执行这里');
    })

stopPropagation
阻止事件的捕获或冒泡。
该方法将停止事件的传播,阻止它被分派到其他 Document 节点。在事件传播的任何阶段都可以调用它。注意,虽然该方法不能阻止同一个 Document 节点上的其他事件句柄被调用,但是它可以阻止把事件分派到其他节点。

<div id="fu">
    <div id="zi">点击子元素</div>
</div>

    var fu = document.getElementById('fu');
    var zi = document.getElementById('zi');
    fu.addEventListener('click',function(event){
      console.log("父元素点击事件触发");
    });
    zi.addEventListener('click',function(event){
      console.log("子元素点击事件触发");
      event.stopPropagation
    });

原本给父子绑定事件,点击后触发子事件,然后冒泡触发父事件;加上event.stopPropagation 之后,触发子事件之后,不再冒泡。

clientY 、pageY 、 screenY 、offsetY
clientY :浏览器顶部到鼠标的位置。
pageY :浏览器顶部到鼠标的位置,并且加上滚动轴的距离。
screenY:屏幕顶部到鼠标位置。
offset:事件对象顶部到鼠标的举例。

IE8及一下浏览器Event对象属性与方法
type:事件的类型;
srcElement/target:事件源,就是发生事件的元素;
cancelBubble:布尔属性,设为true的时候,将停止事件进一步起泡到包容层次的元素;(e.cancelBubble=true;相当于e.stopPropagation(); );
returnValue:布尔属性,设置为false的时候可以组织浏览器执行默认的事件动作;(e.returnValue=false;相当于e.preventDefault(); );

event.returnValue=false;	阻止默认行为同preventDefault
event.cancelBubble=true;	取消事件冒泡同stopPropagation 
srcElement					同target
type						事件类型

Event对象跨浏览器兼容写法

  <div id="fu">
    <div id="zi">点击子元素</div>
  </div>
  <a href="baidu.com" id="a1">阻止默认事件</a>


    //定义  (用的时候可以直接拷贝)
    var butsj = {
      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] = null;
        }
      },
      removeHandler : function(element,type,handler){	//解除
        if(element.removeEventListener){
          element.removeEventListener(type,handler,false);
        }else if(element.attachEvent){
          element.datachEvent('on'+type,handler);
        }else{
          element["on"+type] = null;
        }
      },
      getTarget : function(event){ //点击谁返回谁
        return event.target || event.srcElement;
      },
      preventDefault : function(event){  //阻止默认行为
        if(event.preventDefault){
          event.preventDefault();
        }else{
          event.returnValue = false;
        }
      },
      stopPropagation : function(event){ //阻止事件的捕获或冒泡。
        if(event.stopPropagation){
          event.stopPropagation();
        }else{
          event.cancelBubble = true;
        }
      },
      getCharCode : function(event){
        if(typeof event.charCode == 'number'){
          return event.charCode;
        }else{
          return even.keyCode;
        }
      }
    }
    //使用 
    var fu = document.getElementById('fu');
    var zi = document.getElementById('zi');

    butsj.addHandler(zi, "click", function(event){
      var target = butsj.getTarget(event);
      console.log("子事件触发");
      butsj.stopPropagation(event);  //阻止冒泡
    });
    
    butsj.addHandler(fu,'click',function(event){
      console.log("父事件触发");
    });

    var a = document.getElementById('a1');
    butsj.addHandler(a,'click',function(event){
      butsj.preventDefault(event);  //阻止默认行为
    });
事件类型
//常见类型:
onclick:当用户点击某个对象时调用的事件句柄。
onfocus:元素获得焦点。
onblur:元素失去焦点。
onmouseover:鼠标移到某元素之上。
onmouseout:鼠标从某元素移开。
onmousedown:鼠标按钮被按下。
onmousemove:鼠标被移动。
onmouseup:鼠标按键被松开。
UI事件
//使用上面定义好的函数
    var butsj = {...}	//定义  (用的时候可以直接拷贝)

	//当页面完全加载后在window上触发	
    buts.addHandler(window,"load",function(event){alert("加载完成后在window上触发");})
    //以下案例用截图

生成一个img标签,添加load事件,指向一个地址。
图片可能比较大,用这种方式,他会慢慢加载,加载完成之后会执行中间的话。
在这里插入图片描述
图片预加载
new image,将图片缓存的内存空间上。
在这里插入图片描述
动态加载js文件
创建一个script标签,添加load事件,引入js文件,添加进body里。
在这里插入图片描述
动态加载css文件
在这里插入图片描述
先过,后补。
在这里插入图片描述
窗口变化大小变化时触发
滚动触发,所以注意性能。
在这里插入图片描述
滚动跳变化大小变化时触发,经典案例,瀑布流、商城商品
滚动触发,所以注意性能。在这里插入图片描述

焦点事件

blur 元素失去焦点的时候触发,不支持冒泡:

<input type="text" name="" id="text1">
	
	var butsj = {...}
	var text1 = document.getElementById("text1);
	butsj.addHandler(text1,"blur",function(event){
      console.log("123");
    });

focus 元素获取焦点的时候触发,不支持冒泡:

<input type="text" name="" id="text1">
	
	var butsj = {...}
	var text1 = document.getElementById("text1);
	butsj.addHandler(text1,"focus",function(event){
      console.log("元素获得焦点的时候触发!");
    });

focusinfocus 一样,但支持冒泡。
在这里插入图片描述

focusoutblur 一样,但支持冒泡。在这里插入图片描述

鼠标事件
onclick    	点击事件
dbclick   	双击事件
mousedown   鼠标按键按下事件
mouseup     鼠标按键松开事件
mousemove   鼠标在目标元素上移动的时候触发

mouseover	鼠标进入目标元素的时候触发
mouseout	鼠标离开目标元素的时候触发

mouseenter	鼠标进入(穿过)元素的时候触发,子元素不触发
mouseleave	鼠标离开(穿过)元素的时候触发,子元素不触发

这里注意,mouseover与mouseout,绑定在父元素上,鼠标在父元素与子元素之间切换的时候也会触发。案例:

  <div id="div1">
    <div id="div2">子元素</div>
  </div>
  
	var butsj = {...}
	var div1 = document.getElementById('div1');
    butsj.addHandler(div1,'mouseenter',function(event){
      console.log("父元素");
    })

鼠标 + 按键 事件
在事件对象区域内,同时按下对应按键加上鼠标按键

<div id="mydiv"></div>	//css没写

var mydiv = document.getElementById('mydiv');
    butsj.addHandler(mydiv, 'click', function (event) {
      var keys = new Array();
      if (event.shiftKey) {
        keys.push('shift');
      }else if (event.ctrlKey) {
        keys.push('ctrl');
      }else if (event.altKey) {
        keys.push('alt');
      }else if (event.meteKey) {
        keys.push('meta');
      }
      console.log(keys.join(","));
    });

// mousedown	中完全生效
event.button  == 0 鼠标左键
event.button  == 1 鼠标中键
event.button  == 2 鼠标右键

这是在高级浏览器中,ie中不一样具体用的时候再查。

键盘事件

keydown 键盘按下事件触发
keypress 按键被按下
keyup 键盘松开事件触发
在这里插入图片描述

.keyCode 获取键盘键码

<input type="text" id="txt">

	var butsj = {...}
	var txt1 = document.getElementById("txt");
    butsj.addHandler(txt,"keydown",function(event){
      console.log(event.keyCode);
    })

charCode 获取字符键的ASCII码
兼容性写法:

	var butsj = {
	  getCharCode : function(event){
        if(typeof event.charCode == 'number'){
          return event.charCode;
        }else{
          return even.keyCode;
        }
      }
    }

textInput 在输入框中输入什么就可以用.data输出什么。

	var txt1 = document.getElementById("txt");
    butsj.addHandler(txt,"textInput",function(event){
      console.log(event.data);
    })
特殊事件

DOMNodeRemove
绑定在document上,所以删除页面(document)上任意元素都会被触发。
绑定在ul上,那么删除其后代元素才会被触发,比如li。
在这里插入图片描述
DOMNodeInserted
任意元素被添加就会触发
在这里插入图片描述

DOMSubtreeModified
结构中发生任何变化都会触发在这里插入图片描述
DOMNodeRemovedFromDocument
从文档中移除之前被触发 ,注意这里第一个参数不是document了,而是事件对象
在这里插入图片描述
类似于上边那个
在这里插入图片描述

从文档中添加之前被触发
在这里插入图片描述
DOMContentLoaded
DOM树解析完成之后就触发。比load触发快得多
在这里插入图片描述

readystatechange
不稳定,尽量不用
在这里插入图片描述
hashchange
链接#后边的发生变化会触发
在这里插入图片描述
在这里插入图片描述

手机事件
touchstart	手指触摸屏幕。
touchmove	手指在屏幕上滑动。
touchend	手指从屏幕上移开。

touchcancel	当系统停止跟踪触摸时

<button id="but1">点击我</button>

	var butsj = {...}
	var but1 = document.getElementById('but1');
    butsj.addHandler(but1,"touchstart" ,function(e){
      console.log("触摸屏幕");
    });

注意,touchmove是持续事件,所以事件内容不要太复杂,内存会爆掉。
在这里插入图片描述

event.touches 当前触摸屏幕的触摸点数组,四个触摸点的信息都在
event.changedTouches 数组中只包含引起事件的触摸点信息,四个点点上去,其中两个动了,那么里边包含的就是动了的那两个
event.targetTouches 只包含放在元素上的触摸信息,四个点,两个点在事件上,那么只包含这两个在时间上的点

小项目

在这里插入图片描述

	
<div id="canves"></div>
  <ul id="ul">
    <li>红色</li>
    <li>黑色</li>
    <li>蓝色</li>
    <li>黄色</li>
    <li>绿色</li>
  </ul>

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值