阅读 38

JavaScript的事件问题

事件流

冒泡与捕获

  • 当我们单击一个元素的时候,我们单击的这个动作会从最下层元素向上层传播,这个过程就是冒泡
  • 恰恰相反,当单击这个动作从最上层元素进入最下层元素的过程,就是捕获

事件处理程序

将事件挂载到dom中的方法就是事件处理程序

HTML事件处理程序

  • 在html文档中直接给各个元素添加事件属性,并添加执行代码,以文字来表述就是当单击按钮的时候触发代码

    html事件

  • html事件处理程序的事件流是冒泡过程

DOM0级事件处理程序

  • 在js代码中给各个元素直接添加事件属性,并添加代码,这里的思想与html基本一致,只是在js代码中实现,我们也可以将值设置为null,就可以删除该事件了

    document.querySelector('button').onclick=null
    复制代码
  • 同样的DOM0事件处理程序的事件流也是冒泡过程

DOM2级事件处理程序

  • DOM2级事件处理程序使用DOM专门为添加删除事件准备的两个方法:addEventListener,removeEventListener
  • 他们都接收三个参数,第一个是添加的事件名,第二个要执行的代码,第三个是一个boolean值,默认是false,false表示触发冒泡,true表示触发捕获

事件对象

在我看来,事件对象是一直存在的,当我们触发事件的时候,会生成事件对象的一个实例,我们触发不同的事件类型,那么这个实例也会有所不同,我们会将生成的这个事件对象传入事件处理程序

事件类型有哪些

  1. UI事件:load,error,scroll等
  2. 焦点事件:focus,focusin,focusout,blur,加粗的会冒泡剩下的不会
  3. 鼠标事件:左右中键各种事件
  4. 滚轮事件:这不就是鼠标滚轮进行操作的时候吗
  5. 文本事件:textInput
  6. 键盘事件:keydown,keypress,keyup
  7. 合成事件:剩下的事件不去了解了,具体看红宝书事件部分就是了
  8. 变动事件
  9. 变动名称事件

事件对象的公共属性与方法

不同的事件类型创建的事件对象是不同的,但他们也有共同的属性与方法

属性:

  • bubbles,事件是否冒泡
  • cancelable,事件是否能够取消默认行为
  • currentTarget,事件处理程序当前正在处理事件的那个元素
  • target,事件的目标元素
  • trusted,事件是否自定义
  • type,事件类型(String)
  • view,与事件关联的抽象视图,等同于发生事件的window
  • defaultPrevented,事件是否调用了preventDefault方法
  • detail,保存事件的细节信息
  • eventPhase,调用事件处理程序的阶段,1捕获,2处于目标阶段,3冒泡

方法:

  • preventDefault(),取消事件默认行为
  • stopImmediatePropagation(),取消事件进一步捕获或冒泡,阻止任何事件处理程序被调用
  • stopPropagation(),取消事件进一步捕获或冒泡

不同事件对象的不同属性

关于鼠标的属性

  • clientX,clientY,表示事件发生时鼠标指针在视口中的位置
  • pageX,PageY,表示事件发生时鼠标指针在页面中的位置
  • screenX,screenY,表示事件发生时鼠标指针在电脑屏幕的位置
  • button属性,储存鼠标的点击状态

0:没有按键,1:按了左键,2:按了右键,3:按了左键和右键,4:按了中间键,5:按了左键和中间键,6:按了右键和中间键,7:三个键都按了

关于键盘的属性

  • shiftKey,ctrlKey,altKey,metakey,相应的键是否被按下
  • keyCode,储存按下的键的键码

当然还有更多的属性就不一一列举了

事件委托

我们为每一个具体的dom元素添加事件的行为或许会使得事件处理函数变得过多了,这或许会导致内存和性能的问题,事件委托就用来处理这件事

  • 事件委托通过事件冒泡的特性来解决这件事,例如当我们在最底层的一个元素上执行了点击事件的话这个行为会传递到顶层的document对象上面,那么我们只要在顶层的document里去判断这个行为是从哪里传递过来的,然后执行相应的代码就可以了

  • 下面测试事件委托,事件的path属性就存储了冒泡过程经历的所有元素

    <body>
        <div id="c" > 1
            <div id="b">            2 
               <div id="a">                3
                </div>        </div>    </div>
        <script>
            let c=document.getElementById('c')
            c.addEventListener('click',function(e){
                console.log(e)//这里打印事件对象,能够查看事件对象的所有属性方法!
                switch(e.path[0].id){
                    case 'a':
                     console.log('执行了3');
                      break;
                    case 'b':
                    console.log('执行力b');
                     break;
                       case 'c':
                     console.log('执行了c');
                     break;
                       default:console.log('按到别的地方了')
                }
            })
        </script>
    </body>
    复制代码
  • 在浏览器中测试发现达到预期要求

事件对象的参数如上

自定义事件

document对象提供了createEvent方法来创建event对象,这个方法接收一个参数,表示要创建的对象类型,这个地方就不深究了。。