DOM事件——鼠标事件和键盘事件

DOM事件基础就要结束了,今天整理一下,发上来。做的小案例和练习,有的我没有放html和css,一般都是使用ul和li做的,大家可以自行搭建吧,主要是学习JavsScript的,但是也不能忘记前面学习的。

 

事件的注册和解绑

两种注册绑定事件的方式

    <script>
        // 给li注册点击事件
        // 传统方式
        var lis = document.querySelector('ul').querySelectorAll('li');
        // for (var i = 0; i < lis.length; i++) {
        //     lis[i].onclick = function () {
        //         alert('li被点击了');
        //     }
        //     // lis[i].onclick = function () {
        //     //     alert('传统方式的唯一性'); // 这个注册事件把上面一个事件给覆盖掉了
        //     // }
        // }
        // 监听方法注册事件
        for (var i = 0; i < lis.length; i++) {
            lis[i].addEventListener('click', fn);
        }

        function fn() {
            alert('add点击实现li');
            alert('可以注册多个事件');
        }
    </script>

 

两种解除事件绑定的方式 

    <script>
        // 给li注册点击事件
        // 传统方式
        var lis = document.querySelector('ul').querySelectorAll('li');
        var lilis = document.querySelector('.ul').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            lis[i].onclick = function () {
                alert('li被点击了');
                // 解绑事件
                // 传统方式的解绑
                this.onclick = null;
            }
            // lis[i].onclick = function () {
            //     alert('传统方式的唯一性'); // 这个注册事件把上面一个事件给覆盖掉了
            // }
        }
        // 监听方法注册事件
        for (var i = 0; i < lilis.length; i++) {
            lilis[i].addEventListener('click', fn);
        }
        for (var i = 0; i < lilis.length; i++) {
            lilis[i].removeEventListener('click', fn);
        }

        function fn() {
            alert('add点击实现li');
            alert('可以注册多个事件');
        }
    </script>

 

DOM事件的事件流

代码中的注释有详细解释

其中包含阻止冒泡阶段

利用冒泡可以进行事件委托,就是不给子节点添加监听方法,给父节点添加监听方法来影响子节点。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            position: relative;
            width: 400px;
            height: 400px;
            background-color: pink;
            margin: 100px auto;
        }

        ul {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            margin: auto;
            width: 200px;
            height: 200px;
            background-color: purple;
        }
    </style>
</head>

<body>
    <div>
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
    </div>
    <script>
        // 事件流:事件的传播过程叫做事件流
        // addEventListener(type, listener[, useCapture])
        var div = document.querySelector('div');
        var ul = document.querySelector('ul');
        var lis = document.querySelectorAll('li');
        // 捕获阶段:doucument-->html-->body-->div-->ul-->li
        // 冒泡阶段:doucument<--html<--body<--div<--ul<--li
        // 给li注册点击事件  
        for (var i = 0; i < lis.length; i++) {
            lis[i].addEventListener('click', function (e) {
                alert('方法监听实现li被点击');
                // 阻止事件冒泡 给li使用方法阻止冒泡,div的事件就不会触发了
                e.stopPropagation(); // div的事件就没有执行了 因为阻止了li的冒泡阶段
            })
        }
        // 给div注册点击事件  
        // 先执行的是li的事件,然后冒泡得到div的事件  因为方法监听的第三个参数省略不写得到的是冒泡阶段
        // 把第三个参数设为:true 得到的是捕获阶段:先得到div事件,再得到li的事件
        // 为false或者省略不写 得到的是冒泡阶段 先得到li事件,再得到div的事件
        div.addEventListener('click', function () {
            alert('div被点击');
        }, false)
    </script>
</body>

</html>

事件对象 

 鼠标事件

实现案例:图片跟着鼠标移动。

    <script>
        // 常用事件对象的方法和属性
        // preventDefault()方法 阻止默认事件
        // target属性:返回的是触发事件的对象元素
        // type属性:返回的是事件类型
        // 常用的事件对象  鼠标事件和键盘事件
        // 鼠标常用事件:contextmenu selectstart
        // contextmenu  禁止鼠标右键   preventDefault方法 阻止默认行为
        // selectstart  禁止文字被选中
        var lis = document.querySelector('ul').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            // 在li上鼠标是无法右键弹出菜单的
            lis[i].addEventListener('contextmenu', function (e) {
                e.preventDefault();
                e.returnValue; //兼容ie678的写法
            })
            // li中的文字无法被选中
            lis[i].addEventListener('selectstart', function (e) {
                e.preventDefault();
            })
        }
        // 鼠标事件对象中常用的属性 client系列:是鼠标位置距离可视窗口水平和垂直的距离
        // page系列:是鼠标位置距离页面顶部(左上角)水平和垂直距离
        document.addEventListener('click', function (e) {
            console.log(e.clientX);
            console.log(e.clientY);
            console.log(e.pageX);
            console.log(e.pageY);
        })
        // 鼠标事件对象的案例:图片跟随鼠标移动
        var img = document.querySelector('img');
        document.addEventListener('mousemove', function (e) {
            // 坑:一定要加单位  px
            var x = e.clientX;
            var y = e.clientY;
            img.style.top = y - 50 + 'px';
            img.style.left = x - 40 + 'px';
        })
    </script>

 

键盘事件 

 案例:判断用户输入的字母是否为s,是的话表单自动获得焦点

    <script>
        // 键盘事件
        // keyup:键盘弹起触发  文本不会录入文本框
        // keydown:键盘按下触发 不识别字母大小写 文本会录入文本框
        // keypress:键盘下触发
        // keyCode 可以识别 返回的是字符对应的ASCII值
        // 实现按下s键,搜索框自动获焦
        var search = document.querySelector('input');
        document.addEventListener('keyup', function (e) {
            if (e.keyCode == 83) {
                search.focus();
                console.log(e.keyCode);
            }
        })
    </script>

 

案例:查询快递单号 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .search {
            position: relative;
            width: 178px;
            margin: 100px;
        }

        .con {
            display: none;
            position: absolute;
            top: -40px;
            width: 171px;
            border: 1px solid rgba(0, 0, 0, .2);
            box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
            padding: 5px 0;
            font-size: 18px;
            line-height: 20px;
            color: #333;
        }

        .con::before {
            content: '';
            width: 0;
            height: 0;
            position: absolute;
            top: 28px;
            left: 18px;
            border: 8px solid #000;
            border-style: solid dashed dashed;
            border-color: #fff transparent transparent;
        }
    </style>
</head>

<body>
    <div class="search">
        <div class="con">123</div>
        <input type="text" placeholder="请输入您的快递单号" class="jd">
    </div>
    <script>
        // 快递单号输入内容时, 上面的大号字体盒子(con)显示(这里面的字号更大)
        // 表单检测用户输入: 给表单添加键盘事件
        // 同时把快递单号里面的值(value)获取过来赋值给 con盒子(innerText)做为内容
        // 如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子
        var con = document.querySelector('.con');
        var jd_input = document.querySelector('.jd');
        jd_input.addEventListener('keyup', function () {
            // console.log('输入内容啦');
            if (this.value == '') {
                con.style.display = 'none';
            } else {
                con.style.display = 'block';
                con.innerText = this.value;
            }
        })
        // 当我们失去焦点,就隐藏这个con盒子
        jd_input.addEventListener('blur', function () {
            con.style.display = 'none';
        })
        // 当我们获得焦点,就显示这个con盒子
        jd_input.addEventListener('focus', function () {
            if (this.value !== '') {
                con.style.display = 'block';
            }
        })
    </script>
</body>

</html>

效果

 

 最后附上我的学习笔记。

DOM事件学习笔记 

###注册事件的两种方式
    传统方式: 
        事件源.事件类型 = 事件处理程序
    方法监听注册
        1.使用addEventListener()方法 存在兼容性问题:支持ie9以上
            事件源.addEventListener('type',listener)
            addEventListener()方法有三个参数
                type:事件类型
                listener:处理函数,也叫监听器,就是事件处理程序的函数
                    这里的处理函数可以写在外面,添加监听时直接调用函数名即可
                useCapture:判断是捕获还是冒泡过程,可选参数
        2.使用attachEvent()方法 ie678支持,使用方法与addEventListener()相同

    两种方式的区别
        1.传统方式注册事件,具有唯一性,简单来说就是同一元素同一个事件只能注册一次
        方法监听注册可以同一元素同一事件可以注册多个监听器
        2.传统方式的事件类型带 on,比如 onclick、onmouseover等
        方法监听的事件类型不带 on,比如 click mouseover等

###删除事件
    传统方式:
        事件源.事件类型 = null
    方法监听方式:
        事件源.removeEventListener('type',listener)

###DOM事件流
    概念:事件的传播过程就是DOM事件流
    事件流的三个阶段
        1.捕获阶段
            事件从最顶层节点(document)往里层找当前目标
        2.当前目标阶段
            监听事件的元素
        3.冒泡阶段
            事件从当前目标往顶层节点找
    方法监听的第三个参数:
        useCapture:
            true —— 捕获阶段
            false\省略不写 —— 冒泡阶段
    事件流注意点
        JS代码只能获取捕获阶段或者冒泡阶段
        有些事件是没有冒泡阶段的:onfocus、onblur、onmouseenter、onmouseleave
        attachEvent()和onclick只能得到冒泡阶段

###事件对象 addEventListener('click',function(e){})
    常用事件一般包括的是鼠标事件和键盘事件
    事件对象的解释
        事件对象是事件的一系列相关数据的集合
        事件对象只有事件存在,才会有事件对象
        事件的处理函数中的一个参数(形参),就是事件对象event都可以
        事件对象是系统自动创建的,不需要我们传输参数,直接使用。其中event是程序员可以自定义的evt、e都可以表示事件对象
        ie678,通过window.event 获取事件对象,参数必须是event
    常见事件对象的属性和方法
        方法
            e.preventDefault() 方法:阻止事件默认行为 比如说:让连接不跳转、按钮不能提交等
            e.returnValue  是属性 阻止事件默认行为 为了兼容ie678
        属性
            e.target 返回的是触发事件的对象(元素)  谁触发事件,返回谁
                与this区别:this是谁绑定事件(注册事件、添加监听)返回谁

            e.type 返回的是事件类型

###阻止事件冒泡
    使用事件对象方法
        e.stopPropagation() 方法
        e.cancelBubble = true 

###事件委托
    原理
        不在每个子节点上添加监听器,而是在子节点的父节点上添加监听,利用冒泡原理影响设置每个子节点
    作用
        DOM操作次数减少,提高程序性能

###常用的鼠标事件
    禁止鼠标右键:contextmenu
        ele.addEventListener('contextmenu',function(e){
            e.preventDefault();
        })
    禁止选中文字:selectstart 
        ele.addEventListener('selectstart',function(e){
            e.preventDefault();
        }
###鼠标事件对象 MouseEvent中常用的属性
    e.clientX 返回的是鼠标距离可视区域顶部的距离  可视区域就是眼睛看到的那一个矩形 
    e.clientY 返回的是鼠标距离可视区域左边的距离
    e.pageX 返回的是鼠标距离页面顶部距离
    e.pageY 返回的是鼠标距离页面左侧距离
    实现一个案例:图片跟着鼠标移动  鼠标到哪图片跟着到哪。实质就是获取鼠标的位置,把位置数据复制给图片的top和left

###常用键盘事件
    keyup:键盘弹起,松开时触发事件
    keydown:键盘按下,按键盘点击时触发事件
    keypress:键盘按下触发事件

    keydown和keypress的区别
        keydown 不区别字母大小写;keypress不识别功能键,比如ctrl等
        二者均是在按下按键触发事件,在执行时,keydown先于keypress执行
    键盘事件对象常用的属性
        e.keyCode 返回的是字符的ASCII字符编码
            用此属性判断字母大小写
    实例:检测用户输入的字符 s可以使搜索框自动获焦点 表单的focus()方法——获焦
        keydown和keypress在文本框中的特点:
           这两个事件触发的时候,文字还没有落入文本框。因为在按下的那一瞬间就触发了事件,文字还没来得及存入文本框
           keyup事件触发是在松开时,这是文字已经落入文本框内

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章