• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
百事可爱
一起努力鸭~~~
博客园    首页    新随笔    联系   管理    订阅  订阅
DOM高级事件

事件高级

1. 注册事件(绑定事件)

给元素添加事件,称为注册事件(绑定事件)
注册事件有两种方式:

  1. 传统方式
    利用on开头的事件onclick , 利用事件三要素 来注册
    特点:
    注册事件的唯一性:
    就是同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面的注册的处理函数
  2. 方法监听注册方式
    是W3C标准,也是推荐方式
    用到 addEventListener() 方法 ,IE9以上版本支持
    特点:
    同一个元素同一个事件可以注册多个处理监听器,会按照注册顺序依次执行
    监听器就是监听处理函数

eventTarget.addEventListener(‘type’, listener, useCapture)

方法实现将指定的监听器注册到eventTarget(目标对象)上,当 该对象触发指定的事件时,就会执行事件处理函数
该方法接收三个参数:

  1. type: 事件类型字符串,比如 click , mouseover, 这里不带 on
  2. listener: 事件处理函数 ,事件发生时,会调用该监听函数
  3. useCapture: 可选参数, 是一个布尔值, 默认是false
<body>
     <button>传统方式</button>
     <button>方法监听注册方式</button>
    <script>
         var btns = document.querySelectorAll("button");
         //1. 给第一个按钮以传统方式注册同一个事件“弹出一个对话框”
         btns[0].onclick = function(){
             alert('hi');
         }
         btns[0].onclick = function(){
             alert('nihao');
         }
         //结果只有第二个事件触发
         //2.给第二个按钮以方法监听方式注册同一个事件“弹出一个对话框”
         btns[1].addEventListener('click',function(){
            alert('hi');
         })
         //addEventListener 方法里面的事件类型是字符串,必须加引号,并且不带 on
         btns[1].addEventListener('click',function(){
            alert('22');
         })
    </script>
</body>

2. 删除事件(解绑事件)

  1. 传统方式:
    eventTarget.onclick = null;
  2. eventTarget.removeEventListener(‘type’, listener, useCapture)
    因为移除时要将那个函数移除要写出来,不可以用匿名函数的形式
    就是添加注册事件 另写一个函数
<body>
     <button>传统方式注册和删除事件</button>
     <button>方法监听注册和删除事件</button>
    <script>
         var btns = document.querySelectorAll("button");
         //1. 给第一个按钮以传统方式注册同一个事件“弹出一个对话框”
         btns[0].onclick = function(){
             alert('hi');
             btns[0].onclick = null;//解绑
         }
         
          
         //2.给第二个按钮以方法监听方式注册同一个事件“弹出一个对话框”
        //  btns[1].addEventListener('click',function(){
        //     alert('hi');    
        //  })
          
        btns[1].addEventListener('click',fn);//此处函数调用没有小括号,
        function fn(){
            alert('hi'); 
            //解绑
            btns[1].removeEventListener('click',fn);
        }
         
    </script>
</body>

DOM事件流: 事件的传播过程

  1. 事件流描述的是从页面中接收事件的顺序
  2. 事件发生时会在元素节点之间按照特定的顺序传播,这个传播的过程就是DOM事件流
  3. DOM事件流分为3个阶段:
    (1)捕获阶段
    (2)当前目标阶段
    (3)冒泡阶段
    例如:我们给一个div注册了点击事件:
    先从Document节点先接收到点击事件,因为没有做处理程序,不会执行任何操作
    向下传播,到Element html 节点,执行以上操作,再往下传播,到Element body 节点,再到Element div 节点 , 其中的节点都会接收到此点击事件,若有具体的事件处理程序就执行,没有就往下依次传播,以上阶段称为捕获阶段

div去执行,称为当前目标阶段

div执行完,会传播到Element body 节点,接收到了此点击事件,没有任何操作,再往上依次传播到Document节点,以上阶段称为冒泡阶段

捕获阶段:由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接收的过程
冒泡阶段:事件由最具体的元素接收,逐级向上传播到DOM最顶层节点的过程

  1. JS代码只能执行捕获或者冒泡中的一个阶段,onclick只能得到冒泡阶段,对于addEventListener(‘type’, listener, useCapture) 的第三个参数若是true,表示事件捕获阶段调用事件处理程序,第三个参数若是false,表示事件冒泡阶段调用事件处理程序。
  2. 有些事件没有冒泡的:onbur , onfocus, onmouseenter, onmouseleave
<body>
     <div class="father">
         <div class="son">儿子</div>
     </div>
     <script>
        //  最里层的div
         var son = document.querySelector('.son');
         son.addEventListener('click',function(e){
             alert('son');
         },false);

        //  father层的div
         var father = document.querySelector('.father');
         father.addEventListener('click',function(e){
             alert('father');
         },false);

        //   最高级的大盒子
        document.addEventListener('click',function(e){
             alert('document');
         },false);

        //  对于以上代码:(体会冒泡阶段)
        //  点击儿子盒子,会依次弹出 son  father  document
        //  点击父亲盒子,会依次弹出  father  document
        //  点击document盒子,会依次弹出 document
     </script>
 </body>

事件对象

事件对象代表事件的状态,比如键盘按键的状态,鼠标的位置;
事件发生后,跟事件相关的信息数据的集合都放到这个对象里

  1. 事件对象写到监听函数的小括号里面的,当形参来看
  2. 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
  3. 事件对象是事件一系列相关数据的集合,和事件相关的,比如鼠标点击里面就包含了鼠标的相关信息,比如鼠标坐标,若是键盘事件,里面就包含了键盘事件的信息,按的是哪一个键等
  4. 事件对象是自定义来命名的,常常写event , evt 和e
  5. 事件对象有兼容性问题(了解),就是旧版本的 IE,会识别 window.event
<button>方式</button>
     <script>
        //  eventTarget.onclick = function(event){}
       
        //  eventTarget.addEventListener('click',function(event){})
     
        var btns = document.querySelector("button");
        // btns.onclick = function(e){
        //     console.log(e);
        // }
        btns.addEventListener('click',function(e){
            console.log(e);
        })
     </script>
</body>

1. 事件对象的常见的属性和方法

1. e.target 返回触发的对象

区别于this:
e.target 点击了那个元素,就返回那个元素
this 那个元素绑定了这个点击事件,就返回那个元素

<body>
     <div>123</div>
     <ul>
         <li>1</li>
         <li>2</li>
         <li>3</li>
     </ul>
     <!-- 给div注册点击事件 -->
     <script>
      
        // 1.e.target  返回触发的对象(元素)
        var div = document.querySelector('div');
        div.addEventListener('click',function(e){
            console.log(e.target);
            //效果就是当点击时,控制台输出<div>123</div>
            console.log(this);
            //此时的this效果和target相同
        })
        // this  返回的是绑定事件的对象(元素)
     
        // 重点:区分二者
        
        var ul = document.querySelector('ul');
        ul.addEventListener('click',function(e){
            //因为给ul绑定了事件 ,所以this 就指向了ul
            console.log(this);

            //e.target 指向我们点击的那个对象,就是谁触发了这个事件,
            //我们点击li  ,因为有冒泡,也会触发这个点击,所以e.target指向li
            console.log(e.target);
        })
        
     </script>

2. e.type 返回事件的类型 比如:click mouseover 不带on

<body>
     <div>123</div>
      <script>
          var div = document.querySelector('div');
          div.addEventListener('click',fn);
           function fn(e){
               console.log(e.type);//click
           }
      </script>
</body>

3. e.preventDefault() 阻止默认的事件(行为)

<body>
     <a href="http://www.baidu.com">百度</a>
     <button>提交</button>
      <script>
//  阻止默认的事件(行为) :为了让链接不跳转,或者提交按钮不提交

          var a = document.querySelector('a');
          a.addEventListener('click',fn);
           function fn(e){
               e.preventDefault();
           }
           var btn = document.querySelector('button');
           btn.addEventListener('click',fn);
           function fn(e){
               e.preventDefault();
           }
      </script>
</body>

4. e.stopPropagation() 阻止事件冒泡阶段

<body>
     <div class="father">
         <div class="son">儿子</div>
     </div>
     <script>
        //  最里层的div
         var son = document.querySelector('.son');
         son.addEventListener('click',function(e){
             alert('son');
             e.stopPropagation();//添加后只弹出son 不再向上冒泡
         },false);

        //  father层的div
         var father = document.querySelector('.father');
         father.addEventListener('click',function(e){
             alert('father');
         },false);

        //   最高级的大盒子
        document.addEventListener('click',function(e){
             alert('document');
         },false);
     </script>

2. 利用事件冒泡阶段:事件委托:不是每个子节点单独添加事件监听器,而是将其设置在其父节点上,然后利用冒泡原理影响设置每个子节点(利用事件对象的target获得触发事件对象的子节点,事件冒泡到已经绑定了事件的父节点上,就可以触发事件了)

<body>
     <ul>
         <li>1</li>
         <li>2</li>
         <li>3</li>
         <li>4</li>
     </ul>
     <!-- 要给每个li添加点击事件 -->
     <script>
//  给ul注册点击事件,利用事件对象的target找到当前点击的li,因为点击li,事件会冒泡到ul上
//  ul有注册点击事件,就会 触发事件监听器 
var ul = document.querySelector('ul');
ul.addEventListener('click',function(e){
    // alert('加油,坚持,耐心');
    // 若想点击li时,改变该li的背景色:那需要获取到 触发事件的对象 e.target
    e.target.style.backgroundColor = 'pink';
    

})
     </script>
 </body>

3.常用的鼠标事件

之前学过:onclick onmouseover onmouseout onfocus onblur

<body>
    <div>不想被复制的文字</div>
    <!-- (了解) -->
     <script>
// 1.禁止鼠标右键菜单
// contexmenu 控制何时显示上下菜单
document.addEventListener('contextmenu',function(e){
    e.preventDefault();
})//效果是鼠标右击失效
//2.禁止鼠标选中 
// selectstart  开始选中
document.addEventListener('selectstart',function(e){
    e.preventDefault();
})//效果是鼠标选中失效
     </script>
 </body>

4.鼠标事件对象 MouseEvent

  1. e.clientX 返回鼠标相对于浏览器窗口可视区的x的坐标,(距离可视区左沿的距离)
  2. e.clientY 返回鼠标相对于浏览器窗口可视区的y的坐标,(距离可视区上沿的距离)

当文档比较长时,就是比可视区长:
3. e.pageX 返回鼠标相对于文档页面的x的坐标
4. e.pageY 返回鼠标相对于文档页面的y的坐标

跟随鼠标的图片:(思路要知道)

  1. 鼠标不断移动,使用鼠标移动事件:mousemove
  2. 在页面中移动,给document注册事件
  3. 图片要移动距离,而且不占位置,使用绝对定位
  4. 核心:每次鼠标移动,都会获得最新的鼠标坐标,将x和y坐标作为图片的top和left的值就可以实现移动图片
<style>
        img{
            position:absolute;
        }
    </style>
</head>
<body>
    <img src="imagines/logo02.jpg" alt="">;
    <script>
        var img = document.querySelector('img');
        document.addEventListener('mousemove',function(e){
            var x = e.pageX;
            var y = e.pageY;
            //对于加了定位的,就是position,一定要给个类似于top等的带有px单位的数值
            // img.style.left=x +'px';
            // img.style.top = y+'px';
            // 实现鼠标在图片的中间,将位置往上走图片高度一半,是负的
            img.style.left=x -50+'px';
            img.style.top = y-50+'px';
        })
    </script>
</body>

5.常用的键盘事件

  1. onkeyup 某个键盘按键被松开时触发
  2. onkeydown 某个键盘按键被按下时触发
  3. onkeypress 某个键盘按键被按下时触发,但它不识别功能键,例如:ctrl shift 箭头等等
    三个事件执行顺序:keydown keypress keyup
<script>
        // 利用事件监听器,不加on
        document.addEventListener('keyup', function () {
            console.log('按键弹起触发up');
        })

        document.addEventListener('keydown', function () {
            console.log('按键按下触发 down');
        })

        document.addEventListener('keypress', function () {
            console.log('按键按下触发 press');
        })
    </script>

6.键盘事件对象 KeyboardEvent

键盘事件对象keyCode 属性,返回该键的ASCII码值

<script>
        // 利用键盘事件对象keyCode 属性,判断用户按下哪个键
        document.addEventListener('keyup', function (e) {
            console.log(e.keyCode);
            if(e.keyCode==65){
                alert('你按下的是a键');
            }
        })

        document.addEventListener('keypress', function (e) {
            console.log(e.keyCode);
        })
        //效果就是:按下 a, 输出 97和65


        // 1.keyup 和 keydown 事件不区分字母大小写 a和A得到的都是65
        // 2.keypress  事件区分字母大小写   a得到的是97,A得到的是65
    </script>

模拟京东按键输入内容案例

京东网页中,按下键盘的s键,就可以自动将光标定到搜索框,方便用户输入内容
分析:

  1. 检测用户是否按下s键,若按下s键,就将光标定位到搜索框里面
  2. 用键盘事件对象keyCode 属性,判断用户按下是否为s键
  3. 搜索框获得焦点,使用js里面的 focus() 方法
<body>
    <input type="text" name="" id="">
    <script>
        var search = document.querySelector('input');
        document.addEventListener('keyup', function (e) {
            // console.log(e.keyCode);//先自己手动得到s键对应的ASCII码值是83
            if (e.keyCode == 83) {
                search.focus();
            }
        })
        //是keyup 这样触发事件时,才不会将s写进去
    </script>
</body>

模拟京东快递单号查询案例

就是输入单号时,在上面多出一个框,里面不仅会显示单号的内容,同时单号的字号大一些,看的更清楚
分析:

  1. 快递单号输入内容时,上面的大号字体盒子显示
  2. 表单检测用户输入:给表单添加键盘事件
  3. 把快递单号里面的值value获取过来赋值给大盒子(innerText)作为内容
  4. 若快递单号里面的值为空,则隐藏上面的大号字体盒子
<style>
        .search{
            height: 300px;
            width: 300px;
            margin:auto;
            background-color: pink;
            position: relative;
        }
        .con {
           
            display: none;
            /* position:absolute; */
            height: 200px;
            /* top: 150px;
            left:50px; */
            background-color: red;
            font-size: large;
            font-weight: 900;
            color: blue;
            
        }
        .jg{
         position:absolute;
            height: 50px;
            color:#333;
          
            top: 220px;
            left:50px;

        }
    </style>
</head>

<body>
    <div class="search">
        <div class="con"></div>
        <input type="text" placeholder="请输入你的快递单号" class="jg">

    </div>
    <script>
        var con = document.querySelector('.con');
        var jg = document.querySelector('.jg');
        //表单检测用户输入:给表单添加键盘事件
        jg.addEventListener('keyup', function () {
            if (this.value == '') {
                con.style.display = 'none';
            }
            else {
                con.style.display = 'block';
                con.innerHTML = this.value;
            }
        })
        //keydown  和 keypress 在文本框里面的特点:连个事件触发时,文字还没有落入文本框
        //keyup  事件触发时,文字已经落入文本框了

         //当失去焦点就隐藏这个con盒子
         jg.addEventListener('blur',function(){
            con.style.display = 'none';
         })
         //当获得焦点就显示这个con盒子
         jg.addEventListener('focus',function(){
            if(this.value){
                con.style.display = 'block';
            }
         })
    </script>
</body>
posted on 2021-12-06 00:12  精致猪猪侠  阅读(68)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3