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事件觸發是在鬆開時,這是文字已經落入文本框內

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