JavaScript進階內容——DOM詳解

来源:https://www.cnblogs.com/qiuluoyuweiliang/archive/2022/07/21/16500640.html
-Advertisement-
Play Games

JavaScript進階內容——DOM詳解 當我們已經熟練掌握JavaScript的語法之後,我們就該進入更深層次的學習了 首先我們思考一下:JavaScript是用來做什麼的? JavaScript誕生就是為了能夠讓它在瀏覽器中運行 那麼DOM就是我們學習中不可或缺的一個環節,下麵讓我們深入瞭解D ...


JavaScript進階內容——DOM詳解

當我們已經熟練掌握JavaScript的語法之後,我們就該進入更深層次的學習了

首先我們思考一下:JavaScript是用來做什麼的?

  • JavaScript誕生就是為了能夠讓它在瀏覽器中運行

那麼DOM就是我們學習中不可或缺的一個環節,下麵讓我們深入瞭解DOM

DOM簡介

DOM定義:

  • 文檔對象模型(DOM),是W3C組織推薦的處理可擴展標記語言(HTML或者XML)的標準編程介面

DOM作用:

  • 用來修改網頁內容,結構和樣式

DOM樹:

  • 我們用一個圖片來表示(來自B站黑馬程式員Pink老師)

獲得元素

DOM在我們實際開發中主要用來操作元素

那麼如果要操作元素,最基本的就是要先獲得元素:

  1. ID獲得元素:

代碼:

//註意這裡返回的是元素對象
document.getElementById('ID');

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="div1"></div>


<script>
    //1.我們常常把script放在body的內部下方
    //2.get 獲得 Element 元素 by 通過 Id
    //3.註意ID是大小寫敏感
    //4.返回的是一個元素對象
    var div1 = document.getElementById('div1');
    //這裡正常輸出
    console.log(div1);
    //這裡dir表示更好的輸出(展示其整體內容)
    console.dir(div1);
</script>
</body>
</html>
  1. 標簽名獲取元素:

代碼:

//註意這裡返回的是元素對象集合
document.getElementsByTagName('TagName');
//可以獲得某個父元素中的全部元素對象集合
element.getElementsByTagName('TagName');

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>

    <ol id="ol">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ol>

    <script>
        //這裡是整個body中的li,返回的是元素對象集合
        var lis = document.getElementsByTagName('li');
        console.log(lis);
        //通過遍歷獲得集合中各個元素對象
        for (const iterator of lis) {
            console.log(iterator);
        }

        //當li為空,仍舊返回數組,但為空數組(偽數組)

        //我們可以單獨獲得ol中的li
        var ol = document.getElementById('ol');
        var ollis = ol.getElementsByTagName('li');
        //通過遍歷獲得集合中各個元素對象
        for (const iterator of ollis) {
            console.log(iterator);
        }
    </script>
</body>
</html>
  1. 類名獲取元素(HTML5):

代碼:

document.getElementByClassName('類名');

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    
</head>
<body>
    <div id="nav"></div>
    <div class="box"></div>
    <div class="box">
        <ul>
            <li></li>
            <li></li>
        </ul>
    </div>

    <script>
        //1.通過類名獲得對象
        var box = document.getElementsByClassName('div');
        console.log(box);

        //2.document.querySelector('.box')我們可以獲得選擇器中的第一個
        var fristBox = document.querySelector('.box');

        //3。上方的獲取方法同樣適用於id選擇,註意需要用‘’包括
        var nav = document.querySelector('#nav');

        //4.同樣使用於標簽選擇
        var fristLi = document.querySelector('li');

        //5.document.querySelectorAll()獲取所有的類型的集合
        var allLi = document.querySelectorAll('li');
    </script>
</body>
</html>
  1. 獲得特殊標簽body和html元素

代碼:

//body元素
document.body
//html元素
document.documentElement

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    

    <script>
        //1.獲得body元素
        var bodyEle = document.body;
        console.log(bodyEle);
        console.dir(bodyEle);

        //2.獲得html元素
        var htmlEle = document.documentElement;
        console.log(htmlEle);
    </script>
</body>
</html>

事件基礎

JavaScript使我們有能力創建動態頁面,而事件就是被JavaScript所偵測到的行為。

頁面中的每個元素都可以產生某些觸發JavaScript的事件,簡單來說就是產生:觸發——響應機制

事件三要素

我們把事件分為三部分:

  • 事件源
    • 事件被觸發的對象
  • 事件類型
    • 如何觸發,例如點擊onclick
  • 事件處理程式
    • 通過一個函數賦值的方法完成

我們下麵給出基本格式:

name.methodName = function() {
    ~~~
    ~~~
}

我們給出一個基礎案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="but">按鈕</button>

    <script>
        //我們下麵做出的:點擊按鈕就會彈出“你好”的對話框
        
        //1.獲得事件源
        var button = document.getElementById('but');
        //2.針對事件源,給出事件類型和事件處理程式(這裡指點擊事件)
        button.onclick = function() {
            alert("你好");
        }
    </script>
</body>
</html>

事件類型概括

我們下麵給出所有可用到的事件類型:

滑鼠事件 觸發條件
onclick 滑鼠點擊左鍵觸發
onmouseover 滑鼠經過觸發
onmouseout 滑鼠離開觸發
onfocus 獲得滑鼠焦點觸發
onblur 失去滑鼠焦點觸發
onmousemove 滑鼠移動觸發
onmouseup 滑鼠彈起觸發
onmousedown 滑鼠按下觸發

操作元素

我們學習事件的目的就是為了對元素進行修改

下麵我們依次介紹一些操作元素的方法:

元素內容修改

元素內容修改有兩種方法:

//element.innerText不識別HTML標簽,會去除空格和換行
element.innerText = '';
//element.innerHTML識別HTML標簽,不會去除空格和換行(推薦)
element.innerHTML = '';
//註意:我們可以通過上述方法來獲得該元素的內容

除內容修改外,元素屬性同樣也可以進行修改:

//我們需要把下述圖片修改放於某元素的事件中就可以進行修改
img.src = '';

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="but">按鈕</button>
    <div class="box">時間~~~~</div>

    <script>
        //當我們點擊按鈕,將box內容更改為當前時間

        //獲得元素
        var button = document.getElementById('but');
        var timer = document.querySelector(".box");

        //做出事件
        button.onclick = function() {
            //註意這裡採用innerHTML,strong會以HTML的形式用來加粗內容而不會展示出來
            timer.innerHTML = "<strong>2022.7.20</strong>";
        }
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="ldh">劉德華</button>
    <button id="zxy">張學友</button>
    <img src="images/ldh.jpg" alt="">

    <script>
        //首先我們獲得按鈕元素對象
        var ldh = document.getElementById('ldh');
        var zxy = document.getElementById('zxy');
        var img = document.querySelector('img');

        //然後設置事件:在點擊該對象時更換到對應圖片
        ldh.onclick = function(){
            img.src = "images/ldh.jpg";
            img.title = "劉德華";
        }

        zxy.onclick = function(){
            img.src = "images/zxy.jpg";
            img.title = "張學友";
        }
    </script>
</body>
</html>

表單元素修改

  1. value內容修改:

    input.value = '';
    
  2. disabled禁用屬性:

    name.disabled = true;
    this.disable = true;
    

下麵我們給出一個案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button>按鈕</button>
    <input type="text" value="請輸入內容">

    <script>
        //首先我們需要獲取元素
        var btn = document.querySelector('button');
        var input = document.querySelector('input');

        //在我們點擊按鈕後,input內容變為已提交且button本身不能二次提交
        btn.onclick = function() {
            //首先對input進行更換value
            input.value = "已提交";

            //再對btn進行禁止操作(可以採用this表示本身)
            this.disabled = true;
        }
    </script>
</body>
</html>
  1. 樣式屬性操作:

    //單個修改屬性,適用於修改內容不多
    this.style.屬性內容 = ~~~;
    
  2. 樣式整體屬性操作:

    //CSS重新創建類屬性,在元素中加入對應類,進行屬性修改,適用於大幅度修改屬性
    this.className = '';
    

下麵我們給出一個案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <style>
        .divv {
            height: 400px;
            width: 400px;
            background-color: red;
        }

        .change {
            height: 200px;
            width: 200px;
            background-color: aqua;
            font-size: 20px;
        }
    </style>
</head>
<body>
    <div id="div1" class="divv"></div>
    <div id="div2" class="divv"></div>
    <div id="div3" class="divv">123</div>

    <script>
        //我們希望點擊上方盒子,然後盒子樣式發生變化

        //獲得元素
        var div1 = document.getElementById('div1');
        var div2 = document.getElementById('div2');
        var div3 = document.getElementById('div3');

        //針對第一個盒子,當我們點擊它,它變為紫色
        div1.onclick = function() {
            this.style.backgroundColor = 'purple';
        }

        //針對第二個盒子,當我們點擊它,它消失
        div2.onclick = function(){
            this.style.display = 'none';
        }

        //針對第三個盒子,修改內容過多,我們採用className方法
        div3.onclick = function(){
            //註意:如果之前class的部分樣式未修改,需要把之前樣式也加上,形成多class對象
            this.className = "divv change";
        }
    </script>
</body>
</html>

自定義屬性

首先我們瞭解一下自定義屬性:

  • 並非HTML自帶的,但是可以在標簽中寫入的屬性,被稱為自定義屬性
  • 自定義屬性沒有規範,可以隨意任命
  • 但H5給了我們自定義屬性規範:以data-開頭,後面加上其他內容

然後我們講一下獲得屬性值的方法:

//獲得屬性值(只能獲得內置屬性,即自身攜帶屬性)
element.屬性;
//獲得屬性值(可以獲得所有屬性,包括自定義屬性)
element.getAttribute('屬性');

然後我們講一下設置屬性值的方法:

//註意:下麵兩種方法中針對class的設置不同

//設置屬性值(內置屬性)
對象.屬性名 = '屬性值';
name.className = 'class1';
//設置屬性值(所有屬性)
對象.setAttribute('屬性名','屬性值');
name.setAttribute('class','class1');

最後我們講一下刪除屬性值的方法:

//註意:大部分刪除自定義屬性
name.removeAttribute('屬性名');

下麵我們通過一個案例來解釋:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 這裡的index就是自定義屬性 -->
    <div class="class1" data-index=1></div>

    <script>
        var div = document.querySelector('div');

        //首先是獲得屬性的方法

        // 1.element.屬性;
        console.log(div.className);
        // 2.element.getAttribute('屬性');
        console.log(div.getAttribute('data-index'));

        // 然後講解修改方法:

        // 1.對象.屬性名 = '屬性值';
        div.className = '';
        // 2.對象.setAttribute('屬性名','屬性值');
        div.setAttribute('data-index',2);

        // 最後刪除方法:
        // name.removeAttribute('屬性名');
        div.removeAttribute('data-index');
    </script>
</body>
</html>

排他思想(演算法)

當我們有同一組元素,我們希望某個元素實現某種樣式,就需要用到迴圈的排他思想:

  • 將所有元素全部清除樣式
  • 給當前元素設置樣式

我們給出一個案例來解釋排他思想:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    
    <style>
        button {
            height: 20px;
            width: 40px;
        }
    </style>
</head>
<body>
    <ul>
        <button></button><button></button><button></button><button></button><button></button>
    </ul>

    <script>
        //我們希望點擊某個按鈕時,只有當前按鈕發生變化(變紅色),其他按鈕保持原有狀態

        //首先我們獲得所有元素
        var btns = document.getElementsByTagName('button');

        //依次設計點擊狀態
        for(var i=0;i<btns.length;i++){
            btns[i].onclick = function(){
                //首先全部設置為最初狀態
                for(var j=0;j<btns.length;j++){
                    btns[j].style.backgroundColor = '';
                }
                //然後針對當前元素進行修改
                this.style.backgroundColor = 'red';
            }
        }
    </script>
</body>
</html>

節點操作

節點操作的具體作用:

  • 用來獲得元素,且具有邏輯性地獲得元素

節點概述:

  • 節點操作的主要操作時元素節點操作
  • 頁面內所有內容都是節點,在DOM中,節點使用node表示
  • HTML DOM中所有節點均可以通過JavaScript進行訪問,所有HTML元素節點均可以被修改,也可以創建或刪除

節點基本屬性:

  • 節點類型nodeType
  • 節點名稱nodeName
  • 節點值nodeValue

節點分類:

  • 元素節點nodeType = 1
  • 屬性節點nodeType = 2
  • 文本節點nodeType = 3

節點層級

我們在使用節點時,通常利用DOM樹把節點劃分為不同的層級關係

  1. 父級節點
對象.parentNode
  • 得到的是元素最近的父節點
  • 如果找不到父節點,返回為null

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 父節點案例 -->
    <div class="father">
        <div class="son"></div>
    </div>

    <script>
        //1.通過子節點找到父節點
        
        //首先獲得子節點
        var son_1 = document.querySelector('.son');
        
        //通過子節點獲得父節點
        console.log(son_1.parentNode);
    </script>
</body>
</html>
  1. 子節點
對象.children
  • 常用,因為我們基本上只對元素進行修改
  • 獲得的元素是集合,需要採用[]獲得單個元素
  • 這裡獲得的是全部子元素節點

拓展:

對象.childrens
  • 獲得的元素是集合,需要採用[]獲得單個元素
  • 這裡獲得的是全部子節點,包括元素節點,文本節點

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 子節點案例 -->
    <ul>
        <li>我是li</li>
        <li></li>
        <li></li>
        <li></li>
        <li>我是li</li>
    </ul>

    <script>
        // 這裡我們只介紹children

        // 首先我們獲得父節點
        var ul = document.querySelector('ul');
        // 然後根據父節點獲得子節點:
        console.log(ul.children);
    </script>
</body>
</html>
  1. 第一個子元素和最後一個子元素
對象.firstChild
對象.lastChild
  • 可以獲得第一個和最後一個子節點
  • 可以獲得所有節點:元素節點和文本節點
對象.firstElementChild
對象.lastElementChild
  • 可以獲得第一個和最後一個子元素節點
  • 只能獲得元素節點
對象.children[0]
對象.children[對象.children.length - 1]
  • 實際案例常用方法
  • 因為第一個包含文本節點,第二個具有相容性問題,所以當前常用該方法進行選擇
  1. 兄弟節點
對象.nextSibling
對象.previousSibling
  • 獲得下一個和上一下兄弟節點
  • 包括所有節點:元素節點和文本節點
對象.nextElementSibling
對象.previousElementSibling
  • 獲得下一個和上一下兄弟元素節點
  • 只包括元素節點

節點操作

  1. 創建節點
document.createElement('tagName')
  • 創建由tagName指定的HTML元素
  • 因為元素原先不存在,是根據我們的需求動態生成的,所以稱為動態創建元素節點
  1. 添加節點
node.appendChild(child)
  • 將一個節點添加到指定父節點的末尾
  1. 添加節點到指定位置
node.insertBefore(child,指定元素)
  • 將一個節點放到指定元素前面

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>123</li>
    </ul>

    <script>
        // 創建節點
        var li = document.createElement('li');

        // 添加節點
        var ul = document.querySelector('ul');
        ul.appendChild(li);

        // 添加到指定元素
        var li2 = document.createElement('li');
        ul.insertBefore(li2,ul.children[0]);
    </script>
</body>
</html>
  1. 刪除節點
node.removeChild(child)
  • 刪除指定節點
  1. 複製節點
node.cloneNode()
  • 複製某一結點
  • 括弧裡面為true,表示深拷貝,複製內容
  • 括弧裡面為空或者false,表示淺拷貝,不複製內容
  • 節點並未出現在頁面,如果希望出現該節點,需要插入該節點

事件高級內容

我們在前面已經掌握了事件的基本方法,接下來我們來學習進階內容:

註冊事件概述

給元素添加事件,被稱為註冊事件或者綁定事件

註冊事件有兩種方法:

  • 傳統註冊方法:
    • 註冊事件具有唯一性
    • 同一元素同一事件只能設置一個處理函數,最後註冊的處理函數會覆蓋前面註冊的處理函數
  • 事件監聽方法:
    • 註冊事件可以有多個處理函數,依次執行
    • eventTarget.addEventListener(type,listener[,useCapture])
    • 該方法將指定的監聽器註冊到eventTarget(目標對象)上,當該對象觸髮指定的事件時,就會執行事件處理函數
    • type:事件類型字元串,比如click,mouseover,註意:這裡不需要帶on
    • listener:事件處理函數,事件發生時,會調用該監聽函數
    • useCapture:可選參數,一個布爾值,預設false;這裡暫時不做講解

代碼展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button>傳統方法</button>
    <button>監聽方法</button>

    <script>
        var btns = document.querySelectorAll('button');

        // 1.傳統方法
        // 傳統方法只能有一個函數調用,後面覆蓋前面
        btns[0].onclick = function(){
            alert('1');
        }
        btns[0].onclick = function(){
            alert('2');
        }

        // 2.監聽方法(IE9之前不能用)
        // 監聽方法會依次調用所有函數
        // 註意:事件類型加'',是字元串,不能帶on
        btns[1].addEventListener('click',function(){
            alert('1');
        })
        btns[1].addEventListener('click',function(){
            alert('2');
        })
    </script>
</body>
</html>

刪除事件概述

給元素刪除事件,被稱為刪除事件或者解綁事件

刪除事件有兩種方法:

  • 傳統解綁方法:
    • eventTarget.onclick = null;
  • 監聽解綁方法:
    • eventTarget.removeEventListener('click',fn);
    • eventTarget是監聽對象
    • 'click'是監聽對象的操作
    • fn是監聽對象所使用的方法

代碼展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=, initial-scale=1.0">
    <title>Document</title>
    
    <style>
        div {
            height: 400px;
            width: 400px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <div>1</div>
    <div>2</div>

    <script>
        var divs = document.querySelectorAll('div');

        // 1.傳統刪除方法
        divs[0].onclick = function(){
            alert('1');
            // 在點擊一次後刪除其效果
            divs[0].onclick = null;
        }

        // 2.removeEventListener刪除事件
        // 首先我們div對象所使用的函數必須採用有名稱的函數
        var fn = function (){
            alert('1');
            // 在所使用的函數中使用刪除事件方法
            divs[1].removeEventListener('click',fn);
        }
        divs[1].addEventListener('click',fn);
    </script>
</body>
</html>

DOM事件流

事件流描述的是從頁面接收事件的順序

事件發生時會在元素節點之間按照特定的順序傳播,這個傳播過程即DOM事件流

DOM事件流分為3個階段:

  • 捕獲階段
  • 當前目標階段
  • 冒泡階段

  • 事件冒泡:IE最早提出,事件開始時由具體的元素接收,然後逐級向上傳播到DOM最頂層節點的過程
  • 事件捕獲:網景最早提出,由DOM最頂層節點開始,然後逐層向下傳播到最具體的元素接收過程

我們通過一些代碼來解釋:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .father {
            height: 400px;
            width: 400px;
            background-color: pink;
        }

        .son {
            height: 200px;
            width: 200px;
            background-color: purple;
            margin: auto;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="son">son</div>
    </div>

    <script>
        var son = document.querySelector('.son');

        // 註意:下述代碼具有互斥性,測試時請先註釋掉其中一部分

        // 註意:JS代碼中只能執行捕獲或者冒泡的其中一個階段
        // 註意:onclick只能得到冒泡階段,要研究捕獲階段,需要採用addEventListener,且第三個參數為true時,屬於捕獲階段
        // 捕獲階段: document-> html -> body -> father -> son
        // 冒泡階段: son -> father -> body -> html -> document

        // 首先先來解釋捕獲
        // 當我們對他們均設置function方法,當執行一個底部對象的函數,我們需要按照順序先執行上方的函數
        // 例如:下麵的代碼,當我們點擊son,會先輸出father的2,再輸出son的1
        
        son.addEventListener('click',function(){
            alert('1');
        },true);
        son.parentNode.addEventListener('click',function(){
            alert('2');
        },true);

        // 對於冒泡也是同理
        // 我們執行底層對象的函數時,需要按照順序先從下麵的函數執行,然後逐漸執行上面的函數

        son.addEventListener('click',function(){
            alert('1');
        });
        son.parentNode.addEventListener('click',function(){
            alert('2');
        });
    </script>
</body>
</html>

事件對象

首先我們先來介紹一下事件對象:

  • 事件對象是指 事件函數的參數
  • 它通常用e,evt,event來命名
  • 事件對象不需要傳遞,是系統自動生成的
  • 事件對象包含了跟事件有關的一系列信息數據,它是一個集合,包含許多屬性和方法

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            height: 400px;
            width: 400px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <div></div>
    <div></div>

    <script>
        var divs = document.querySelectorAll('div');

        // function中的參數event就是事件對象
        // 不需要傳遞參數,是系統自動形成,可以任意命名
        divs[0].onclick = function (event) {
            // 我們可以查看event所包含的內容
            console.log(event);
        }

        // 使用addEventListener方法 以及 其他操作也是可以的
        // 滑鼠就會展示滑鼠相關信息,鍵盤就會展示鍵盤相關信息
        divs[1].addEventListener('mouseover',function(event){
            console.log(event);
        })
    </script>
</body>
</html>

下麵我們介紹一下常見事件對象的屬性和方法:

事件對象屬性方法 說明
e.target 返回觸發事件的對象 標準
e.srcElement 返回觸發事件的對象 非標準 ie6~ie8使用
e.type 返回事件的類型,比如click,mouseover
e.cancelBubble 該屬性阻止冒泡 非標準 ie6~ie8使用
e.returnValue 該屬性 阻止預設事件(預設行為)非標準 ie6~ie8使用 比如不讓鏈接跳轉
e.preventDefault() 該屬性 阻止預設事件(預設行為)標準 比如不讓鏈接跳轉
e.stopPropagation() 阻止冒泡 標準

下麵我們用代碼形式分開介紹一些屬性和方法:

  • e.target和this的區別:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            div {
                height: 300px;
                width: 300px;
                background-color: pink;
            }
        </style>
    </head>
    <body>
        <div>111</div>
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
    
        <script>
            var div = document.querySelector('div');
    
            // 首先我們介紹一下target
            div.onclick = function(e) {
                // target是指觸發該事件的對象,即你點擊哪裡就是哪個對象觸發
                console.log(e.target);
            }
    
            // 然後我們稍微區別一下this
            // this永遠只是指調用對象本體
            var ul = document.querySelector('ul');
            ul.addEventListener('click',function(e){
                // 這裡this指向的永遠是ul
                console.log(this);
                // 這裡target,當你點擊的是li時,返回的對象是li
                console.log(e.target);
            })
        </script>
    </body>
    </html>
    
  • 阻止預設行為

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>123</div>
    <a href="https://www.baidu.com/">百度</a>
    <form action="https://www.baidu.com/">
        <input type="submit" value="提交" name="sub">
    </form>

    <script>
        var div = document.querySelector('div');
        var a = document.querySelector('a');
        var input = document.querySelector('input');


        // 我們在這裡稍微介紹一下type屬性
        // 首先我們設置一個函數
        fn = function(e) {
            console.log(e.type);
        }
        // 然後我們把這個函數應用到某些對象的某些操作中
        div.addEventListener('click',fn);
        div.addEventListener('mouseover',fn);
        div.addEventListener('mouseout',fn);

        // 接下來我們介紹阻止預設行為:e.preventDefault()方法
        // 正常情況下我們點擊連接會進行跳轉,我們點擊提交按鈕會進行信息提交
        // 但是當我們採用了阻止預設行為,我們的這些行為就會被組織

        // 採用e的方法來阻止預設行為
        a.addEventListener('click',function(e){
            // 註意是方法,需要帶()
            e.preventDefault();
        })
        // 我們也可以採用return false來阻止預設行為
        input.onclick = function(e){
            // 註意return方法只能在傳統方法中使用,在addEventListener中無法使用
            return false;
        }
    </script>
</body>
</html>
  • 阻止事件冒泡:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .father {
            height: 400px;
            width: 400px;
            background-color: pink;
        }

        .son {
            height: 200px;
            width: 200px;
            background-color: purple;
            margin: auto;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="son">son</div>
    </div>

    <script>
        var son = document.querySelector('.son');

        // 當我們採用stopPropagation時,冒泡不再進行

        son.addEventListener('click',function(e){
            alert('1');
            // 我們對son進行冒泡禁止處理,當點擊son時僅對son的函數輸出
            e.stopPropagation();
        });
        son.parentNode.addEventListener('click',function(){
            alert('2');
            // 我們未對father進行冒泡禁止處理,所以點擊father時,document的函數alert('3')仍會輸出
        });
        son.parentNode.parentNode.addEventListener('click',function(){
            alert('3');
        });
    </script>
</body>
</html>

事件委托

事件委托解釋:

  • 事件委托被稱為時間代理,在jQuery中被稱為事件委派

事件委托原理:

  • 不在每個子節點單獨設置事件監聽器,而是將事件監聽器設置在其父節點上,然後利用冒泡原理影響設置每個子節點

事件委托的作用:

  • 我們僅需要操作一次DOM,提高了程式的性能

案例解釋:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>點擊我彈出彈框</li>
        <li>點擊我彈出彈框</li>
        <li>點擊我彈出彈框</li>
        <li>點擊我彈出彈框</li>
        <li>點擊我彈出彈框</li>
    </ul>

    <script>
        // 將事件監聽器設置在其父節點上,然後利用冒泡原理影響設置每個子節點

        var ul = document.querySelector('ul');

        ul.addEventListener('click',function(e){
            // 當點擊時,彈出彈框
            alert('彈框');
            // 我們也可以針對點擊的對象來進行一些操作
            e.target.style.backgroundColor = 'black';

        })
    </script>
</body>
</html>

滑鼠事件拓展

我們在前面給出了一些滑鼠操作:

滑鼠事件 觸發條件
onclick 滑鼠點擊左鍵觸發
onmouseover 滑鼠經過觸發
onmouseout 滑鼠離開觸發
onfocus 獲得滑鼠焦點觸發
onblur 失去滑鼠焦點觸發
onmousemove 滑鼠移動觸發
onmouseup 滑鼠彈起觸發
onmousedown 滑鼠按下觸發

下麵我們再介紹一些另類的滑鼠事件:

  • 禁止右鍵選中:

    document.addEventListener('contextmenu',function(e){
        //禁止contextmenu右鍵滑鼠操作
    	e.preventDefault();
    })
    
  • 禁止選中文字:

    document.addEventListener('selectstart',function(e){
        //禁止selectstart選中文字
    	e.preventDefault();
    })
    

滑鼠事件對象

event對象代表事件的狀態,跟事件相關的一系列信息的集合

我們首先來學習滑鼠事件對象:

滑鼠屬性 說明
e.clientX 當前可視頁面的x
e.clientY 當前可視頁面的y
e.pageX 當前頁面的x(不具有相容性)
e.pageY 當前頁面的y(不具有相容性)

代碼示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            height: 3000px;
        }
    </style>
</head>
<body>
    
    <script>
        // 接下里都是滑鼠對象的屬性

        // 這裡表示在頁面內點擊時
        // 註意只能用addEventListener,傳統方法不能使用
        document.addEventListener('click',function(e){
            // 這裡獲得的是針對當前可視頁面的x,y
            console.log(e.clientX);
            console.log(e.clientY);

            // 分割線
            console.log('------------------')

            // 這裡獲得的是針對當前頁面的x,y(針對IE9以上版本)
            console.log(e.pageX);
            console.log(e.pageY);
        })
    </script>
</body>
</html>

鍵盤事件和鍵盤事件對象

我們先來學習鍵盤事件:

鍵盤事件 說明
onkeyup 某個鍵盤按鍵被鬆開時觸發
onkeydown 某個鍵盤按鍵被按下時觸發
onkeypress 某個鍵盤按鍵被按下時觸發(不能識別功能鍵,如ctrl,shift,左右箭頭)

註意:

  • 三個時間的執行順序:keydown -> keypress -> keyup

然後我們來瞭解一下鍵盤事件對象:

鍵盤事件對象屬性 說明
e.key 返回相應鍵(不具備相容性,不推薦)
e.keyCode 返回相應鍵的ASCII值(具有相容性,推薦)

註意:

  • keyup和keydown事件中不區分大小寫,均為大寫輸出
  • keypress事件區分大小寫,A:65,a:97

案例展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 下述都是針對頁面操作:
        document.addEventListener('keyup',function(){
            console.log('彈起')
        })
        document.addEventListener('keydown',function(){
            console.log('按下down')
        })
        document.addEventListener('keypress',function(){
            console.log('按下press')
        })

        // 接下來我們講解一下keyCode:
        // 註意:keydown不區分大小寫,keypress區分大小寫
        document.addEventListener('keydown',function(e){
            console.log('down:' + e.keyCode);
        })
        document.addEventListener('keypress',function(e){
            console.log('press:' + e.keyCode);
        })
    </script>
</body>
</html>

結束語

好的,那麼關於DOM的全部知識點總結完畢!

下一節我會對BOM做出詳解,並且在JavaScript的內容結束後,會對DOM的各種實際網頁應用做出各種案例模板,請多多關照!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文包含SQL基礎語法、函數、索引、sql編程、事務、事務原則、備份恢復,許可權資料庫設計、三大範式、JDBC、SQL註入、資料庫連接池等所有知識都在這裡了 ...
  • 原文地址:Kotlin學習快速入門(8)—— 屬性委托 - Stars-One的雜貨小窩 委托其實是一種設計模式,但Kotlin把此特性編寫進了語法中,可以方便開發者快速使用 委托對應的關鍵字是by 屬性委托 先講下屬性委托吧,首先,複習下kotlin中設置set和get方法 預設的set和get我 ...
  • 華為應用內支付服務(In-App Purchases)通過簡便的接入流程為用戶提供良好的應用內支付體驗,然而在實際接入過程中,有一些開發者反饋測試時會無法正常拉起支付頁面,下文將詳細分析問題出現的5種情形,並給出解決方案,希望給遇到類似問題的開發者提供參考。 情形1:AGC控制臺上API管理中的支付 ...
  • JavaScript進階內容——BOM詳解 在上一篇文章中我們學習了DOM,接下來讓我們先通過和DOM的對比來簡單瞭解一下BOM 首先我們先來複習一下DOM: 文檔對象模型 DOM把文檔當作一個對象來看待 DOM的頂級對象是document DOM的主要學習是操作頁面元素 DOM是W3C標準規範 然 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一、Git 1. git 和 svn 的區別 git 和 svn 最大的區別在於 git 是分散式的,而 svn 是集中式的。因此我們不能再離線的情況下使用 svn。如果伺服器出現問題,就沒有辦法使用 svn 來提交代碼。 svn 中的分 ...
  • ES6 class中的一些問題 記錄下class中的原型,實例,super之間的關係 //父類 class Dad { constructor(x, y) { this.x = 5; this.y = 1; this.state = 789 } static x = 521 state1 = 666 ...
  • 在早期的隨筆就介紹過,把常規頁面的內容拆分為幾個不同的組件,如普通的頁面,包括列表查詢、詳細資料查看、新增資料、編輯資料、導入資料等頁面場景,這些內容相對比較獨立,而有一定的代碼量,本篇隨筆介紹基於Vue3+Typescript+Setup語法方式,來拆分頁面模塊內容為組件,實現分而治之的處理。 ...
  • @(文章目錄) 提示:本文僅供學習交流,請勿用於非法活動! 前言 本文大概內容: 在官網展現圖表及報表(含導出) 一、使用highcharts前後端交互展示圖表,及使用報表導出 如下圖,我們在首頁如何將折線圖、柱狀圖結合報表,並實現根據不同的倉庫實時刷新不同的數據,最後可以選擇導出圖表及報表。 二、 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...