DOM(基礎操作)(作爲學習筆記)

1. 目標

  1. 能夠說出什麼是DOM
  2. 能夠獲取頁面元素
  3. 能夠給元素註冊事件
  4. 能夠操作DOM元素的屬性
  5. 能夠創建元素
  6. 能夠操作DOM節點

2. DOM簡介

2.1 什麼是DOM呢?

文檔對象模型( Document Object Model ,簡稱DOM),是W3C推薦的處理可擴展標記語言( HTML或者XML )的標準編程接口。

W3C已經定義了一系列的DOM接口,通過這些DOM接口可以改變網頁的內容,結構和樣式。

2. DOM樹

html 上面的標籤時 document。document代表整個文檔

在這裏插入圖片描述

  • 文檔:一個頁面就是一個文檔,DOM中使用 document 表示
  • 元素:頁面中的所有標籤都是元素,DOM中使用 element 表示
  • 節點:網頁中的所有內容都是節點(標籤,屬性,文本,註釋等),DOM中使用node表示

DOM 把以上的內容都看作是對象

3. 獲取元素

在實際開發中主要用來操作元素。

3.1 獲取頁面元素
3.1.1 根據 ID 獲取
- 返回一個匹配特點 ID 的元素
- id是大小寫敏感的字符串

栗子:

<body>
    <div id="time">2020-4-8</div>
    <script>
        // 1. 因爲文檔頁面從上往下加載,所以得先有標籤,所以我們script寫到標籤的下面
        // 2. 獲得 元素 通過 id(翻譯)駝峯命名法
        // 3. 參數 id 是大小寫敏感的字符串,所以加引號。
        // 4. 返回的是一個元素對象
        div = document.getElementById("time");
        console.log(time);
        console.log(typeof(time));
        // 5. console.dir 打印我們返回的元素對象 更好的查看裏面的屬性與方法
        console.dir(time);
    </script>
</body>
3.1.2 根據標籤名獲取

使用 getElementByTagName() 方法可以返回帶有指定標籤名的對象集合。
栗子:

<body>
    <ul>
        <li>帥哥是我 我是帥哥1</li>
        <li>帥哥是我 我是帥哥2</li>
        <li>帥哥是我 我是帥哥3</li>
        <li>帥哥是我 我是帥哥4</li>
        <li>帥哥是我 我是帥哥5</li>
    </ul>
    <ul id="nav">
        <li>噓!~ 禁止想象 1</li>
        <li>噓!~ 禁止想象 2</li>
        <li>噓!~ 禁止想象 3</li>
        <li>噓!~ 禁止想象 4</li>
        <li>噓!~ 禁止想象 5</li>
    </ul>
    <script>
        // 返回的是 獲取過來元素對象的集合 以僞數組的形式存儲
        var list = document.getElementsByTagName('li');
        console.dir(list);
        console.log(list[0]);

        // 我們想要依次打印裏面的元素對象我們可以採用遍歷的方式
        for (var i = 0; i < list.length; i++) {
            console.log(list[i]);
        }

        // 3. element.getElementsByTagName() 可以得到這個元素裏面的某個標籤
        var nav = document.getElementById('nav'); //可以獲得 nav 元素
        var navList = nav.getElementsByTagName('li');
        console.dir(navList);
    </script>
</body>
3. 通過 HTML5 新增的方法獲取
  1. getElementsByClassName(‘類名’)
  2. querySelctor( )
  3. querySelctorAll( )
    栗子:
<body>
    <div class="box">盒子1</div>
    <div class="box">盒子2</div>
    <div id="nav">
        <ul>
            <li>首頁</li>
            <li>產品</li>
        </ul>
    </div>
    <script>
        // 1. getElementsByClassName('類名') 根據類名返回元素對象集合
        var box = document.getElementsByClassName('box');
        console.log(box);
        // 2. querySelctor 返回選擇器的第一個元素對象
        var firstBox = document.querySelector('.box');
        console.log(firstBox);

        var nav = document.querySelector('#nav');
        console.log(nav);

        var li = document.querySelector('li');
        console.log(li);

        // 3. querySelctorAll() 返回指定選擇器的所有對象集合
        var allBox = document.querySelectorAll('.box');
        console.log(allBox);

        var lis = document.querySelectorAll('li');
        console.log((lis));
    </script>
</body>
4. 特殊元素獲取
<body>
    <script>
        /* 獲取body */
        var bodyEle = document.body;
        console.log(bodyEle);
        /* 獲取html */
        var htmlEle = document.documentElement;
        console.log(htmlEle);
    </script>
</body>

4. 事件基礎

JavaScript使我們有能力創建動態頁面事件是可以被JavaScript偵測到的行爲。
簡單理解:觸發—響應機制。

網頁中的每個元素都可以產生某些可以觸發 JavaScript的事件,例如,我們可以在用戶點擊某按鈕是產生一個事件,然後去執行某些操作。
在這裏插入圖片描述

栗子:唐伯虎點秋香

<body>
    <button id="btn">唐伯虎</button>
    <script>
        // 點擊一個按鈕,彈出對話框
        // 1. 事件是有三部分組成 事件源 事件類型 事件處理程序 我們也稱爲事件三要素
        //  (1) 事件源 事件被觸發的對象 誰 按鈕
        var btn = document.getElementById('btn');
        //  (2) 事件類型 如何觸發 什麼事件 比如鼠標點擊(onclick) 還是鼠標經過 還是鍵盤按下
        //  (3) 事件處理程序 通過一個函數賦值的方式 完成
        btn.onclick = function() {
            alert('點秋香');
        }
    </script>
</body>
執行事件的步驟
  1. 獲取事件源
  2. 註冊事件(綁定事件)
  3. 添加事件處理程序(採取函數賦值的形式)

常見鼠標事件

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

栗子:

<body>
    <div>123</div>
    <script>
        //執行事件步驟
        //點擊 div 控制檯輸出 我被選中了
        // 1. 獲取事件源
        var div = document.querySelector('div');
        // 2. 綁定事件 註冊事件
        // div.onclick
        // 3. 添加事件處理程序
        div.onclick = function() {
            console.log('我被選中了');
        }
    </script>
</body>

5. 操作元素

JavaScript 的 DOM 操作可以改變網頁內容,結構和樣式,我們可以利用 DOM 操作元素來改變元素裏面的內容,屬性等,注意以下都是屬性

5.1 改變元素內容
	element.innerText

從起始位置到終止位置的內容,但它除去html標籤,同時空格和換行也會同時去掉

	element.innerHtml
  1. 栗子一:顯示當前時間

  2. 栗子二:
    二者區別:

<body>
    <div></div>
    <p>
        我是文字
        <span>123</span>
    </p>
    <script>
        // innerText 和 innerHTML 的區別
        // 1. innerText 不識別 html標籤 非標準
        // var div = document.querySelector('div');
        // div.innerText = "<strong>最帥</strong>是我";

        // 2. innerHTML 識別 html 標籤 W3C 標準
        // div.innerHTML = "<strong>最帥</strong>是我";

        // 這兩個屬性是可讀寫的 可以獲取元素裏面的內容
        // var p = document.querySelector('p');
        // console.log(p.innerText);
        // console.log(p.innerHTML);
    </script>
</body>

起始位置到終止位置的全部內容,包括html標籤,同時保留空格和換行
innerHTML標準,儘量用

5.2 改變元素屬性

再來個栗子:
通過不同時間得到不同的問候語

<body>
    <img src="" alt="">
    <div>上午好</div>
    <script>
        // 1. 獲取元素
        var img = document.querySelector('img');
        var div = document.querySelector('div');
        // 2. 獲取當前小時數
        var date = new Date();
        var h = date.getHours();
        console.log(h);

        // 3. 判斷小時數
        switch (true) {
            case h < 12:
                img.src = "morning.jpg"
                div.innerHTML = '親!早上好';
                break;
            case h > 12 && h < 17:
                img.src = "afternoon.jpg"
                div.innerHTML = '親!下午好';
                break;
            default:
                img.src = "night.jpg"
                div.innerHTML = '親!晚上好';
                break;
        }
    </script>
</body>
5.3 表單元素的屬性操作

type, value, checked, selected, disabled(禁用按鈕)

表單裏面的值是通過value來變化的

  1. 三個栗子(important!!!):1. 點擊 input 的 value 變化 2. 點擊按鈕禁用 3. 密碼的明文和暗碼
5.4 樣式屬性操作

我們可以通過 js 修改元素的大小,顏色,位置等樣式

方法 作用
element.style 行內樣式操作如果說樣式比較少 或者 功能簡單的情況下使用
element.className 類名樣式操作 如果說樣式比較多或者功能比較複雜那麼就用這個(更好的分離樣式與行爲

注:

  • js裏面的樣式採用駝峯命名法 比如 fontSize, backgroundColor
  • js 修改 style 樣式操作,產生的是行內樣式, 權重高。
  1. 栗子1( element.style ):隱藏文本框的內容
    當鼠標點擊文本框的時候,裏面的默認文字隱藏,當鼠標離開文本框時,裏面的文字顯示。

  2. 栗子2( element.className ):改變class名

    • 如果樣式修改較多,可以採取操作類名方式更改元素樣式
    • class是個保留字,因此使用className來操作元素類名屬性
    • className會直接更改元素的類名,會覆蓋原先的類名 所以要加新的類名要把原先的寫上
<!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 {
            width: 200px;
            height: 200px;
            color: saddlebrown;
            background-color: red;
        }
        
        .change {
            margin: 20px;
            color: silver;
            background-color: royalblue;
        }
    </style>
</head>

<body>
    <div>我是帥哥</div>
    <script>
        var div = document.getElementsByTagName('div');
        div[0].onclick = function() {
            this.className = 'change';
        }
    </script>
</body>

</html>
  1. 栗子3:密碼較短提示信息
5.5 排他思想

如果有同一組元素我們想要改變某一個元素實現某種樣式,需要用到循環的排他思想:

  • 所有元素清空樣式(幹掉其他人)
  • 給當前元素設置樣式(留下我自己)
  • 注意順序不能顛倒,首先幹掉其他人,在設置自己
  1. 栗子1:按鈕點擊變色

  2. 栗子2:換皮膚

    • 給一組元素註冊事件
    • 點擊後頁面背景變化
  3. 栗子3:鼠標經過變色

  4. 栗子4:全選和取消全選

5.5 自定義屬性的操作
獲取方法 不同點
element.屬性 只能獲得內置的屬性(元素本身自帶的)
element.getAttribute(‘屬性’) 主要獲得自定義的屬性(標準)
5.5 設置屬性值
設置方法 不同點
element.屬性 = ‘屬性值’ 內置的屬性
element.setAttribute(‘屬性’, ‘屬性值’) 自定義屬性

注:class比較特殊element.setAttribute('class', '啥啥啥')記住不是className。

5.6 移除屬性

element.removeAttribute('屬性');

5.7 H5自定義屬性
一:
  1. 自定義屬性的目的:是爲了保存並使用數據,有些數據可以保存到頁面中而不用保存到數據庫
  1. 自定義屬性是通過getAttribute(‘屬性’)獲取。
  1. 但是有些自定義屬性很容易引起歧義,不容易判斷是元素的內置屬性還是自定義屬性

注: 爲了解決上述問題我們在設置自定義屬性的時候以 data- 開頭作爲屬性名並賦值
例:<div data-index = "1"><div>

二:
  1. js 添加自定義屬性及屬性值:

    • element.setAttribute('屬性', '啥啥啥') = ‘啥啥啥’
  2. js 獲取自定義屬性值:

    • element.getAttribute('屬性')(兼容性獲取方法)
    • element.dataset.自定義屬性名(H5新增方法)
    • element.dataset['自定義屬性名'](H5新增方法)
    • 注:如果自定義屬性中有多個 "- " 鏈接的單詞, 我們獲取的時候採取的是 駝峯命名法

栗子(important):

<body>
    <div getTime='20' data-index='2' data-list-name="andy"> </div>
    <script>
        var div = document.querySelector('div');
        console.log(div.getAttribute('getTime')); /* 傳統獲取方法 */
        div.setAttribute('data-time', 20); /* 傳統添加方式 */

        console.log(div.getAttribute('data-index')); /* H5新增命名方法 */
        console.log(div.getAttribute('data-list-name'));

        /* h5新增的獲取自定義屬性的方法, 只能獲取 data- 開頭的自定義屬性 ie 11纔開始識別*/
        /* dataset是一個集合裏面存放了所有以data開頭的自定義屬性 */
        console.log(div.dataset); /* 所有的自定義屬性都存放在裏面 */
        console.log(div.dataset.index); /* 和對象的用法一樣,直接提取即可 */
        console.log(div.dataset['index']); /* 第二種方法提取 */

        /*  如果自定義屬性中有多個 " - " 鏈接的單詞, 我們獲取的時候採取的是 駝峯命名法*/
        console.log(div.dataset.listName);
        console.log(div.dataset['listName']);
    </script>
</body>

6. 節點操作

6.1 爲啥學習節點操作
利用DOM提供的方法獲取元素 利用節點的層級關係獲取元素
document.getElementById() 1. 利用利用 父 子 兄 節點關係獲取元素
document.getElementByTagName()
document.querySelector等
邏輯性不強,繁瑣 邏輯性強,操作簡單,但是兼容性差,

在這裏插入圖片描述

6.2 節點概述

一般的,節點至少擁有nodeType(節點類型),nodeName(節點名稱)和nodeValue(節點值)這三個基本屬性。

  • 元素節點 nodeType 爲1
  • 屬性節點 nodeType 爲2
  • 文本節點 nodeType 爲3(文本節點包含文字,空格,換行等)
  • 注:我們在實際開發中,節點操作的是元素節點
6.3 節點層級

利用 DOM 樹可以把節點劃分爲不同的層級關係,常見的是 父 子 兄 的層級關係間 DOM 樹

6.3.1 父節點獲取(element.parentNode)

栗子(important):

<body>
    <div class="box">
        <span class="erweima"></span>
    </div>
    <script>
        /* 1. 父節點 parentNode */
        var erweima = document.querySelector('.erweima');
        /* 2. 得到的是離元素最近的父節點,如果找不到就返回空 */
        console.log(erweima.parentNode);
    </script>
</body>
6.3.2 子節點獲取(element.childNodes)
  1. parentNode.childNodes (標準)

parentNode.childNodes返回包含指定節點的子元素的集合,該集合爲即時更新的集合
注意:

  1. 返回值裏面包含了所有的子節點,包括元素節點,文本節點等
  2. 如果只想要獲得裏面的元素節點,則需要專門處理,所以我們一般不提倡使用childNodes
  3. 如果非要用那麼要加一個條件判斷(利用 元素節點 nodeType 爲1這一性質)
<body>
    <ul>
        <li>我很帥</li>
        <li>我很帥</li>
        <li>我很帥</li>
        <li>我很帥</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        for (var i = 0; i < ul.childNodes.length; i++) {
            if (ul.childNodes[i].nodeType == 1) {
                    // ul.childNodes[i] 是元素節點
                    console.log(ul.childNodes[i]);
            }
        }
    </script>
</body>
  1. parentNode.children (非標準) (庶出)但是卻被廣泛的應用(各個瀏覽器都支持)
<body>
    <ul>
        <li>我很帥</li>
        <li>我很帥</li>
        <li>我很帥</li>
        <li>我很帥</li>
    </ul>
    <script>
        /* DOM提供的方法 (API) 獲取 */
            var ul = document.querySelector('ul');
            var lis = ul.querySelectorAll('li');
        /* 1. 子節點 childNodes 所有的子節點 包含 元素節點 文本節點等等 */
            console.log(ul.childNodes);
            console.log(ul.childNodes[0].nodeType);
            console.log(ul.childNodes[1].nodeType);
        /* 2. children 獲取所有的子元素節點 也是實際開發中常用的 */
            console.log(ul.children);
    </script>
</body>
6.3.3 第一個和最後一個子節點的獲取
  1. element.firstChild :第一個子節點 不管是文本節點還是元素節點
  1. element.lastChild:同理
  1. element.firstElementChild :返回第一個子元素節點,找不到返回null
  1. element.lastElementChild : 同理

注:3 4 種方法有兼容性問題,IE9 以上才支持

實際開發的寫法 既沒有兼容性問題又返回第一個子元素 : console.log(ul.children[0]);

實際開發的寫法 既沒有兼容性問題又返回最後一個子元素 : console.log(ul.children[ul.children.length -1]);

栗子:

<body>
    <ul>
        <li>我很帥1</li>
        <li>我很帥2</li>
        <li>我很帥3</li>
        <li>我很帥4</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        /* firstChild 第一個子節點 不管是文本節點還是元素節點 */
        console.log(ul.firstChild);
        /* 同上 */
        console.log(ul.lastChild);

        /* firstElementChild 返回第一個子元素節點,找不到返回null*/
        console.log(ul.firstElementChild);
        /* lastElementChild 返回最後一個子元素節點,找不到返回null*/
        console.log(ul.lastElementChild);

        /* 實際開發的寫法 既沒有兼容性問題又返回第一個子元素 */
        console.log(ul.children[0]);
        /* 實際開發的寫法 既沒有兼容性問題又返回最後一個子元素 */
        console.log(ul.children[ul.children.length - 1]);
    </script>
</body>
6.3.4兄弟節點
  1. node.nextSibling : 返回下一個兄弟節點,找不到返回null,包含所有的節點
  1. node.previousSibling : 返回上一個兄弟節點,找不到返回null,包含所有的節點
  1. node.nextElementSibling : 返回當前元素下一個兄弟節點(元素節點),找不到則返回null
  1. node.previousElementSibling : 返回當前元素上一個兄弟節點(元素節點),找不到則返回null

注:3 4 種方法有兼容性問題,IE9 以上才支持

栗子:

<body>
    <div>我是div</div>
    <span>我是span</span>
    <script>
        var div = document.querySelector('div');
        /* 得到了文本節點,下一個兄弟節點 包含元素節點或者文本節點等等*/
        console.log(div.nextSibling);
        /* 得到了文本節點,上一個兄弟節點 包含元素節點或者文本節點等等*/
        console.log(div.previousSibling);
        console.log(div.nextElementSibling);
        console.log(div.previousElementSibling);
    </script>
</body>
6.4 創建節點,添加節點
  1. document.createElement(‘element’) : 創建一個元素
  1. 父級.appendChild(變量); : 添加在後面
  1. 父級.insertBefore(變量, 父級.children[0]) : 傳入變量,和要插入的位置
<body>
    <ul>
        <li>123</li>
    </ul>
    <script>
        /* 1. 創建節點元素 */
        var li = document.createElement('li');
        /* 2. 添加節點 node.appendChild(child) node 父級 child 子級 後面追加元素  類似於數組中的push */
        var ul = document.querySelector('ul');
        ul.appendChild(li);
        /* 3. 添加節點 node.insertBefore(child, 指定元素); */
        var lili = document.createElement('li');
        ul.insertBefore(lili, ul.children[0]);
        /* 4. 我們想要頁面添加一個新的元素: 1. 創建元素  2. 添加元素 */
    </script>
</body>

栗子

  1. 模擬留言板(js小案例)
6.5 刪除節點

node.removeChild(child):DOM 中刪除一個子節點,刪除一個子節點,返回刪除的節點

<body>
    <button>delate</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光頭強</li>
    </ul>
    <script>
        // 1. 獲取元素
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
        // 2. 刪除元素

        // 3. 點擊依次刪除
        btn.onclick = function() {
            // if(ul.children.length == 0){
            //     this.disabled = true;
            // }
            for (var i = 0; i < ul.children.length; i++) {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>
</body>

阻止鏈接跳轉添加javascript:void(0);或者javascript:;

栗子

  1. 動態生成表格(js小案例)
6.6 複製節點(克隆節點)

node.cloneNode():返回調用該方法的節點的一個副本,也稱爲克隆節點,拷貝節點

注意:

  1. 如果括號參數爲空或者爲false,則是淺拷貝,即只克隆複製節點本身,不克隆裏面的子節點
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        var lili = ul.children[0].cloneNode(true);
        ul.insertBefore(lili, ul.children[0]);
    </script>
</body>
6.7 三種動態創建元素的區別
  1. https://blog.csdn.net/weixin_45773503/article/details/105945722

總結

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