• 有问题请联系QQ:2374146085
  • 有问题请联系QQ:2374146085

DOM-事件高级

2年前 (2021-09-14) 1367次浏览 已收录 0个评论 扫描二维码

注册事件(绑定事件)

注册事件有两种方式:

  • 传统方式
  • 方法监听注册方式

传统注册方式

  • 利用on开头的事件
  • btn.onclick=function(){};
  • 特点:注册事件的唯一性
  • 即同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数。

方法监听注册方式(推荐)

  • w3c标准
  • addEventListener()它是一个方法
  • IE9之前不支持上面的方法,可使用arrachEvent()代替(这句话可以忽略)
  • 特点:同一个元素用一个事件可以注册多个监听器(处理函数)
  • 按注册顺序依次执行

addEventListener事件监听方式

目标对象.addEventListener(type,listener[ , useCapture])
  • type:事件类型字符串。比如click、mouseover等
  • listener:事件处理函数,事件发生时,会调用该监听函数
  • useCapture:可选参数,布尔值,下面的事件流会用
<script>
    var btn=document.querySelector('button');
    // 同一个元素可以注册多个监听器(处理函数)
    btn.addEventListener('click',function(){
        alert('广告1');
    })
    btn.addEventListener('click',function(){
        alert('广告2');
    })
</script>

删除事件

删除事件的方式

传统注册方式的删除事件

eventTarget.onclick=null;

方法监听注册方式的删除事件

eventTarger.removeEventListener(type, listener[ , useCapture]);
<script>
    var divs=document.querySelectorAll('div');
    div[0].onclick=function(){
        alert('广告');
        //传统方式删除事件
        div.onclick=null;
    }
    
    div[1].addEventListener('click',fn);//里面的fn调用不需要加小括号
    function fn(){
        alert('广告');
        //方法监听方式删除事件
        div[1].removeEvnetListener('click',fn);
    }
</script>

DOM事件流

事件流描述的是从页面中接收事件的顺序。

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程就是DOM事件流。

比如给一个div注册了点击事件,然后dom事件流就分为了3个阶段:

  1. 捕获阶段
  2. 当前目标阶段
  3. 冒泡阶段

形象比喻:我们向水里扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点(最具体的元素,即目标点)之后漂浮到水面上,这个过程相当于事件冒泡。

注意:

  • js代码中只能执行捕获或者冒泡其中的一个阶段
  • onclick和attchEvent只能得到冒泡阶段
  • addEventListener(type, listenr[ , useCapture])第三个参数如狗是true,表示在事件捕获阶段调用事件处理程序,如果是false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序。
  • 实际开发中很少使用事件捕获,更多使用事件冒泡。
  • 有些事件是没有冒泡,比如onblur、onfocus、onmouseenter、onmouseleave
<div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        // dom 事件流 三个阶段
        // 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
        // 2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。
        // 3. 捕获阶段 如果addEventListener 第三个参数是 true ,
        // 那么则处于捕获阶段  document -> html -> body -> father -> son
        // var son = document.querySelector('.son');
        // son.addEventListener('click', function() {
        //     alert('son');
        // }, true);
        // var father = document.querySelector('.father');
        // father.addEventListener('click', function() {
        //     alert('father');
        // }, true);
        // 4. 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略,
        // 那么则处于冒泡阶段  son -> father ->body -> html -> document
        var son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, false);
        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, false);
        document.addEventListener('click', function() {
            alert('document');
        })
    </script>
结果演示

事件对象

btn.onclick=function(event){
console.log(event);
//兼容性方法
//e=e||window.event;
//console.log(e);
}//event就是一个事件对象,写到监听函数的小括号里,当形参看。
  • 事件对象只有有了事件才会存在,它是系统自动创建的,不需要我们传递参数。
  • 事件对象是我们事件的一系列相关数据的集合,跟事件相关的,比如鼠标点击,event里面就包含了鼠标的相关信息:鼠标坐标等,如果是键盘事件,event里面就包含了键盘事件的信息:判断用户按下了哪个键等等。
  • 事件对象可以自己命名
  • 兼容性:IE678通过window.event 获取事件对象

event.target与this的区别

  • event.target点击了哪个元素,就返回哪个元素
  • this:哪个元素绑定了这个点击事件,就返回哪个元素

事件对象属性方法

阻止默认事件

  • 普通浏览器 e.preventDefault() 最常用了
  • 低版本浏览器 e.returnValue;

阻止事件冒泡

标准写法:

利用事件对象里面的event.stopPropagetion()方法

非标准写法:IE678:

利用事件对象event.cancelBubble=true;

阻止事件冒泡的兼容性解决方案

<script>
        if(enevt && event.stopPropagation){//如果有这个事件对象,并且可以识别这个方法
            event.stopPropagation();
        }else{
            window.enevt.cancelBubble=true;
        }
    </script>

事件委托(代理、委派)

原理:

不是每个子节点都单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置的每一个子节点。

作用:只操作了一次DOM,提高了程序的性能。

举例:

给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul已经注册(绑定)了事件,就会触发事件监听器

<!--
        <ul>
            <li>点我</li>
            <li>点我</li>
            <li>点我</li>
            <li>点我</li>
        </ul>
    -->
    <script>
        //事件委托的原理:给父节点添加监听器,利用事件冒泡影响每一个子节点
        var ul=document.querySelector('ul');
        ul.addEventListener('click',function(e){
            alert('哈哈');          
            e.target.style.backgroundColor='blue';
        })
    </script>
结果演示

常用的鼠标事件

方法监听注册方式的鼠标事件不写前面的on,键盘事件亦是如此。

mouseenter和mouseover的区别

  • 当鼠标移动到元素上时就会触发mouseenter事件
  • mouseover:鼠标经过自身盒子会触发,经过子盒子也会触发
  • mouseenter:只会经过自身盒子触发
  • 之所以这样,是因为mouseennter不会冒泡
  • 跟mouseenter搭配的 鼠标离开 mouseleave 同样也不会冒泡

鼠标事件对象

案例

做一个跟随鼠标的图片,分析如下:

  • 鼠标不断的移动,使用鼠标移动事件;mousemove
  • 在页面中移动,给document注册事件
  • 图片要移动距离,而且不占位置,则可以使用绝对定位
  • 每次鼠标移动,都会获得最新的坐标,把这个x和y坐标作为图片的top和left值就可以移动图片
<script>
        var div=document.querySelector('div');
        document.addEventListener('mousemove',function(e){
            var x=e.pageX;
            var y=e.pageY;
            div.style.left=x+'px';
            div.style.top=y+'px';
        })
    </script>
结果演示

禁止鼠标右键菜单

contextmenu主要控制应该何时显示上下文菜单,即禁用右键菜单

document.addEventListener('contextmenu',function(e){
e.preventDefault();//阻止默认事件
})

禁止鼠标选中(选中文字)

selectstart 开始选中

document.addEventListener('selectstart',function(event){
event.preventDefault();
})

常用的键盘事件

  • 只是onkeypress不识别功能键,比如ctrl、shift等。
  • onkeyup和keydow事件不区分字母大小写,a和A的得到的都是65
  • onkeypress事件区分字母大小写,a 97和A 65。
同时写三个事件的执行顺序:keydow—keypress—keyup

键盘事件对象

  • e.keyCode 返回该键的ASCII值。

光标定位到搜索框案例

思路:

  • 检测用户是否按下了a键,如果按下了a键,就把光标定位到搜索框里
  • 使用keyCode判断用户是否按下了a键
  • 搜索框获得焦点:使用js里的focus()方法
<script>
        var ip=document.querySelector('input');
        document.addEventListener('keyup',function(e){
            console.log(e.keyCode);
            if(e.keyCode === 65){
                ip.focus();
            }
        })
    </script>
结果演示

搜索框显示隐藏案例

分析:

  • 快递单号输入内容时, 上面的大号字体盒子(con)显示(这里面的字号更大)
  • 表单检测用户输入: 给表单添加键盘事件
  • 同时把快递单号里面的值(value)获取过来赋值给 con盒子(innerText)做为内容
  •  如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子
<script>
        var ip=document.querySelector('input');
        var con=document.querySelector('.con');
        ip.addEventListener('keyup',function(e){
            //没有内容了就隐藏
            if(this.value == ''){
                con.style.display='none';
            }else{     
                con.style.display='block';
                con.innerText=this.value;
            }
        })
        // 失去焦点,就隐藏这个con盒子
        ip.addEventListener('blur',function(){
            con.style.display='none';
        })
        // 获得焦点,就显示这个con盒子
        ip.addEventListener('focus',function(){
            // 然后有内容才会真的显示
            if(this.value !== ''){
                con.style.display='block';
            }
        })
    </script>
结果演示


渣渣龙, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:DOM-事件高级
喜欢 (3)

您必须 登录 才能发表评论!