JavaScript - day13

39 阅读2分钟

一、事件周期

从事件发生到所有事件处理函数执行完毕的全过程
  • 三个阶段
    1. 捕获阶段:由外向内,记录要发生的事件有哪些
    2. 目标优先触发:目标元素就是当前点击的实际发生事件的元素
    3. 冒泡触发:由内向外,依次执行之前记录的要发生的事件
<div id="max">
    <div id="middle">
        <div id="min"></div>
    </div>
</div>
<script>
    var divs = document.querySelectorAll('div')
    divs.forEach(div=>{
        div.onclick = function(){
            alert(div.id)
        }
    })
</script>

二、获取事件对象event

  • 主流:会自动作为事件处理函数的第一个形参传入
  • 老IE(8-):event
  • 兼容:event
<button id="btn">按钮</button>
<script>
    btn.onclick = function(e){
        console.log(e);//主流浏览器
        console.log(event);//老IE
        // 兼容写法
        e = e||event
        console.log(e);
        console.log(event);
    }
</script>

三、得到event可以做的

3.1 获取鼠标的坐标:

  • 鼠标相对于屏幕的坐标:e.screenX/Y
  • 鼠标相对于窗口/客户端/文档显示区域的坐标:e.clientX/Y
  • 鼠标相对于网页的坐标:e.pageX/Y
<script>
    // 获取鼠标相对于屏幕的坐标
    /* window.onmousemove = function(e){
        console.log(e.screenX);
        console.log(e.screenY);
    } */
    // 获取鼠标相对于窗口/客户端/文档显示区域的坐标
    /* window.onmousemove = function(e){
        console.log(e.clientX);
        console.log(e.clientY);
    } */
    // 获取鼠标相对于网页的坐标
    window.onmousemove = function(e){
        console.log(e.pageX);
        console.log(e.pageY);
    }
</script>

3.2 阻止事件冒泡:

  • 主流:e.stopPropagation()
  • 老IE:e.cancelBubble=true
  • 兼容:e.cancelBubble=true
<script>
    // 阻止事件冒泡 主流浏览器
    var divs = document.querySelectorAll('div')
    /* divs.forEach(div=>{
        div.onclick = function (e) {
            alert(this.className)
            e.stopPropagation()
        }
    }) */
    // 阻止事件冒泡 老IE
    for(var i = 0; i < divs.length; i++) {
        divs[i].onclick = function (e) {
            alert(this.className)
            var e = event
            e.cancelBubble = true
        }
    }
</script>

3.3 利用冒泡排序/事件委托

1. 开发中常用,提升网页性能,有了它我们的事件函数也可以换为箭头函数了
2. 优化:如果多个子元素定义了相同或者相似的事件操作,最好只给父元素定义一次,因为每绑定一个事件函数,其实都是创建了一个事件对象,创建的事件对象越多,网站性能越差。
3. 目标元素target:你点击的是哪一个,他永远就是那一个,不会变化的
  • 主流:e.target
  • 老IE:e.srcElement
  • 兼容:e.srcElement

3.4 阻止浏览器的默认行为:

比如:a标签默认就可以跳转,提交按钮可以提交表单,右键自带一个弹出框,F12自带一个控制台,F11自带全屏功能,F5自带刷新功能
  • 主流:e.preventDefault()
  • 老IE:e.returnValue=false
  • 兼容:e.returnValue=false
<script>
    // 阻止a标签默认的跳转
    a.onclick = (e) => {
        e.preventDefault()
    }
    // 阻止表单提交
    /* form.onsubmit = function(){
        return false
    } */
    submit.onclick = e => e.preventDefault()
    // 阻止鼠标右键事件
    window.oncontextmenu = e => e.preventDefault()
</script>

四、鼠标和键盘事件

  • 右键事件:window.oncontextmenu
  • 键盘事件
    1. window.onkeydown - 按住和按下,任何键盘按键都可以触发
    2. window.onkeypress - 按住和按下,只有字母、数字、回车、空格可以触发,其他按键不行
    3. window.onkeyup - 松开,任何键盘按键都可以触发(比手速的游戏)
  • 获取键盘的键盘码: e.keyCode
<script>
    // 阻止当按住和按下F12的时候的默认操作
    window.onkeydown = e => {
        if (e.keyCode == 123) {
            e.preventDefault()
        }
    }
</script>

五、扩展

  • 图片的加载速度,比js的执行速度慢,所以js执行完,图片可能还没有加载完,解决:img.onload事件 - 图片加载完毕后才会执行的代码
  • 如果事件委托了
    1. 判断目标元素是什么标签:xx.nodeName; - 得到标签名,是全大写组成的
    2. 事件处理函数可以写为箭头函数->this就会失效,所以必须使用目标元素target
  • this的指向
    1. 单个元素绑定事件,this->这个元素
    2. 多个元素绑定事件,this->当前元素
    3. 箭头函数,this->外部对象