JavaScript事件

119 阅读8分钟

JavaScript事件简介

  1. 事件介绍: 当我们点击一个按钮的时候,会弹出一个对话框。

在JavaScript中, “点击”这个事情就看作一个事件。“弹出对话框”其实就是我们在点击事件中做的一些事。

  1. 事件三要术
  • 事件源:触发事件的元素 ->如:按钮

  • 事件类型:事件如何触发,点击,双击, 移动 .... 如: click 点击事件

  • 事件处理函数:事件做什么

    var oDiv = document.queryselector( "div ")
    
    oDiv.onclick = function () {}
    //谁来触发事件 => oDiv =>这个事件的事件源就是oDiv
    //触发什么事件=> onclick =>这个事件类型就是click
    //触发之后做什么=> function () {}=→>这个事件的处理函数
    

获取事件对象

在每一个事件处理函数的行参位置,默认第一个就是事件对象

oDiv.onclick = function(e) {}
    console.log(e)
}

IE兼容写法:

oDiv.onclick = function(e) {
    e = e || window.event
    console.log(e.X轴坐标点信息)
    console.log(e.Y轴坐标点信息)
}

点击事件的光标坐标获取

  1. 相对事件源(你点击的元素)offsetx,offsetY,是相对于你点击的元素的边框内侧开始计算

    <body>
        <div></div>
        
        <script>
            var oDiv = document.querySelector('div')
            
            //注册点击事件
            oDiv.onclick = function (e) { 
                //事件对象兼容写法
                e = e || window.event
                
                console.log(e.offsetx)
                console.log(e.offsetY)
            }
        </script>
    </body>
    
  2. 相对于浏览器窗口(clientx,clientY)是相对于浏览器窗口来计算的,不管你页面滚动到什么情况,都是根据窗口来计算坐标

     //注册点击事件
     oDiv.onclick = function(e) {
         //事件对象兼容写法
         e = e || window.event
         
         console.log(e.clientx)
         console.log(e.clientY)
     }
    
  3. 相对于页面(pageX,pageY)是相对于整个页面的坐标点,不管有没有滚动,都是相对于页面拿到的坐标点

     //注册点击事件
     oDiv.onclick = function(e) {
         //事件对象兼容写法
         e = e || window.event
             
         console.log(e.pagex)
         console.log(e.pageY)
     }
    

事件

  • 鼠标事件

鼠标移入移除改变事件

const h11 = document.getElementById ('h1') ;
//鼠标移入
h11.onmouseover = function() {
    h11.style.color = "blue' ;
}
//鼠标移出
h11.onmouseout = function() {
    h11.style.color = " red " ;
}
  • 表单事件

    实际项目开发中
    处理表单提交事件方式
        1.使用普通按钮代替 submit提交按钮
            <input type="submit"/>submit提交按钮
            <input type="button"/>普通按钮
    
        2.手动跳转代替默认action动作
            location.href = url地址
            
    
    • change:表单内容改变事件
    • input:表单内容输入事件
    • submit:表单提交事件
  • 焦点事件

失去焦点onblur

获取焦点onfocus

  • 键盘事件

只给能在页面上选中的元素(表单元素)和document来绑定键盘事性

注:不能给页面上一个div元素,设置键盘事件的

document.onkeyup = function()   {// code.. }
oInput.onkeyup = function ()    {// code.. }
  1. 确认按键

键盘上每一个按键都有一个自己独立的编码,靠这个编码来确定按下的是哪个按键,通过事件对象.keyCode或者事件对象.which来获取,要有两个,因为FireFox2.0不支持keycode所以要which

document.keyup = function (e) {
    //事件对象的兼容写法
    e = e || window.event
    
    //获取键盘码的兼容写法
    var keyCode = e.keyCode || e.which
    
    console.log(keyCode)
}

2. 常见的键盘码

  • 8:删除键(delete)
  • 9:制表符(tab)
  • 13:回车键(enter)
  • 16:上档键(shift)
  • 17:ctrl键
  • 18:alt键
  • 27:取消键(esc)
  • 32:空格键(space)
  1. 组合按键

组合案件最主要的就是alt / shift / ctrl三个按键,在我点击某一个按键的时候判断―下这三个键有没有按下,有就是组合了,没有就是没有组合

事件对象里面也为我们提供了三个属性:

  • altKey : alt 键按下得到 true,否则得到 false
  • shiftKey : shift键按下得到true,否则得到 false
  • ctrlKey : ctrl 键按下得到true,否则得到 false

我们就可以通过这三个属性来判断是否按下了

document.onkeyup = function(e) {
    e = e || window.event
    keyCode = e.keyCode || e.which
    
    if (e.altKey && keyCode === 65) {
        console.log('你同时按下了alt和a' )
    }
}
  • 浏览器事件

    • load:页面全部资源加载完毕
    • scroll:浏览器滚动的时候触发
    • resize:页面大小事件
  • 触摸事件

    • touchstart:触摸开始事件
    • touchend:触摸结束事件
    • touchmove:触摸移动事件

事件的绑定方式

DOM0级

  1. 事件属性方式
  • 缺点:只能给一个元素注册一个事件,绑定一个事件,后一个会覆盖前一个

  • 优点:符合“行为,样式,结构”相分离;便于操作当事对象;方便读取事件对象

    oDiv.onclick = function() {
        console.log('我是第一个事件')
    }
    oDiv.onclick = function() { 
        console.log('我是第二个事件')
    }
    
  1. 赋值式

DOM2级

  1. 事件监听
  • addEventListener:非IE78下使用

语法:元素.addEventListener('事件类型',事件处理函数,冒泡还是捕获)

oDiv.addEventListener("click", function() {
    console.log('我是第一个事件')
}, false)

oDiv.addEventListener("click", function() {
    console.log('我是第二个事件')
}, false)
//当你点击div的时候,两个函数都会执行,并且会按照你注册的顺序执行
//先打印我是第一个事件再打印我是第二个事件
//注意:事件类型的时候不要写on,点击事件就是click,不是onclick
  • attachEvent : IE78下使用

语法:元素.attachEvent("E件类型",事件处理函数)

oDiv.attachEvent("onclick", function() {
    console.log('我是第一个事件')
})

oDiv.attachEvent("onclick", function() {
    console.log('我是第二个事件')
})
//当你点击 div的时候,两个函数都会执行,并且会按照你注册的顺序倒叙执行
//先打印我是第二个事件再打印我是第一个事件
//注意:事件类型的时候要写on,点击事件就是onclick
  • 区别:
  1. 事件赋值与事件监听:同事件属性相比,实现了结构与行为分离
  2. 事件赋值与事件监听:事件监听方式 后面的事件不会覆盖前面的事件(事件源和事件类型相同)
  3. 注册事件的时候事件类型参数的书写

addEventListener:不用写on

attachEvent:要写on

  1. 执行顺序

addEventListener:顺序注册,顺序执行

attachEvent:顺序注册,倒叙执行

事件解绑

解绑赋值式绑定事件

  • btn2.onclick = null2.解绑事件监听
  • btn3.removeEventListener( 'click',事件处理函数名)

事件的执行机制

1. 事件的传播

当元素触发一个事件的时候,其父元素也会触发相同的事件,父元素的父元素也会触发相同的事件。也就是说,页面上任何一个元素触发事件,都会一层一层最终导致window的相同事件触发,前提是各层级元素得有注册相同的事件,不然不会触发

注意:只会传播同类事件,只会从点击元素开始按照html的结构逐层向上元素的事件会被触发,内部元素不管有没有该事件,只要上层元素有该事件,那么上层元素的事件就会被触发

2. 事件传播方向

  • 事件冒泡

从事件目标的事件处理函数开始,依次向外,直到window的事件处理函数触发也就是从下向上的执行事件处理函数

特点:事件传播方向,由内向外传

  • 事件捕获

从window的事件处理函数开始,依次向内,只要事件目标的事件处理函数执行也就是从上向下的执行事件处理函数

  • 实现:事件捕获和事件冒泡

addEventListener的第三个参数决定了是事件捕获还是事件冒泡:

true:表示注册的事件在捕获阶段触发

false:表示注册的事件在冒泡阶段触发-----默认值

3. 事件处理三个阶段

  • 事件的处理过程主要有三个阶段:捕获阶段,目标阶段,冒泡阶段;
  • W3C︰任何事件发生时,先从顶层开始进行事件捕获,直到事件触发到达事件源,再从事件源向上进行事件捕获(事件冒泡)。
  • 标准浏览器: addEventListener(" click",function," true")方法,若第三参数为true,则采用事件捕获。若为false,则采用事件冒泡。
  • IE浏览器只支持事件冒泡,不支持事件捕获,所以它不支持addEventlistener( click function ,'true')方法所以ie浏览器使用ele.attachEvent( ondlick doSomething)。

4. 阻止事件传播

  • 事件传播的阻止方法:

    • 在w3C中,使用stopPropagation()方法
    • 在IE下使用cancelBubble = true方法。
  • 兼容写法

    if (e.stopPropagation) {
        e.stopPropagation()
    } else {
        e.cancelBubble = true
    }
    
    e.stopPropagation?e.stopPropagation():e.cancelBubble = true
    

5. 事件委托

这个时候,当我们点击li的时候,也可以触发ul的点事件,并且在事件内不,我们也可以拿到你点击的到底是ul还是li,这个时候,我们就可以把li的事件委托给ul来做

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>

    <script>
        var oUl = docuemnt.querySelector('ul')
        
        oUl.addEventListener("click", function(e) {
            e = e || window.event
            var target = e.target || e.srcElement
            
            //判断你点击的是Li
            if (target.nodeName.toUpperCase === 'LI") {
                //确定点击的是Li
                //因为当你点击在ul 上面的时候,nodeName应该是‘UL"1/去做点击Li的时候该做的事情了
                console.log('我是1i,我被点击了')
            }
        }
    </script>
</body>
  • 事件委托的书写

元素的事件只能委托给结构父级或者再结构父级的同样的事件上,li的点击事件,就不能委托给ul的鼠标移入事件,li的点击事件,只能委托给ul或者在高父级的点击事件上

  • 优点

减少了事件绑定的数量;对后来动态创建的元素依然有效,解决动态添加的元素节点无法绑定事件的问题;减少事件的冗余绑定,节约了事件资源。

  • 缺点

    • 事件委托基于冒泡,对于不冒泡的事件不支持。
    • 层级过多,冒泡过程中,可能会被某层阻止掉。
    • 理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理。所以建议就近委托,比如在table上代理td,而不是在document上代理td。
    • 把所有事件都用代理就可能会出现事件误判。比如,在document中代理了所有button的click事件,另外的人在引用改js时,可能不知道,造成单击button触发了两个click事件。

默认行为

默认行为,就是不用我们注册,它自己就存在的事情

  1. 阻止默认行为

    e.preventDefault0 //非IE使用
    e.returnValue = false // IE使用
    
  2. 兼容写法

     <a href="https://www.baidu.com">点击我试试</a>
     
     <script>
         var oA = document.querySelector('a')
         
         a.addEventListener('click', function(e) {
             e = e || window.event
             
             console.log(this.href)
             
             e.preventDefault ? e.preventDefault(): e.returnValue = false
         })
     </script>