前端:事件 | 青训营笔记

112 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

内容

注册事件的两种方式

<script>
        // 1 传统方式注册事件 注册事件由唯一性 会覆盖
        var btns = document.querySelectorAll('button');
        btns[0].onclick = function() {alert('hi~')};
        btns[0].onclick = function() {alert('hao a u')};

        // 2 事件监听注册事件 addEventListener
        // (1) 里面的事件类型是字符串 必定加引号 且不带on
        // (2) 同一个元素 同一个事件可以添加多个监听器(事件处理程序)
        btns[1].addEventListener('click', function(){
            alert(22);
        })
        btns[1].addEventListener('click', function(){
            alert(33);
        })
     </script>  

attacheEvent注册事件(了解)

btn[2].attachEvent('onclick', function() {
            alert(11);
        });

删除事件(解绑)

<script>
    var divs = document.querySelectorAll('div');
    // 1 传统方式删除事件
    divs[0].onclick = function() {
        alert(11);
        divs[0].onclick =  null;
    }
    // 2 removeEventListener 删除事件
    divs[1].addEventListener('click', fn); 
     /* 1里面的fn 不需要调用加小括号
        2 不能传入匿名函数,否则后序无法删除*/
    function fn() {
        alert(22);
        divs[1].removeEventListener('click', fn);   
    }
    // 3 
    divs[2].attacEvent('onclick', fn1)
    function fn1 () {
        alert(33);
        divs[2].detachEvent('onclick', fn1);
    }
</script>

事件流

事件流描述的是从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流 事件流分为三个阶段:
1. 捕获阶段 2. 当前目标阶段 3. 冒泡阶段

image.png

<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 -> body -> html -> document 
    // document -> html -> body -> father -> son
    /* 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>

事件对象

image.png

image.png

<script>
    // 事件对象
    var div = document.querySelector('div');
    div.onclick = function(e) {
        console.log(e);
    }

    div.addEventListener('click', function(event) {
        console.log(event);
    })

    // 兼容性写法
    div.onclick = function(e) {
        // console.log(e);
        // console.log(window.event);
        e = e || window.event;
        console.log(e);
    }

    // 1 event 就是一个事件对象 写到我们的监听函数的 小括号里面 当形参来看
    // 2 事件对象只有有了事件才会存在,是系统给我么自动创建的不需要我们传递参数
    // 3 事件对象 是 我们事件的一系列相关数据的集合 跟时间相关的 比如鼠标点击里面就包含了鼠标的关键信息
    // 包括鼠标坐标、target等等
    // 4 事件对象可以自己命名 比如event、evt、e
    // 5 事件对象也有兼容性问题 IE678 通过 window.event 
</script>

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

image.png

this vs e.target区别

    // 1 e.target 返回的触发事件的对象(元素)  this 返回的是绑定事件的对象(元素)
    // 区别:e.target点击了哪个元素 就返回哪个元素
    // this 哪个元素 绑定 了这个点击事件 就返回谁
    var div = document.querySelector('div');
    div.addEventListener('click', function(e) {
        console.log(e.target);  // 点击son 返回son
        console.log(this);/* 点击son 返回button */
    })

阻止事件冒泡

<script>
    // 阻止冒泡 dom 推荐的标准 stopPropagation()
    var son = document.querySelector('.son');
    son.addEventListener('click', function(e) {
        alert('son');
        e.stopPropagation();
    })
    var father = document.querySelector('.father');
    father.addEventListener('click', function() {
        alert('father');
    })
    document.addEventListener('click', function() {
        alert('document');
    })
</script>

事件委托

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

<script>
    // 事件委托的核心原理:给父节点添加侦听器 利用事件冒泡影响每一个节点
    var ul = document.querySelector('ul');
    ul.addEventListener('click',(e) => {
        alert('应是绿肥红瘦');
        e.target.style.backgroundColor = 'white';   // 用e.target找到点击对象
    })
</script>

禁止选中文字和右键菜单(了解)

// 1 contextmenu 禁用右键菜单
    document.addEventListener('contextmenu', function(e) {
        e.preventDefault();
    })
    // 2 禁止选中文字 selectstart
    document.addEventListener('selectstart', function(e) {
        e.preventDefault();
    })

鼠标事件对象

// 鼠标事件对象 MouseEvent
    document.addEventListener('click', function(e) {
        // 1 client 鼠标在可视区的x和y坐标
        console.log(e.clientX);
        console.log(e.clientY);
        console.log('---------------------');

        // 2 page 鼠标在页面文档的x和y坐标
        console.log(e.pageX);
        console.log(e.pageY);
        console.log('---------------------');

        // 3 screen 鼠标在电脑屏幕的x和y坐标(了解)
        console.log(e.screenX);
        console.log(e.screenY);

    })

图片跟随鼠标实例

<script>
    var pic = document.querySelector('img');
    var img = document.querySelector('img');
    document.addEventListener('mousemove', function(e) {
        // 1 mousemove 只要鼠标移动1px.就会触发事件
        // console.log(1);

        // 2核心原理 移动鼠标 记录新的坐标 把这个x 和 y 坐标作为图片的left 和 top 值
        var x = e.pageX;
        var y = e.pageY;
        // 3 千万别忘加'px' 只有数组无法识别
        img.style.left = x +'px';
        img.style.top = y + 'px';
    })
</script>

常用键盘事件

// 常用键盘事件
    // 1 keyup 按键弹起的时候触发
    /* document.onkeyup = function() {
        console.log('我弹起了');

    } */
    document.addEventListener('keyup', function() {
        console.log('我谈起了');
    })
    // 2 keydown 按键按下的时候触发 按下的时候触发 能识别功能键 比如 ctrl shift 左右箭头
    document.addEventListener('keydown', function() {
        console.log('我按下了down');
    })
    // 3 keypress 按键按下时触发 不能识别功能键 
    document.addEventListener('keypress', function() {
        console.log('我按下了down');
    })
    // 4 三个事件执行的顺序 keydown keypress keyup

keyCode 判断用户按下哪个键

// 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
    // 1 我们的keyup 和 keydown 事件 不区分字母大小写 a 和 A 得到的都是65
    // 2 我们的keypress 事件 区分大小写
    document.addEventListener('keyup', function(e) {
        // console.log(e);
        console.log('up' + e.keyCode);
        // 我们可以利用keycode 返回的ASCII码值来判断用户按下了哪个键
        if (e.keyCode == 65) {
            alert('您按下了a键');
        } else {
            alert('您没有按下了a键');
        }
    })
    document.addEventListener('keypress', function(e) {
        console.log('press:' + e.keyCode);
    })

实例

var jd_input = document.querySelector('.id') ;
    var jd_con = document.querySelector('.con');
    jd_input.addEventListener('keyup', function() {
        if (jd_input.value != '')  {
            jd_con.innerHTML = this.value;
            jd_con.style.display = 'block';
        } else {
            jd_con.style.display = 'none';
        }
    })  
    // 1 不能keydown,文字还没输入进入input,value就被赋值给innerHTML
    // 2 更不能keypress,除上述问题外,还不能使用功能键Backspace等
    jd_input.addEventListener('blur', function() {
        jd_con.style.display = 'none';
    })
    jd_input.addEventListener('focus', function() {
        if (jd_input.value != '') {
            jd_con.style.display = 'block';
        }
    })

参考资料:黑马程序员JavaScript核心教程,前端基础教程,JS的DOM BOM操作教程_哔哩哔哩_bilibili

附:如有错误,恳请指正,侵权必删: