WebAPI筆記(上)

第一部分
1.1. Web API介紹
1.1.1 API的概念
1.1.2 Web API的概念
1.1.3 API 和 Web API 總結(jié)
1.2. DOM 介紹
1.2.1 什么是DOM
1.2.2. DOM樹
1.3. 獲取元素
1.3.1. 根據(jù)ID獲取
1.3.2. 根據(jù)標(biāo)簽名獲取元素
1.3.3. H5新增獲取元素方式
1.3.4 獲取特殊元素(body,html)
1.4. 事件基礎(chǔ)
1.4.1. 事件概述
1.4.2. 事件三要素
1.4.3. 執(zhí)行事件的步驟
1.4.4. 常見的鼠標(biāo)事件
1.4.5. 分析事件三要素
1.5. 操作元素
1.5.1. 改變?cè)貎?nèi)容(獲取或設(shè)置)
1.5.2. 常用元素的屬性操作
1.5.3. 案例:分時(shí)問(wèn)候
1.5.4. 表單元素的屬性操作
1.5.5. 案例:仿京東顯示密碼
1.5.6. 樣式屬性操作方式
1.6. 今日總結(jié)第二部分
2.1. 排他操作
2.1.1 排他思想
2.2 案例:百度換膚
2.3 案例:表格隔行變色
2.4 案例:全選
2.5. 自定義屬性操作
2.5.1 獲取屬性值
2.5.2. 設(shè)置屬性值
2.5.3. 移出屬性
2.5.4. 案例:tab欄
2.5.5. H5自定義屬性
2.6. 節(jié)點(diǎn)操作
2.6.1. 節(jié)點(diǎn)概述
2.6.2. 節(jié)點(diǎn)層級(jí)
2.6.3. 父級(jí)節(jié)點(diǎn)
2.6.4. 子節(jié)點(diǎn)
2.6.5. 案例:新浪下拉菜單
2.6.6. 兄弟節(jié)點(diǎn)
2.6.7. 創(chuàng)建節(jié)點(diǎn)
2.6.8. 添加節(jié)點(diǎn)
2.6.9. 案例:簡(jiǎn)單版發(fā)布留言
第三部分
3.1. 節(jié)點(diǎn)操作
3.1.1 刪除節(jié)點(diǎn)
3.1.2 案例:刪除留言
3.1.3 復(fù)制(克虑摺)節(jié)點(diǎn)
3.1.4 案例:動(dòng)態(tài)生成表格
3.1.5 創(chuàng)建元素的三種方式
3.1.6 innerTHML和createElement效率對(duì)比
3.2. DOM的核心總結(jié)
3.2.1. 創(chuàng)建
3.2.2. 增加
3.2.3. 刪
3.2.4. 改
3.2.5. 查
3.2.6. 屬性操作
3.2.7. 事件操作(重點(diǎn))
3.3. 事件高級(jí)
3.3.1. 注冊(cè)事件(2種方式)
3.3.2 事件監(jiān)聽
3.3.3. 刪除事件(解綁事件)
3.3.4. DOM事件流
3.3.5. 事件對(duì)象
3.3.6 阻止默認(rèn)行為
3.3.7 阻止事件冒泡
3.3.8 事件委托
3.4. 常用鼠標(biāo)事件
3.4.1 案例:禁止選中文字和禁止右鍵菜單
3.4.2 鼠標(biāo)事件對(duì)象
3.4.3 獲取鼠標(biāo)在頁(yè)面的坐標(biāo)
3.4.4 案例:跟隨鼠標(biāo)的天使
第四部分
4.1. 常用的鍵盤事件
4.1.1 鍵盤事件
4.1.2 鍵盤事件對(duì)象
4.1.3 案例:模擬京東按鍵輸入內(nèi)容
4.1.4 案例:模擬京東快遞單號(hào)查詢
4.2. BOM
4.2.1. 什么是BOM
4.2.2. BOM的構(gòu)成
4.2.3. 頂級(jí)對(duì)象window
4.2.4. window對(duì)象的常見事件頁(yè)面(窗口)加載事件(2種)
4.2.5. 定時(shí)器(兩種)
案例:5秒后關(guān)閉廣告停止定時(shí)器
案例:倒計(jì)時(shí)停止定時(shí)器
案例:發(fā)送短信倒計(jì)時(shí)
4.2.6. this指向問(wèn)題
4.2.7. location對(duì)象
案例:5分鐘自動(dòng)跳轉(zhuǎn)頁(yè)面
案例:獲取URL參數(shù)location對(duì)象的常見方法
4.2.8. navigator對(duì)象
4.2.9 history對(duì)象
4.3. JS執(zhí)行機(jī)制
4.3.1 JS 是單線程
4.3.2 同步任務(wù)和異步任務(wù)
4.3.3 JS執(zhí)行機(jī)制(事件循環(huán))
4.3.4 代碼思考題

第一部分

學(xué)習(xí)目標(biāo):
能夠通過(guò)ID來(lái)獲取元素
能夠通過(guò)標(biāo)簽名來(lái)獲取元素
能夠通過(guò)class來(lái)獲取元素
能夠通過(guò)選擇器來(lái)獲取元素
能夠獲取body和html元素
能夠給元素注冊(cè)事件
能夠修改元素的內(nèi)容
能夠區(qū)分innerText和innerHTML的區(qū)別
能夠修改像div這類普通元素的屬性
能夠修改表單元素的屬性
能夠修改元素的樣式屬性

1.1. Web API介紹

1.1.1 API的概念

? API是一些預(yù)先定義的函數(shù)。

? 無(wú)需理解其內(nèi)部工作機(jī)制細(xì)節(jié),只需直接調(diào)用使用即可。

? 例如爱咬,javascript中函數(shù)alert(),

1.1.2 Web API的概念

? Web API 是瀏覽器提供的一套操作瀏覽器功能和頁(yè)面元素的 API ( BOM 和 DOM )胯究。

? MDN 詳細(xì) API : https://developer.mozilla.org/zh-CN/docs/Web/API

1.1.3 API 和 Web API 總結(jié)

  1. API 是為我們程序員提供的一個(gè)接口色难,幫助我們實(shí)現(xiàn)某種功能泼舱,我們會(huì)使用就可以了,不必糾結(jié)內(nèi)部如何實(shí)現(xiàn)

  2. Web API 主要是針對(duì)于瀏覽器提供的接口枷莉,主要針對(duì)于瀏覽器做交互效果娇昙。

  3. Web API 一般都有輸入和輸出(函數(shù)的傳參和返回值),Web API 很多都是方法(函數(shù))

  4. 學(xué)習(xí) Web API 可以結(jié)合前面學(xué)習(xí)內(nèi)置對(duì)象方法的思路學(xué)習(xí)

1.2. DOM 介紹

1.2.1 什么是DOM

? 文檔對(duì)象模型笤妙,DOM是W3C組織制定的一套處理 html和xml文檔的規(guī)范冒掌,所有的瀏覽器都遵循了這套標(biāo)準(zhǔn)。

1.2.2. DOM樹

  • 1550731974575.png

? DOM樹 又稱為文檔樹模型蹲盘,把文檔映射成樹形結(jié)構(gòu)宋渔,通過(guò)節(jié)點(diǎn)對(duì)象對(duì)其處理,處理的結(jié)果可以加入到當(dāng)前的頁(yè)面辜限。

  • 文檔document:一個(gè)頁(yè)面就是一個(gè)文檔

  • 節(jié)點(diǎn)node:網(wǎng)頁(yè)中的所有內(nèi)容都是節(jié)點(diǎn)(標(biāo)簽、屬性严蓖、文本薄嫡、注釋等)

  • 標(biāo)簽節(jié)點(diǎn)element:網(wǎng)頁(yè)中的所有標(biāo)簽,通常稱為元素節(jié)點(diǎn)/元素

  • 1550732362134.png

1.3. 獲取元素

1.3.1. 根據(jù)ID獲取

語(yǔ)法:document.getElementById(id)
作用:根據(jù)ID獲取元素對(duì)象
參數(shù):id值颗胡,區(qū)分大小寫的字符串
返回值:元素對(duì)象 或 null

案例代碼

<body>
    <div id="time">2019-9-9</div>
    <script>
        // 因?yàn)槲覀兾臋n頁(yè)面從上往下加載毫深,所以先得有標(biāo)簽 所以我們script寫到標(biāo)簽的下面
        var timer = document.getElementById('time');
        console.log(timer);
        console.log(typeof timer);
        // console.dir 打印我們返回的元素對(duì)象 更好的查看里面的屬性和方法
        console.dir(timer);
    </script>
</body>

1.3.2. 根據(jù)標(biāo)簽名獲取元素

語(yǔ)法:document.getElementsByTagName('標(biāo)簽名') 或者 element.getElementsByTagName('標(biāo)簽名') 
作用:根據(jù)標(biāo)簽名獲取元素對(duì)象
參數(shù):標(biāo)簽名
返回值:元素對(duì)象集合(偽數(shù)組,數(shù)組元素是元素對(duì)象)

案例代碼

<body>
    <ul>
        <li>知否知否毒姨,應(yīng)是等你好久11</li>
        <li>知否知否哑蔫,應(yīng)是等你好久22</li>
        <li>知否知否,應(yīng)是等你好久33</li>
        <li>知否知否弧呐,應(yīng)是等你好久44</li>
        <li>知否知否闸迷,應(yīng)是等你好久55</li>
    </ul>
    <ul id="nav">
        <li>生僻字</li>
        <li>生僻字</li>
        <li>生僻字</li>
        <li>生僻字</li>
        <li>生僻字</li>
    </ul>
    <script>
        // 1.返回的是 獲取過(guò)來(lái)元素對(duì)象的集合 以偽數(shù)組的形式存儲(chǔ)的
        var lis = document.getElementsByTagName('li');
        console.log(lis);
        console.log(lis[0]);
        // 2. 我們想要依次打印里面的元素對(duì)象我們可以采取遍歷的方式
        for (var i = 0; i < lis.length; i++) {
            console.log(lis[i]);
        }
        // 3. element.getElementsByTagName()  可以得到這個(gè)元素里面的某些標(biāo)簽
        var nav = document.getElementById('nav'); // 這個(gè)獲得nav 元素
        var navLis = nav.getElementsByTagName('li');
        console.log(navLis);
    </script>
</body>
  • 1550733441663.png

注意:getElementsByTagName()獲取到是動(dòng)態(tài)集合,即:當(dāng)頁(yè)面增加了標(biāo)簽俘枫,這個(gè)集合中也就增加了元素腥沽。

1.3.3. H5新增獲取元素方式

      • 1550733518278.png
      • 1550733734425.png

案例代碼

<body>
    <div class="box">盒子1</div>
    <div class="box">盒子2</div>
    <div id="nav">
        <ul>
            <li>首頁(yè)</li>
            <li>產(chǎn)品</li>
        </ul>
    </div>
    <script>
        // 1. getElementsByClassName 根據(jù)類名獲得某些元素集合
        var boxs = document.getElementsByClassName('box');
        console.log(boxs);
        // 2. querySelector 返回指定選擇器的第一個(gè)元素對(duì)象  切記 里面的選擇器需要加符號(hào) .box  #nav
        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. querySelectorAll()返回指定選擇器的所有元素對(duì)象集合
        var allBox = document.querySelectorAll('.box');
        console.log(allBox);
        var lis = document.querySelectorAll('li');
        console.log(lis);
    </script>
</body>

1.3.4 獲取特殊元素(body勋又,html)

      • 1550733794816.png

1.4. 事件基礎(chǔ)

1.4.1. 事件概述

事件是可以被 JavaScript 偵測(cè)到的行為去扣。

簡(jiǎn)單理解: 觸發(fā)--- 響應(yīng)機(jī)制

? 網(wǎng)頁(yè)中的每個(gè)元素都可以產(chǎn)生某些可以觸發(fā) JavaScript 的事件逊躁,然后去執(zhí)行某些操作茅信。

1.4.2. 事件三要素

  • 事件源(誰(shuí)):觸發(fā)事件的元素
  • 事件類型(什么事件): 例如 click 點(diǎn)擊事件
  • 事件處理程序(做啥):事件觸發(fā)后要執(zhí)行的代碼(函數(shù)形式)盾舌,事件處理函數(shù)

案例代碼

<body>
    <button id="btn">唐伯虎</button>
    <script>
        // 點(diǎn)擊一個(gè)按鈕,彈出對(duì)話框
        // 1. 事件是有三部分組成  事件源  事件類型  事件處理程序   我們也稱為事件三要素
        //(1) 事件源 事件被觸發(fā)的對(duì)象   誰(shuí)  按鈕
        var btn = document.getElementById('btn');
        //(2) 事件類型  如何觸發(fā) 什么事件 比如鼠標(biāo)點(diǎn)擊(onclick) 還是鼠標(biāo)經(jīng)過(guò) 還是鍵盤按下
        //(3) 事件處理程序  通過(guò)一個(gè)函數(shù)賦值的方式 完成
        btn.onclick = function() {
            alert('點(diǎn)秋香');
        }
    </script>
</body>

1.4.3. 執(zhí)行事件的步驟

      • 1550734387056.png

案例代碼

<body>
    <div>123</div>
    <script>
        // 執(zhí)行事件步驟
        // 點(diǎn)擊div 控制臺(tái)輸出 我被選中了
        // 1. 獲取事件源
        var div = document.querySelector('div');
        // 2.綁定事件 注冊(cè)事件
        // div.onclick 
        // 3.添加事件處理程序 
        div.onclick = function() {
            console.log('我被選中了');
        }
    </script>
</body>

1.4.4. 常見的鼠標(biāo)事件

      • 1550734506084.png

1.4.5. 分析事件三要素

  • 下拉菜單三要素

  • 關(guān)閉廣告三要素

1.5. 操作元素

? JavaScript的 DOM 操作可以改變網(wǎng)頁(yè)內(nèi)容蘸鲸、結(jié)構(gòu)和樣式妖谴,我們可以利用 DOM 操作元素來(lái)改變?cè)乩锩娴膬?nèi)容、屬性等酌摇。(注意:這些操作都是通過(guò)元素對(duì)象的屬性實(shí)現(xiàn)的)

1.5.1. 改變?cè)貎?nèi)容(獲取或設(shè)置)

  • element.innerText

從起始位置到終止位置的內(nèi)容窖维,但它去除html 標(biāo)簽榆综,同時(shí)空格和換行也會(huì)去掉

  • element.innerHTML

起始位置到終止位置的全部?jī)?nèi)容,包括html標(biāo)簽铸史,同時(shí)保留空格和換行

1鼻疮、innerText改變?cè)貎?nèi)容

<body>
    <button>顯示當(dāng)前系統(tǒng)時(shí)間</button>
    <div>某個(gè)時(shí)間</div>
    <p>1123</p>
    <script>
        // 當(dāng)我們點(diǎn)擊了按鈕,  div里面的文字會(huì)發(fā)生變化
        // 1. 獲取元素 
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        // 2.注冊(cè)事件
        btn.onclick = function() {
            // div.innerText = '2019-6-6';
            div.innerHTML = getDate();
        }
        function getDate() {
            var date = new Date();
            // 我們寫一個(gè) 2019年 5月 1日 星期三
            var year = date.getFullYear();
            var month = date.getMonth() + 1;
            var dates = date.getDate();
            var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
            var day = date.getDay();
            return '今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day];
        }
    </script>
</body>

2琳轿、innerText和innerHTML的區(qū)別

  • 獲取內(nèi)容時(shí)的區(qū)別:

? innerText會(huì)去除空格和換行判沟,而innerHTML會(huì)保留空格和換行

  • 設(shè)置內(nèi)容時(shí)的區(qū)別:

? innerText不會(huì)識(shí)別html,而innerHTML會(huì)識(shí)別

案例代碼

<body>
    <div></div>
    <p>
        我是文字
        <span>123</span>
    </p>
    <script>
        // innerText 和 innerHTML的區(qū)別 
        // 1. innerText 不識(shí)別html標(biāo)簽 非標(biāo)準(zhǔn)  去除空格和換行
        var div = document.querySelector('div');
        // div.innerText = '<strong>今天是:</strong> 2019';
        // 2. innerHTML 識(shí)別html標(biāo)簽 W3C標(biāo)準(zhǔn) 保留空格和換行的
        div.innerHTML = '<strong>今天是:</strong> 2019';
        // 這兩個(gè)屬性是可讀寫的  可以獲取元素里面的內(nèi)容
        var p = document.querySelector('p');
        console.log(p.innerText);
        console.log(p.innerHTML);
    </script>
</body>

1.5.2. 常用元素的屬性操作

獲取屬性的值

元素對(duì)象.屬性名

設(shè)置屬性的值

元素對(duì)象.屬性名 = 值

案例代碼

<body>
    <button id="ldh">劉德華</button>
    <button id="zxy">張學(xué)友</button> <br>
    <img src="images/ldh.jpg" alt="" title="劉德華">
    <script>
        // 修改元素屬性  src
        // 1. 獲取元素
        var ldh = document.getElementById('ldh');
        var zxy = document.getElementById('zxy');
        var img = document.querySelector('img');
        // 2. 注冊(cè)事件  處理程序
        zxy.onclick = function() {
            img.src = 'images/zxy.jpg';
            img.title = '張學(xué)友思密達(dá)';
        }
        ldh.onclick = function() {
            img.src = 'images/ldh.jpg';
            img.title = '劉德華';
        }
    </script>
</body>

1.5.3. 案例:分時(shí)問(wèn)候

      • 1550735858049.png
      • 1550735877145.png

1.5.4. 表單元素的屬性操作

表單屬性:type value checked selected disabled

獲取屬性的值

元素對(duì)象.屬性名

設(shè)置屬性的值

元素對(duì)象.屬性名 = 值

表單元素中有一些屬性如:disabled崭篡、checked挪哄、selected,元素對(duì)象的這些屬性的值是布爾型琉闪。

案例代碼

<body>
    <button>按鈕</button>
    <input type="text" value="輸入內(nèi)容">
    <script>
        // 1. 獲取元素
        var btn = document.querySelector('button');
        var input = document.querySelector('input');
        // 2. 注冊(cè)事件 處理程序
        btn.onclick = function() {
            // 表單里面的值 文字內(nèi)容是通過(guò) value 來(lái)修改的
            input.value = '被點(diǎn)擊了';
            // 如果想要某個(gè)表單被禁用 不能再點(diǎn)擊 disabled  我們想要這個(gè)按鈕 button禁用
            // btn.disabled = true;
            this.disabled = true;
            // this 指向的是事件函數(shù)的調(diào)用者 btn
        }
    </script>
</body>

1.5.5. 案例:仿京東顯示密碼

      • 1550736346822.png

1.5.6. 樣式屬性操作

我們可以通過(guò) JS 修改元素的大小迹炼、顏色、位置等樣式颠毙。

常用方式:

1斯入、行內(nèi)樣式操作:element.style
2、類名樣式操作:element.className

方式1:通過(guò)操作style屬性

元素對(duì)象的style屬性也是一個(gè)對(duì)象蛀蜜!
元素對(duì)象.style.樣式屬性 = 值;

注意:樣式屬性名用駝峰命名法刻两,如fontSize backgroundColor; 該方式修改后css權(quán)重比較高

get start

<body>
    <div></div>
    <script>
        // 1. 獲取元素
        var div = document.querySelector('div');
        // 2. 注冊(cè)事件 處理程序
        div.onclick = function() {
            // div.style里面的屬性 采取駝峰命名法 
            this.style.backgroundColor = 'purple';
            this.style.width = '250px';
        }
    </script>
</body>

案例:淘寶點(diǎn)擊關(guān)閉二維碼

      • 1550736881832.png

案例:循環(huán)精靈圖背景

      • 1550736956754.png

案例:顯示隱藏文本框內(nèi)容

      • 1550737019729.png

方式2:通過(guò)操作className屬性

元素對(duì)象.className = 值;

因?yàn)閏lass是關(guān)鍵字,所有使用className滴某。

      • 1550737214510.png

案例代碼

<body>
    <div class="first">文本</div>
    <script>
        // 1. 使用 element.style 獲得修改元素樣式  如果樣式比較少 或者 功能簡(jiǎn)單的情況下使用
        var test = document.querySelector('div');
        test.onclick = function() {
            // this.style.backgroundColor = 'purple';
            // this.style.color = '#fff';
            // this.style.fontSize = '25px';
            // this.style.marginTop = '100px';

            // 2. 我們可以通過(guò) 修改元素的className更改元素的樣式 適合于樣式較多或者功能復(fù)雜的情況
            // 3. 如果想要保留原先的類名磅摹,我們可以這么做 多類名選擇器
            // this.className = 'change';
            this.className = 'first change';
        }
    </script>
</body>

案例:密碼框格式提示錯(cuò)誤信息

要求輸入 6-16位

      • 1550737284218.png

第二部分

學(xué)習(xí)目標(biāo):

能夠說(shuō)出排他操作的一般實(shí)現(xiàn)步驟

能夠使用html5中的dataset方式操作自定義屬性

能夠根據(jù)提示完成百度換膚的案例

能夠根據(jù)提示完成全選案例

能夠根據(jù)提示完成tab欄切換案例

能夠區(qū)分元素節(jié)點(diǎn)、文本節(jié)點(diǎn)霎奢、屬性節(jié)點(diǎn)

能夠獲取指定元素的父元素

能夠獲取指定元素的所有子元素

能夠說(shuō)出childNodes和children的區(qū)別

能夠使用createElement創(chuàng)建頁(yè)面元素

2.1. 排他操作

2.1.1 排他思想

      • 1550914482628.png

如果有同一組元素户誓,我們想要某一個(gè)元素實(shí)現(xiàn)某種樣式, 需要用到循環(huán)的排他思想算法:

  1. 所有元素全部清除樣式(干掉其他人)

  2. 給當(dāng)前元素設(shè)置樣式 (留下我自己)

  3. 注意順序不能顛倒幕侠,首先干掉其他人厅克,再設(shè)置自己

    <button>按鈕1</button>
    <button>按鈕2</button>
    <button>按鈕3</button>
    <button>按鈕4</button>
    <button>按鈕5</button>
    <script>
        // 1. 獲取所有按鈕元素
        var btns = document.getElementsByTagName('button');
        // btns得到的是偽數(shù)組  里面的每一個(gè)元素 btns[i]
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function() {
                // (1) 我們先把所有的按鈕背景顏色去掉  干掉所有人
                for (var i = 0; i < btns.length; i++) {
                    btns[i].style.backgroundColor = '';
                }
                // (2) 然后才讓當(dāng)前的元素背景顏色為pink 留下我自己
                this.style.backgroundColor = 'pink';

            }
        }
    </script>

2.2 案例:百度換膚

      • 1550914640677.png
      • 1550914663042.png
<body>
    <ul class="baidu">
        <li><img src="images/1.jpg"></li>
        <li><img src="images/2.jpg"></li>
        <li><img src="images/3.jpg"></li>
        <li><img src="images/4.jpg"></li>
    </ul>
    <script>
        // 1. 獲取元素 
        var imgs = document.querySelector('.baidu').querySelectorAll('img');
        // console.log(imgs);
        // 2. 循環(huán)注冊(cè)事件 
        for (var i = 0; i < imgs.length; i++) {
            imgs[i].onclick = function() {
                // this.src 就是我們點(diǎn)擊圖片的路徑   images/2.jpg
                // console.log(this.src);
                // 把這個(gè)路徑 this.src 給body 就可以了
                document.body.style.backgroundImage = 'url(' + this.src + ')';
            }
        }
    </script>
</body>

2.3 案例:表格隔行變色

      • 1550914812202.png
    <script>
        // 1.獲取元素 獲取的是 tbody 里面所有的行
        var trs = document.querySelector('tbody').querySelectorAll('tr');
        // 2. 利用循環(huán)綁定注冊(cè)事件
        for (var i = 0; i < trs.length; i++) {
            // 3. 鼠標(biāo)經(jīng)過(guò)事件 onmouseover
            trs[i].onmouseover = function() {
                    // console.log(11);
                    this.className = 'bg';
                }
                // 4. 鼠標(biāo)離開事件 onmouseout
            trs[i].onmouseout = function() {
                this.className = '';
            }
        }
    </script>

2.4 案例:全選

      • 1550915005393.png
    <script>
        // 1. 全選和取消全選做法:  讓下面所有復(fù)選框的checked屬性(選中狀態(tài)) 跟隨 全選按鈕即可
        // 獲取元素
        
        var j_cbAll = document.getElementById('j_cbAll'); 
        var j_tbs = document.getElementById('j_tb').getElementsByTagName('input'); 
        // 全選按鈕注冊(cè)事件
        j_cbAll.onclick = function() {
                // this.checked 當(dāng)前復(fù)選框的選中狀態(tài)
                console.log(this.checked);
                for (var i = 0; i < j_tbs.length; i++) {
                    j_tbs[i].checked = this.checked;
                }
         }
         // 給所有的子復(fù)選框注冊(cè)單擊事件
        for (var i = 0; i < j_tbs.length; i++) {
            j_tbs[i].onclick = function() {
                // flag 控制全選按鈕是否選中
                var flag = true;
                // 每次點(diǎn)擊下面的復(fù)選框都要循環(huán)檢查者4個(gè)小按鈕是否全被選中
                for (var i = 0; i < j_tbs.length; i++) {
                    if (!j_tbs[i].checked) {
                        flag = false;
                        break; 
                    }
                }
                // 設(shè)置全選按鈕的狀態(tài)
                j_cbAll.checked = flag;
            }
        }
    </script>

2.5. 自定義屬性操作

2.5.1 獲取屬性值

      • 1550915376339.png
    <div id="demo" index="1" class="nav"></div>
    <script>
        var div = document.querySelector('div');
        // 1. 獲取元素的屬性值
        // (1) element.屬性
        console.log(div.id);
        //(2) element.getAttribute('屬性')  get得到獲取 attribute 屬性的意思 我們程序員自己添加的屬性我們稱為自定義屬性 index
        console.log(div.getAttribute('id'));
        console.log(div.getAttribute('index'));
    </script>

2.5.2. 設(shè)置屬性值

      • 1550915445026.png
        // 2. 設(shè)置元素屬性值
        // (1) element.屬性= '值'
        div.id = 'test';
        div.className = 'navs';
        // (2) element.setAttribute('屬性', '值');  主要針對(duì)于自定義屬性
        div.setAttribute('index', 2);
        div.setAttribute('class', 'footer'); // class 特殊  這里面寫的就是

2.5.3. 移出屬性

element.removeAttribute('屬性')

        // class 不是className
        // 3 移除屬性 removeAttribute(屬性)    
        div.removeAttribute('index');

2.5.4. 案例:tab欄

      • 1550915567627.png
      • 1550915590707.png
    <script>
        // 獲取元素
        var tab_list = document.querySelector('.tab_list');
        var lis = tab_list.querySelectorAll('li');
        var items = document.querySelectorAll('.item');
        // for循環(huán),給選項(xiàng)卡綁定點(diǎn)擊事件
        for (var i = 0; i < lis.length; i++) {
            // 開始給5個(gè)小li 設(shè)置索引號(hào) 
            lis[i].setAttribute('index', i);
            lis[i].onclick = function() {
                // 1. 上的模塊選項(xiàng)卡橙依,當(dāng)前這一個(gè)底色會(huì)是紅色证舟,其余不變(排他思想)
                // 干掉所有人 其余的li清除 class 這個(gè)類
                for (var i = 0; i < lis.length; i++) {
                    lis[i].className = '';
                }
                // 留下我自己 
                this.className = 'current';
                // 2. 下面的顯示內(nèi)容模塊
                var index = this.getAttribute('index');
                console.log(index);
                // 干掉所有人 讓其余的item 這些div 隱藏
                for (var i = 0; i < items.length; i++) {
                    items[i].style.display = 'none';
                }
                // 留下我自己 讓對(duì)應(yīng)的item 顯示出來(lái)
                items[index].style.display = 'block';
            }
        }
    </script>

2.5.5. H5自定義屬性

自定義屬性目的:是為了保存并使用數(shù)據(jù)。有些數(shù)據(jù)可以保存到頁(yè)面中而不用保存到數(shù)據(jù)庫(kù)中窗骑。

自定義屬性獲取是通過(guò)getAttribute(‘屬性’) 獲取女责。

但是有些自定義屬性很容易引起歧義,不容易判斷是元素的內(nèi)置屬性還是自定義屬性创译。

H5給我們新增了自定義屬性:

      • 1550915798516.png
      • 1550915815571.png
    <div getTime="20" data-index="2" data-list-name="andy"></div>
    <script>
        var div = document.querySelector('div');
        // console.log(div.getTime);
        console.log(div.getAttribute('getTime'));
        div.setAttribute('data-time', 20);
        console.log(div.getAttribute('data-index'));
        console.log(div.getAttribute('data-list-name'));
        // h5新增的獲取自定義屬性的方法 它只能獲取data-開頭的
        // dataset 是一個(gè)集合里面存放了所有以data開頭的自定義屬性
        console.log(div.dataset);
        console.log(div.dataset.index);
        console.log(div.dataset['index']);
        // 如果自定義屬性里面有多個(gè)-鏈接的單詞抵知,我們獲取的時(shí)候采取 駝峰命名法
        console.log(div.dataset.listName);
        console.log(div.dataset['listName']);
    </script>

2.6. 節(jié)點(diǎn)操作

2.6.1. 節(jié)點(diǎn)概述

? 網(wǎng)頁(yè)中的所有內(nèi)容都是節(jié)點(diǎn)(標(biāo)簽、屬性、文本刷喜、注釋等)残制,在DOM 中,節(jié)點(diǎn)使用 node 來(lái)表示掖疮。

? HTML DOM 樹中的所有節(jié)點(diǎn)均可通過(guò) JavaScript 進(jìn)行訪問(wèn)初茶,所有 HTML 元素(節(jié)點(diǎn))均可被修改,也可以創(chuàng)建或刪除浊闪。

? 一般地恼布,節(jié)點(diǎn)至少擁有nodeType(節(jié)點(diǎn)類型)、nodeName(節(jié)點(diǎn)名稱)和nodeValue(節(jié)點(diǎn)值)這三個(gè)基本屬性搁宾。

      • 1550970986988.png

2.6.2. 節(jié)點(diǎn)層級(jí)

? 利用 DOM 樹可以把節(jié)點(diǎn)劃分為不同的層級(jí)關(guān)系折汞,常見的是父子兄層級(jí)關(guān)系

2.6.3. 父級(jí)節(jié)點(diǎn)

      • 1550971196686.png
    <div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
    </div>
    <script>
        // 1. 父節(jié)點(diǎn) parentNode
        var erweima = document.querySelector('.erweima');
        // var box = document.querySelector('.box');
        // 得到的是離元素最近的父級(jí)節(jié)點(diǎn)(親爸爸) 如果找不到父節(jié)點(diǎn)就返回為 null
        console.log(erweima.parentNode);
    </script>

2.6.4. 子節(jié)點(diǎn)

所有子節(jié)點(diǎn)

      • 1550971263925.png

子元素節(jié)點(diǎn)

      • 1550971325828.png
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <script>
        // DOM 提供的方法(API)獲取
        var ul = document.querySelector('ul');
        var lis = ul.querySelectorAll('li');
        // 1. 子節(jié)點(diǎn)  childNodes 所有的子節(jié)點(diǎn) 包含 元素節(jié)點(diǎn) 文本節(jié)點(diǎn)等等
        console.log(ul.childNodes);
        console.log(ul.childNodes[0].nodeType);
        console.log(ul.childNodes[1].nodeType);
        // 2. children 獲取所有的子元素節(jié)點(diǎn) 也是我們實(shí)際開發(fā)常用的
        console.log(ul.children);
    </script>

第1個(gè)子節(jié)點(diǎn)

  • 1550971774758.png

最后1個(gè)子節(jié)點(diǎn)

  • 1550972014509.png
  • 1550971825493.png

第1個(gè)子元素節(jié)點(diǎn)

  • 1550972014509.png

最后1個(gè)子元素節(jié)點(diǎn)

  • 1550972106485.png

? 實(shí)際開發(fā)中盖腿,firstChild 和 lastChild 包含其他節(jié)點(diǎn)爽待,操作不方便,而 firstElementChild 和 lastElementChild 又有兼容性問(wèn)題翩腐,那么我們?nèi)绾潍@取第一個(gè)子元素節(jié)點(diǎn)或最后一個(gè)子元素節(jié)點(diǎn)呢鸟款?

  • 1550972648014.png
    <ol>
        <li>我是li1</li>
        <li>我是li2</li>
        <li>我是li3</li>
        <li>我是li4</li>
        <li>我是li5</li>
    </ol>
    <script>
        var ol = document.querySelector('ol');
        // 1. firstChild 第一個(gè)子節(jié)點(diǎn) 不管是文本節(jié)點(diǎn)還是元素節(jié)點(diǎn)
        console.log(ol.firstChild);
        console.log(ol.lastChild);
        // 2. firstElementChild 返回第一個(gè)子元素節(jié)點(diǎn) ie9才支持
        console.log(ol.firstElementChild);
        console.log(ol.lastElementChild);
        // 3. 實(shí)際開發(fā)的寫法  既沒有兼容性問(wèn)題又返回第一個(gè)子元素
        console.log(ol.children[0]);
        console.log(ol.children[ol.children.length - 1]);
    </script>

2.6.5. 案例:新浪下拉菜單

  • 1550974934894.png
  • 1550975025608.png
  • 1550975049176.png
    <script>
        // 1. 獲取元素
        var nav = document.querySelector('.nav');
        var lis = nav.children; // 得到4個(gè)小li
        // 2.循環(huán)注冊(cè)事件
        for (var i = 0; i < lis.length; i++) {
            lis[i].onmouseover = function() {
                this.children[1].style.display = 'block';
            }
            lis[i].onmouseout = function() {
                this.children[1].style.display = 'none';
            }
        }
    </script>

2.6.6. 兄弟節(jié)點(diǎn)

下一個(gè)兄弟節(jié)點(diǎn)

  • 1550973538696.png

上一個(gè)兄弟節(jié)點(diǎn)

  • 1550973558511.png
    <div>我是div</div>
    <span>我是span</span>
    <script>
        var div = document.querySelector('div');
        // 1.nextSibling 下一個(gè)兄弟節(jié)點(diǎn) 包含元素節(jié)點(diǎn)或者 文本節(jié)點(diǎn)等等
        console.log(div.nextSibling);
        console.log(div.previousSibling);
        // 2. nextElementSibling 得到下一個(gè)兄弟元素節(jié)點(diǎn)
        console.log(div.nextElementSibling);
        console.log(div.previousElementSibling);
    </script>

下一個(gè)兄弟元素節(jié)點(diǎn)(有兼容性問(wèn)題)

  • 1550973610223.png

上一個(gè)兄弟元素節(jié)點(diǎn)(有兼容性問(wèn)題)

  • 1550973630150.png
  • 1550973722805.png
  • 1550973799759.png
   function getNextElementSibling(element) {
      var el = element;
      while (el = el.nextSibling) {
        if (el.nodeType === 1) {
            return el;
        }
      }
      return null;
    }  

2.6.7. 創(chuàng)建節(jié)點(diǎn)

  • 1550975514321.png

2.6.8. 添加節(jié)點(diǎn)

    <ul>
        <li>123</li>
    </ul>
    <script>
        // 1. 創(chuàng)建節(jié)點(diǎn)元素節(jié)點(diǎn)
        var li = document.createElement('li');
        // 2. 添加節(jié)點(diǎn) node.appendChild(child)  node 父級(jí)  child 是子級(jí) 后面追加元素
        var ul = document.querySelector('ul');
        ul.appendChild(li);
        // 3. 添加節(jié)點(diǎn) node.insertBefore(child, 指定元素);
        var lili = document.createElement('li');
        ul.insertBefore(lili, ul.children[0]);
        // 4. 我們想要頁(yè)面添加一個(gè)新的元素 : 1. 創(chuàng)建元素 2. 添加元素
    </script>

2.6.9. 案例:簡(jiǎn)單版發(fā)布留言

  • 1550975849302.png
  • 1550975887017.png
<body>
    <textarea name="" id=""></textarea>
    <button>發(fā)布</button>
    <ul>

    </ul>
    <script>
        // 1. 獲取元素
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        // 2. 注冊(cè)事件
        btn.onclick = function() {
            if (text.value == '') {
                alert('您沒有輸入內(nèi)容');
                return false;
            } else {
                // console.log(text.value);
                // (1) 創(chuàng)建元素
                var li = document.createElement('li');
                // 先有l(wèi)i 才能賦值
                li.innerHTML = text.value;
                // (2) 添加元素
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);
            }
        }
    </script>
</body>

第三部分

學(xué)習(xí)目標(biāo):

能夠使用removeChild()方法刪除節(jié)點(diǎn)

能夠完成動(dòng)態(tài)生成表格案例

能夠使用傳統(tǒng)方式和監(jiān)聽方式給元素注冊(cè)事件

能夠說(shuō)出事件流執(zhí)行的三個(gè)階段

能夠在事件處理函數(shù)中獲取事件對(duì)象

能夠使用事件對(duì)象取消默認(rèn)行為

能夠使用事件對(duì)象阻止事件冒泡

能夠使用事件對(duì)象獲取鼠標(biāo)的位置

能夠完成跟隨鼠標(biāo)的天使案例

3.1. 節(jié)點(diǎn)操作

3.1.1 刪除節(jié)點(diǎn)

node.removeChild() 方法從 node節(jié)點(diǎn)中刪除一個(gè)子節(jié)點(diǎn),返回刪除的節(jié)點(diǎn)栗菜。

    <button>刪除</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光頭強(qiáng)</li>
    </ul>
    <script>
        // 1.獲取元素
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
        // 2. 刪除元素  node.removeChild(child)
        // ul.removeChild(ul.children[0]);
        // 3. 點(diǎn)擊按鈕依次刪除里面的孩子
        btn.onclick = function() {
            if (ul.children.length == 0) {
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>

3.1.2 案例:刪除留言

  • 1551163586475.png
  • 1551163635501.png
    <textarea name="" id=""></textarea>
    <button>發(fā)布</button>
    <ul>

    </ul>
    <script>
        // 1. 獲取元素
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        // 2. 注冊(cè)事件
        btn.onclick = function() {
            if (text.value == '') {
                alert('您沒有輸入內(nèi)容');
                return false;
            } else {
                // console.log(text.value);
                // (1) 創(chuàng)建元素
                var li = document.createElement('li');
                // 先有l(wèi)i 才能賦值
                li.innerHTML = text.value + "<a href='javascript:;'>刪除</a>";
                // (2) 添加元素
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);
                // (3) 刪除元素 刪除的是當(dāng)前鏈接的li  它的父親
                var as = document.querySelectorAll('a');
                for (var i = 0; i < as.length; i++) {
                    as[i].onclick = function() {
                        // 刪除的是 li 當(dāng)前a所在的li  this.parentNode;
                        ul.removeChild(this.parentNode);
                    }
                }
            }
        }
    </script>

3.1.3 復(fù)制(克隆)節(jié)點(diǎn)

  • 1551163763825.png
    <ul>
        <li>1111</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        // 1. node.cloneNode(); 括號(hào)為空或者里面是false 淺拷貝 只復(fù)制標(biāo)簽不復(fù)制里面的內(nèi)容
        // 2. node.cloneNode(true); 括號(hào)為true 深拷貝 復(fù)制標(biāo)簽復(fù)制里面的內(nèi)容
        var lili = ul.children[0].cloneNode(true);
        ul.appendChild(lili);
    </script>

3.1.4 案例:動(dòng)態(tài)生成表格

  • 1551163900675.png
  • 1551163924396.png
    <script>
        // 1.先去準(zhǔn)備好學(xué)生的數(shù)據(jù)
        var datas = [{
            name: '魏瓔珞',
            subject: 'JavaScript',
            score: 100
        }, {
            name: '弘歷',
            subject: 'JavaScript',
            score: 98
        }, {
            name: '傅恒',
            subject: 'JavaScript',
            score: 99
        }, {
            name: '明玉',
            subject: 'JavaScript',
            score: 88
        }, {
            name: '大豬蹄子',
            subject: 'JavaScript',
            score: 0
        }];
        // 2. 往tbody 里面創(chuàng)建行: 有幾個(gè)人(通過(guò)數(shù)組的長(zhǎng)度)我們就創(chuàng)建幾行
        var tbody = document.querySelector('tbody');
        // 遍歷數(shù)組
        for (var i = 0; i < datas.length; i++) { 
            // 1. 創(chuàng)建 tr行
            var tr = document.createElement('tr');
            tbody.appendChild(tr);
            // 2. 行里面創(chuàng)建單元格td 單元格的數(shù)量取決于每個(gè)對(duì)象里面的屬性個(gè)數(shù)  
            // 使用for in遍歷學(xué)生對(duì)象
            for (var k in datas[i]) { 
                // 創(chuàng)建單元格 
                var td = document.createElement('td');
                // 把對(duì)象里面的屬性值 datas[i][k] 給 td  
                td.innerHTML = datas[i][k];
                tr.appendChild(td);
            }
            // 3. 創(chuàng)建有刪除2個(gè)字的單元格 
            var td = document.createElement('td');
            td.innerHTML = '<a href="javascript:;">刪除 </a>';
            tr.appendChild(td);

        }
        // 4. 刪除操作 開始 
        var as = document.querySelectorAll('a');
        for (var i = 0; i < as.length; i++) {
            as[i].onclick = function() {
                // 點(diǎn)擊a 刪除 當(dāng)前a 所在的行(鏈接的爸爸的爸爸)  node.removeChild(child)  
                tbody.removeChild(this.parentNode.parentNode)
            }
        }
    </script>

3.1.5 創(chuàng)建元素的三種方式

  • 1551164214925.png
    <script>
        // 三種創(chuàng)建元素方式區(qū)別 
        // 1. document.write() 創(chuàng)建元素  如果頁(yè)面文檔流加載完畢蹄梢,再調(diào)用這句話會(huì)導(dǎo)致頁(yè)面重繪
         var btn = document.querySelector('button');
         btn.onclick = function() {
             document.write('<div>123</div>');
         }

        // 2. innerHTML 創(chuàng)建元素
        var inner = document.querySelector('.inner');
         for (var i = 0; i <= 100; i++) {
             inner.innerHTML += '<a href="#">百度</a>'
         }
        var arr = [];
        for (var i = 0; i <= 100; i++) {
            arr.push('<a href="#">百度</a>');
        }
        inner.innerHTML = arr.join('');
        // 3. document.createElement() 創(chuàng)建元素
        var create = document.querySelector('.create');
        for (var i = 0; i <= 100; i++) {
            var a = document.createElement('a');
            create.appendChild(a);
        }
    </script>

3.1.6 innerTHML和createElement效率對(duì)比

innerHTML字符串拼接方式(效率低)

<script>
    function fn() {
        var d1 = +new Date();
        var str = '';
        for (var i = 0; i < 1000; i++) {
            document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
        }
        var d2 = +new Date();
        console.log(d2 - d1);
    }
    fn();
</script>

createElement方式(效率一般)

<script>
    function fn() {
        var d1 = +new Date();

        for (var i = 0; i < 1000; i++) {
            var div = document.createElement('div');
            div.style.width = '100px';
            div.style.height = '2px';
            div.style.border = '1px solid red';
            document.body.appendChild(div);
        }
        var d2 = +new Date();
        console.log(d2 - d1);
    }
    fn();
</script>

innerHTML數(shù)組方式(效率高)

<script>
    function fn() {
        var d1 = +new Date();
        var array = [];
        for (var i = 0; i < 1000; i++) {
            array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
        }
        document.body.innerHTML = array.join('');
        var d2 = +new Date();
        console.log(d2 - d1);
    }
    fn();
</script>

3.2. DOM的核心總結(jié)

  • 1551164669434.png
  • 1551164715018.png

關(guān)于dom操作疙筹,我們主要針對(duì)于元素的操作。主要有創(chuàng)建禁炒、增而咆、刪、改幕袱、查暴备、屬性操作、事件操作们豌。

3.2.1. 創(chuàng)建

  • 1551164797164.png

3.2.2. 增加

  • 1551164829832.png

3.2.3. 刪

  • 1551164872533.png

3.2.4. 改

  • 1551164907830.png

3.2.5. 查

  • 1551164936214.png

3.2.6. 屬性操作

  • 1551164985383.png

3.2.7. 事件操作(重點(diǎn))

給元素注冊(cè)事件涯捻,采取 事件源.事件類型 = 事件處理程序

  • 1551172699854.png

3.3. 事件高級(jí)

3.3.1. 注冊(cè)事件(2種方式)

  • 1551165252019.png

3.3.2 事件監(jiān)聽

  • addEventListener()(IE9以后支持)

  • 1551165364122.png
  • 1551165604792.png
  • attacheEvent()(IE678支持)

  • 1551165781836.png
  • 1551165843912.png
<button>傳統(tǒng)注冊(cè)事件</button>
<button>方法監(jiān)聽注冊(cè)事件</button>
<button>ie9 attachEvent</button>
<script>
    var btns = document.querySelectorAll('button');
    // 1. 傳統(tǒng)方式注冊(cè)事件
    btns[0].onclick = function() {
        alert('hi');
    }
    btns[0].onclick = function() {
            alert('hao a u');
        }
   // 2. 事件偵聽注冊(cè)事件 addEventListener 
   // (1) 里面的事件類型是字符串 必定加引號(hào) 而且不帶on
   // (2) 同一個(gè)元素 同一個(gè)事件可以添加多個(gè)偵聽器(事件處理程序)
    btns[1].addEventListener('click', function() {
        alert(22);
    })
    btns[1].addEventListener('click', function() {
            alert(33);
    })
    // 3. attachEvent ie9以前的版本支持
    btns[2].attachEvent('onclick', function() {
        alert(11);
    })
</script>

事件監(jiān)聽兼容性解決方案

封裝一個(gè)函數(shù),函數(shù)中判斷瀏覽器的類型:

  • 1551166023885.png

3.3.3. 刪除事件(解綁事件)

  • 1551166185410.png
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script>
        var divs = document.querySelectorAll('div');
        divs[0].onclick = function() {
            alert(11);
            // 1. 傳統(tǒng)方式刪除事件
            divs[0].onclick = null;
        }
        // 2. removeEventListener 刪除事件
        divs[1].addEventListener('click', fn) // 里面的fn 不需要調(diào)用加小括號(hào)
        function fn() {
            alert(22);
            divs[1].removeEventListener('click', fn);
        }
        // 3. detachEvent
        divs[2].attachEvent('onclick', fn1);

        function fn1() {
            alert(33);
            divs[2].detachEvent('onclick', fn1);
        }
    </script>

**刪除事件兼容性解決方案 **

  • 1551166332453.png

3.3.4. DOM事件流

  • 1551166423144.png

比如:我們給頁(yè)面中的一個(gè)div注冊(cè)了單擊事件望迎,當(dāng)你單擊了div時(shí)障癌,也就單擊了body,單擊了html辩尊,單擊了document涛浙。

  • 1551166555833.png
  • 1551166581552.png
當(dāng)時(shí)的2大瀏覽器霸主誰(shuí)也不服誰(shuí)!
IE 提出從目標(biāo)元素開始,然后一層一層向外接收事件并響應(yīng)轿亮,也就是冒泡型事件流疮薇。
Netscape(網(wǎng)景公司)提出從最外層開始,然后一層一層向內(nèi)接收事件并響應(yīng)我注,也就是捕獲型事件流按咒。

江湖紛爭(zhēng),武林盟主也腦殼疼2质帧E制搿!

最終嗽冒,w3c 采用折中的方式呀伙,平息了戰(zhàn)火,制定了統(tǒng)一的標(biāo)準(zhǔn) —--— 先捕獲再冒泡添坊。
現(xiàn)代瀏覽器都遵循了此標(biāo)準(zhǔn)剿另,所以當(dāng)事件發(fā)生時(shí),會(huì)經(jīng)歷3個(gè)階段贬蛙。

DOM 事件流會(huì)經(jīng)歷3個(gè)階段:

  1. 捕獲階段

  2. 當(dāng)前目標(biāo)階段

  3. 冒泡階段

? 我們向水里面扔一塊石頭雨女,首先它會(huì)有一個(gè)下降的過(guò)程,這個(gè)過(guò)程就可以理解為從最頂層向事件發(fā)生的最具體元素(目標(biāo)點(diǎn))的捕獲過(guò)程阳准;之后會(huì)產(chǎn)生泡泡氛堕,會(huì)在最低點(diǎn)( 最具體元素)之后漂浮到水面上,這個(gè)過(guò)程相當(dāng)于事件冒泡野蝇。

  • 1551169007768.png
  • 1551169042295.png

事件冒泡

    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        // onclick 和 attachEvent(ie) 在冒泡階段觸發(fā)
        // 冒泡階段 如果addEventListener 第三個(gè)參數(shù)是 false 或者 省略 
        // son -> father ->body -> html -> document
        var son = document.querySelector('.son');
        // 給son注冊(cè)單擊事件
        son.addEventListener('click', function() {
            alert('son');
        }, false);
        // 給father注冊(cè)單擊事件
        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, false);
        // 給document注冊(cè)單擊事件讼稚,省略第3個(gè)參數(shù)
        document.addEventListener('click', function() {
            alert('document');
        })
    </script>

事件捕獲

    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        // 如果addEventListener() 第三個(gè)參數(shù)是 true 那么在捕獲階段觸發(fā)
        // document -> html -> body -> father -> son
         var son = document.querySelector('.son');
        // 給son注冊(cè)單擊事件,第3個(gè)參數(shù)為true
         son.addEventListener('click', function() {
             alert('son');
         }, true);
         var father = document.querySelector('.father');
        // 給father注冊(cè)單擊事件绕沈,第3個(gè)參數(shù)為true
         father.addEventListener('click', function() {
             alert('father');
         }, true);
        // 給document注冊(cè)單擊事件锐想,第3個(gè)參數(shù)為true
        document.addEventListener('click', function() {
            alert('document');
        }, true)
    </script>

3.3.5. 事件對(duì)象

什么是事件對(duì)象

事件發(fā)生后,跟事件相關(guān)的一系列信息數(shù)據(jù)的集合都放到這個(gè)對(duì)象里面乍狐,這個(gè)對(duì)象就是事件對(duì)象赠摇。

比如:

  1. 誰(shuí)綁定了這個(gè)事件。

  2. 鼠標(biāo)觸發(fā)事件的話浅蚪,會(huì)得到鼠標(biāo)的相關(guān)信息藕帜,如鼠標(biāo)位置。

  3. 鍵盤觸發(fā)事件的話惜傲,會(huì)得到鍵盤的相關(guān)信息耘戚,如按了哪個(gè)鍵。

事件對(duì)象的使用

事件觸發(fā)發(fā)生時(shí)就會(huì)產(chǎn)生事件對(duì)象操漠,并且系統(tǒng)會(huì)以實(shí)參的形式傳給事件處理函數(shù)收津。

所以饿这,在事件處理函數(shù)中聲明1個(gè)形參用來(lái)接收事件對(duì)象。

  • 1551169537789.png

事件對(duì)象的兼容性處理

事件對(duì)象本身的獲取存在兼容問(wèn)題:

  1. 標(biāo)準(zhǔn)瀏覽器中是瀏覽器給方法傳遞的參數(shù)撞秋,只需要定義形參 e 就可以獲取到长捧。

  2. 在 IE6~8 中,瀏覽器不會(huì)給方法傳遞參數(shù)吻贿,如果需要的話串结,需要到 window.event 中獲取查找。

  • 1551169680823.png
只要“||”前面為false, 不管“||”后面是true 還是 false舅列,都返回 “||” 后面的值肌割。
只要“||”前面為true, 不管“||”后面是true 還是 false,都返回 “||” 前面的值帐要。
    <div>123</div>
    <script>
        var div = document.querySelector('div');
        div.onclick = function(e) {
                // 事件對(duì)象
                e = e || window.event;
                console.log(e);
        }
    </script>

事件對(duì)象的屬性和方法

  • 1551169931778.png

e.target 和 this 的區(qū)別

  • this 是事件綁定的元素(綁定這個(gè)事件處理函數(shù)的元素) 把敞。

  • e.target 是事件觸發(fā)的元素。

常情況下terget 和 this是一致的榨惠,
但有一種情況不同奋早,那就是在事件冒泡時(shí)(父子元素有相同事件,單擊子元素赠橙,父元素的事件處理函數(shù)也會(huì)被觸發(fā)執(zhí)行)耽装,
  這時(shí)候this指向的是父元素,因?yàn)樗墙壎ㄊ录脑貙?duì)象期揪,
  而target指向的是子元素掉奄,因?yàn)樗怯|發(fā)事件的那個(gè)具體元素對(duì)象。
    <div>123</div>
    <script>
        var div = document.querySelector('div');
        div.addEventListener('click', function(e) {
            // e.target 和 this指向的都是div
            console.log(e.target);
            console.log(this);

        });
    </script>

事件冒泡下的e.target和this

    <ul>
        <li>abc</li>
        <li>abc</li>
        <li>abc</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
              // 我們給ul 綁定了事件  那么this 就指向ul  
              console.log(this); // ul

              // e.target 觸發(fā)了事件的對(duì)象 我們點(diǎn)擊的是li e.target 指向的就是li
              console.log(e.target); // li
        });
    </script>

3.3.6 阻止默認(rèn)行為

html中一些標(biāo)簽有默認(rèn)行為凤薛,例如a標(biāo)簽被單擊后姓建,默認(rèn)會(huì)進(jìn)行頁(yè)面跳轉(zhuǎn)。

    <a >百度</a>
    <script>
        // 2. 阻止默認(rèn)行為 讓鏈接不跳轉(zhuǎn) 
        var a = document.querySelector('a');
        a.addEventListener('click', function(e) {
             e.preventDefault(); //  dom 標(biāo)準(zhǔn)寫法
        });
        // 3. 傳統(tǒng)的注冊(cè)方式
        a.onclick = function(e) {
            // 普通瀏覽器 e.preventDefault();  方法
            e.preventDefault();
            // 低版本瀏覽器 ie678  returnValue  屬性
            e.returnValue = false;
            // 我們可以利用return false 也能阻止默認(rèn)行為 沒有兼容性問(wèn)題
            return false;
        }
    </script>

3.3.7 阻止事件冒泡

事件冒泡本身的特性枉侧,會(huì)帶來(lái)的壞處引瀑,也會(huì)帶來(lái)的好處狂芋。

  • 1551171467194.png
    <div class="father">
        <div class="son">son兒子</div>
    </div>
    <script>
        var son = document.querySelector('.son');
        // 給son注冊(cè)單擊事件
        son.addEventListener('click', function(e) {
            alert('son');
            e.stopPropagation(); // stop 停止  Propagation 傳播
            window.event.cancelBubble = true; // 非標(biāo)準(zhǔn) cancel 取消 bubble 泡泡
        }, false);

        var father = document.querySelector('.father');
        // 給father注冊(cè)單擊事件
        father.addEventListener('click', function() {
            alert('father');
        }, false);
        // 給document注冊(cè)單擊事件
        document.addEventListener('click', function() {
            alert('document');
        })
    </script>

阻止事件冒泡的兼容性處理

  • 1551171657513.png

3.3.8 事件委托

事件冒泡本身的特性榨馁,會(huì)帶來(lái)的壞處,也會(huì)帶來(lái)的好處帜矾。

什么是事件委托

把事情委托給別人翼虫,代為處理。

事件委托也稱為事件代理屡萤,在 jQuery 里面稱為事件委派珍剑。

說(shuō)白了就是,不給子元素注冊(cè)事件死陆,給父元素注冊(cè)事件招拙,把處理代碼在父元素的事件中執(zhí)行唧瘾。

事件委托的原理

? 給父元素注冊(cè)事件,利用事件冒泡别凤,當(dāng)子元素的事件觸發(fā)饰序,會(huì)冒泡到父元素,然后去控制相應(yīng)的子元素规哪。

事件委托的作用

  • 我們只操作了一次 DOM 求豫,提高了程序的性能。

  • 動(dòng)態(tài)新創(chuàng)建的子元素诉稍,也擁有事件蝠嘉。

    <ul>
        <li>知否知否,點(diǎn)我應(yīng)有彈框在手杯巨!</li>
        <li>知否知否蚤告,點(diǎn)我應(yīng)有彈框在手!</li>
        <li>知否知否舔箭,點(diǎn)我應(yīng)有彈框在手罩缴!</li>
        <li>知否知否,點(diǎn)我應(yīng)有彈框在手层扶!</li>
        <li>知否知否箫章,點(diǎn)我應(yīng)有彈框在手!</li>
    </ul>
    <script>
        // 事件委托的核心原理:給父節(jié)點(diǎn)添加偵聽器, 利用事件冒泡影響每一個(gè)子節(jié)點(diǎn)
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
            // e.target 這個(gè)可以得到我們點(diǎn)擊的對(duì)象
            e.target.style.backgroundColor = 'pink';
        })
    </script>

3.4. 常用鼠標(biāo)事件

  • 1551172699854.png

3.4.1 案例:禁止選中文字和禁止右鍵菜單

  • 1551172755484.png
<body>
    我是一段不愿意分享的文字
    <script>
        // 1. contextmenu 我們可以禁用右鍵菜單
        document.addEventListener('contextmenu', function(e) {
                e.preventDefault();
        })
        // 2. 禁止選中文字 selectstart
        document.addEventListener('selectstart', function(e) {
            e.preventDefault();
        })
    </script>
</body>

3.4.2 鼠標(biāo)事件對(duì)象

  • 1551173103741.png

3.4.3 獲取鼠標(biāo)在頁(yè)面的坐標(biāo)

    <script>
        // 鼠標(biāo)事件對(duì)象 MouseEvent
        document.addEventListener('click', function(e) {
            // 1. client 鼠標(biāo)在可視區(qū)的x和y坐標(biāo)
            console.log(e.clientX);
            console.log(e.clientY);
            console.log('---------------------');

            // 2. page 鼠標(biāo)在頁(yè)面文檔的x和y坐標(biāo)
            console.log(e.pageX);
            console.log(e.pageY);
            console.log('---------------------');

            // 3. screen 鼠標(biāo)在電腦屏幕的x和y坐標(biāo)
            console.log(e.screenX);
            console.log(e.screenY);

        })
    </script>

3.4.4 案例:跟隨鼠標(biāo)的天使

  • 1551173172613.png
  • 1551173186812.png
    <img src="images/angel.gif" alt="">
    <script>
        var pic = document.querySelector('img');
        document.addEventListener('mousemove', function(e) {
            // 1. mousemove只要我們鼠標(biāo)移動(dòng)1px 就會(huì)觸發(fā)這個(gè)事件
            // 2.核心原理: 每次鼠標(biāo)移動(dòng),我們都會(huì)獲得最新的鼠標(biāo)坐標(biāo)思杯, 
            // 把這個(gè)x和y坐標(biāo)做為圖片的top和left 值就可以移動(dòng)圖片
            var x = e.pageX;
            var y = e.pageY;
            console.log('x坐標(biāo)是' + x, 'y坐標(biāo)是' + y);
            //3 . 千萬(wàn)不要忘記給left 和top 添加px 單位
            pic.style.left = x - 50 + 'px';
            pic.style.top = y - 40 + 'px';
        });
    </script>

第四部分

學(xué)習(xí)目標(biāo):

能夠說(shuō)出常用的3-5個(gè)鍵盤事件

能夠知道如何獲取當(dāng)前鍵盤按下的是哪個(gè)鍵

能夠知道瀏覽器的頂級(jí)對(duì)象window

能夠使用window.onload事件

能夠使用window.onresize事件

能夠說(shuō)出兩種定時(shí)器的區(qū)別

能夠使用location對(duì)象的href屬性完成頁(yè)面之間的跳轉(zhuǎn)

能夠使用location對(duì)象獲取url中的參數(shù)部分

能夠使用history提供的方法實(shí)現(xiàn)頁(yè)面刷新

4.1. 常用的鍵盤事件

4.1.1 鍵盤事件

    <script>
        // 常用的鍵盤事件
        //1. keyup 按鍵彈起的時(shí)候觸發(fā) 
        document.addEventListener('keyup', function() {
            console.log('我彈起了');
        })

        //3. keypress 按鍵按下的時(shí)候觸發(fā)  不能識(shí)別功能鍵 比如 ctrl shift 左右箭頭啊
        document.addEventListener('keypress', function() {
                console.log('我按下了press');
        })
        //2. keydown 按鍵按下的時(shí)候觸發(fā)  能識(shí)別功能鍵 比如 ctrl shift 左右箭頭啊
        document.addEventListener('keydown', function() {
                console.log('我按下了down');
        })
        // 4. 三個(gè)事件的執(zhí)行順序  keydown -- keypress -- keyup
    </script>

4.1.2 鍵盤事件對(duì)象

  • 1551318355505.png
  • 1551318404238.png

使用keyCode屬性判斷用戶按下哪個(gè)鍵

    <script>
        // 鍵盤事件對(duì)象中的keyCode屬性可以得到相應(yīng)鍵的ASCII碼值
        document.addEventListener('keyup', function(e) {
            console.log('up:' + e.keyCode);
            // 我們可以利用keycode返回的ASCII碼值來(lái)判斷用戶按下了那個(gè)鍵
            if (e.keyCode === 65) {
                alert('您按下的a鍵');
            } else {
                alert('您沒有按下a鍵')
            }
        })
        document.addEventListener('keypress', function(e) {
            // console.log(e);
            console.log('press:' + e.keyCode);
        })
    </script>

4.1.3 案例:模擬京東按鍵輸入內(nèi)容

當(dāng)我們按下 s 鍵忆矛, 光標(biāo)就定位到搜索框(文本框獲得焦點(diǎn))。

  • 1551318669520.png

注意:觸發(fā)獲得焦點(diǎn)事件狡相,可以使用 元素對(duì)象.focus()

    <input type="text">
    <script>
        // 獲取輸入框
        var search = document.querySelector('input');
        // 給document注冊(cè)keyup事件
        document.addEventListener('keyup', function(e) {
            // 判斷keyCode的值
            if (e.keyCode === 83) {
                // 觸發(fā)輸入框的獲得焦點(diǎn)事件
                search.focus();
            }
        })
    </script>

4.1.4 案例:模擬京東快遞單號(hào)查詢

要求:當(dāng)我們?cè)谖谋究蛑休斎雰?nèi)容時(shí),文本框上面自動(dòng)顯示大字號(hào)的內(nèi)容。

  • 1551318882189.png
  • 1551318909264.png
    <div class="search">
        <div class="con">123</div>
        <input type="text" placeholder="請(qǐng)輸入您的快遞單號(hào)" class="jd">
    </div>
    <script>
        // 獲取要操作的元素
        var con = document.querySelector('.con');
        var jd_input = document.querySelector('.jd');
        // 給輸入框注冊(cè)keyup事件
        jd_input.addEventListener('keyup', function() {
                // 判斷輸入框內(nèi)容是否為空
                if (this.value == '') {
                    // 為空镣屹,隱藏放大提示盒子
                    con.style.display = 'none';
                } else {
                    // 不為空,顯示放大提示盒子价涝,設(shè)置盒子的內(nèi)容
                    con.style.display = 'block';
                    con.innerText = this.value;
                }
            })
        // 給輸入框注冊(cè)失去焦點(diǎn)事件女蜈,隱藏放大提示盒子
        jd_input.addEventListener('blur', function() {
                con.style.display = 'none';
            })
        // 給輸入框注冊(cè)獲得焦點(diǎn)事件
        jd_input.addEventListener('focus', function() {
            // 判斷輸入框內(nèi)容是否為空
            if (this.value !== '') {
                // 不為空則顯示提示盒子
                con.style.display = 'block';
            }
        })
    </script>

4.2. BOM

4.2.1. 什么是BOM

? BOM(Browser Object Model)即瀏覽器對(duì)象模型,它提供了獨(dú)立于內(nèi)容而與瀏覽器窗口進(jìn)行交互的對(duì)象色瘩,其核心對(duì)象是 window伪窖。

? BOM 由一系列相關(guān)的對(duì)象構(gòu)成,并且每個(gè)對(duì)象都提供了很多方法與屬性居兆。

? BOM 缺乏標(biāo)準(zhǔn)覆山,JavaScript 語(yǔ)法的標(biāo)準(zhǔn)化組織是 ECMA,DOM 的標(biāo)準(zhǔn)化組織是 W3C泥栖,BOM 最初是Netscape 瀏覽器標(biāo)準(zhǔn)的一部分簇宽。

  • 1551319264407.png

4.2.2. BOM的構(gòu)成

BOM 比 DOM 更大勋篓,它包含 DOM。

  • 1551319344183.png

4.2.3. 頂級(jí)對(duì)象window

  • 1551319372909.png

4.2.4. window對(duì)象的常見事件

頁(yè)面(窗口)加載事件(2種)

第1種

  • 1551319525109.png

window.onload 是窗口 (頁(yè)面)加載事件魏割,當(dāng)文檔內(nèi)容完全加載完成會(huì)觸發(fā)該事件(包括圖像生巡、腳本文件、CSS 文件等), 就調(diào)用的處理函數(shù)见妒。

  • 1551319600263.png

第2種

1551319620299.png

? DOMContentLoaded 事件觸發(fā)時(shí)孤荣,僅當(dāng)DOM加載完成,不包括樣式表须揣,圖片盐股,flash等等。

? IE9以上才支持3芸ā7柚!

? 如果頁(yè)面的圖片很多的話, 從用戶訪問(wèn)到onload觸發(fā)可能需要較長(zhǎng)的時(shí)間, 交互效果就不能實(shí)現(xiàn)卵酪,必然影響用戶的體驗(yàn)幌蚊,此時(shí)用 DOMContentLoaded 事件比較合適。

    <script>
        window.addEventListener('load', function() {
            var btn = document.querySelector('button');
            btn.addEventListener('click', function() {
                alert('點(diǎn)擊我');
            })
        })
        window.addEventListener('load', function() {
            alert(22);
        })
        document.addEventListener('DOMContentLoaded', function() {
            alert(33);
        })
    </script>

調(diào)整窗口大小事件

  • 1551319803117.png

? window.onresize 是調(diào)整窗口大小加載事件, 當(dāng)觸發(fā)時(shí)就調(diào)用的處理函數(shù)溃卡。

注意:

  1. 只要窗口大小發(fā)生像素變化溢豆,就會(huì)觸發(fā)這個(gè)事件。

  2. 我們經(jīng)常利用這個(gè)事件完成響應(yīng)式布局瘸羡。 window.innerWidth 當(dāng)前屏幕的寬度

    <script>
        // 注冊(cè)頁(yè)面加載事件
        window.addEventListener('load', function() {
            var div = document.querySelector('div');
            // 注冊(cè)調(diào)整窗口大小事件
            window.addEventListener('resize', function() {
                // window.innerWidth 獲取窗口大小
                console.log('變化了');
                if (window.innerWidth <= 800) {
                    div.style.display = 'none';
                } else {
                    div.style.display = 'block';
                }
            })
        })
    </script>
    <div></div>

4.2.5. 定時(shí)器(兩種)

window 對(duì)象給我們提供了 2 個(gè)非常好用的方法-定時(shí)器漩仙。

  • setTimeout()

  • setInterval()

setTimeout() 炸彈定時(shí)器

開啟定時(shí)器
  • 1551320279307.png
  • 1551320408854.png
  • 1551320298981.png
普通函數(shù)是按照代碼順序直接調(diào)用。

簡(jiǎn)單理解: 回調(diào)犹赖,就是回頭調(diào)用的意思队他。上一件事干完,再回頭再調(diào)用這個(gè)函數(shù)峻村。
例如:定時(shí)器中的調(diào)用函數(shù)麸折,事件處理函數(shù),也是回調(diào)函數(shù)粘昨。

以前我們講的   element.onclick = function(){}   或者  element.addEventListener(“click”, fn);   里面的 函數(shù)也是回調(diào)函數(shù)垢啼。

    <script>
        // 回調(diào)函數(shù)是一個(gè)匿名函數(shù)
         setTimeout(function() {
             console.log('時(shí)間到了');

         }, 2000);
        function callback() {
            console.log('爆炸了');
        }
        // 回調(diào)函數(shù)是一個(gè)有名函數(shù)
        var timer1 = setTimeout(callback, 3000);
        var timer2 = setTimeout(callback, 5000);
    </script>
案例:5秒后關(guān)閉廣告

1551320924828.png

  • 1551320959756.png

    .png)

<body>
    <img src="images/ad.jpg" alt="" class="ad">
    <script>
        // 獲取要操作的元素
        var ad = document.querySelector('.ad');
        // 開啟定時(shí)器
        setTimeout(function() {
            ad.style.display = 'none';
        }, 5000);
    </script>
</body>
停止定時(shí)器
  • 1551321051001.png
  • 1551321064154.png
    <button>點(diǎn)擊停止定時(shí)器</button>
    <script>
        var btn = document.querySelector('button');
        // 開啟定時(shí)器
        var timer = setTimeout(function() {
            console.log('爆炸了');
        }, 5000);
        // 給按鈕注冊(cè)單擊事件
        btn.addEventListener('click', function() {
            // 停止定時(shí)器
            clearTimeout(timer);
        })
    </script>

setInterval() 鬧鐘定時(shí)器

開啟定時(shí)器
  • 1551321162158.png
    <script>
        // 1. setInterval 
        setInterval(function() {
            console.log('繼續(xù)輸出');
        }, 1000);
    </script>
案例:倒計(jì)時(shí)
  • 1551321298787.png
  • 1551321322188.png
    <div>
        <span class="hour">1</span>
        <span class="minute">2</span>
        <span class="second">3</span>
    </div>
    <script>
        // 1. 獲取元素(時(shí)分秒盒子) 
        var hour = document.querySelector('.hour'); // 小時(shí)的黑色盒子
        var minute = document.querySelector('.minute'); // 分鐘的黑色盒子
        var second = document.querySelector('.second'); // 秒數(shù)的黑色盒子
        var inputTime = +new Date('2019-5-1 18:00:00'); // 返回的是用戶輸入時(shí)間總的毫秒數(shù)

        countDown(); // 我們先調(diào)用一次這個(gè)函數(shù),防止第一次刷新頁(yè)面有空白 

        // 2. 開啟定時(shí)器
        setInterval(countDown, 1000);
        
        function countDown() {
            var nowTime = +new Date(); // 返回的是當(dāng)前時(shí)間總的毫秒數(shù)
            var times = (inputTime - nowTime) / 1000; // times是剩余時(shí)間總的秒數(shù) 
            var h = parseInt(times / 60 / 60 % 24); //時(shí)
            h = h < 10 ? '0' + h : h;
            hour.innerHTML = h; // 把剩余的小時(shí)給 小時(shí)黑色盒子
            var m = parseInt(times / 60 % 60); // 分
            m = m < 10 ? '0' + m : m;
            minute.innerHTML = m;
            var s = parseInt(times % 60); // 當(dāng)前的秒
            s = s < 10 ? '0' + s : s;
            second.innerHTML = s;
        }
    </script>
停止定時(shí)器
  • 1551321444559.png

案例:發(fā)送短信倒計(jì)時(shí)

? 點(diǎn)擊按鈕后雾棺,該按鈕60秒之內(nèi)不能再次點(diǎn)擊膊夹,防止重復(fù)發(fā)送短信衬浑。

  • 1551321540676.png
  • 1551321564247.png
    手機(jī)號(hào)碼: <input type="number"> <button>發(fā)送</button>
    <script>
        var btn = document.querySelector('button');
        // 全局變量捌浩,定義剩下的秒數(shù)
        var time = 3; 
        // 注冊(cè)單擊事件
        btn.addEventListener('click', function() {
            // 禁用按鈕
            btn.disabled = true;
            // 開啟定時(shí)器
            var timer = setInterval(function() {
                // 判斷剩余秒數(shù)
                if (time == 0) {
                    // 清除定時(shí)器和復(fù)原按鈕
                    clearInterval(timer);
                    btn.disabled = false;
                    btn.innerHTML = '發(fā)送';
                } else {
                    btn.innerHTML = '還剩下' + time + '秒';
                    time--;
                }
            }, 1000);
        });
    </script>

4.2.6. this指向問(wèn)題

? this的指向在函數(shù)定義的時(shí)候是確定不了的,只有函數(shù)執(zhí)行的時(shí)候才能確定this到底指向誰(shuí)工秩,一般情況下this的最終指向的是那個(gè)調(diào)用它的對(duì)象尸饺。

現(xiàn)階段进统,我們先了解一下幾個(gè)this指向

  1. 全局作用域或者普通函數(shù)中this指向全局對(duì)象window(注意定時(shí)器里面的this指向window)

  2. 方法調(diào)用中誰(shuí)調(diào)用this指向誰(shuí)

  3. 構(gòu)造函數(shù)中this指向構(gòu)造函數(shù)的實(shí)例

    <button>點(diǎn)擊</button>
    <script>
        // this 指向問(wèn)題 一般情況下this的最終指向的是那個(gè)調(diào)用它的對(duì)象
        // 1. 全局作用域或者普通函數(shù)中this指向全局對(duì)象window( 注意定時(shí)器里面的this指向window)
        console.log(this);
        function fn() {
            console.log(this);
        }
        window.fn();
        window.setTimeout(function() {
            console.log(this);
        }, 1000);
        // 2. 方法調(diào)用中誰(shuí)調(diào)用this指向誰(shuí)
        var o = {
            sayHi: function() {
                console.log(this); // this指向的是 o 這個(gè)對(duì)象
            }
        }
        o.sayHi();
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
                console.log(this); // 事件處理函數(shù)中的this指向的是btn這個(gè)按鈕對(duì)象
            })
        // 3. 構(gòu)造函數(shù)中this指向構(gòu)造函數(shù)的實(shí)例
        function Fun() {
            console.log(this); // this 指向的是fun 實(shí)例對(duì)象
        }
        var fun = new Fun();
    </script>

4.2.7. location對(duì)象

什么是 location 對(duì)象

  • 1551322091638.png

URL

  • 1551322373704.png
  • 1551322387201.png

location 對(duì)象的屬性

  • 1551322416716.png
  • 1551322438200.png

案例:5分鐘自動(dòng)跳轉(zhuǎn)頁(yè)面

  • 1551322496871.png
  • 1551322517605.png
    <button>點(diǎn)擊</button>
    <div></div>
    <script>
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        btn.addEventListener('click', function() {
            // console.log(location.href);
            location.;
        })
        var timer = 5;
        setInterval(function() {
            if (timer == 0) {
                location.;
            } else {
                div.innerHTML = '您將在' + timer + '秒鐘之后跳轉(zhuǎn)到首頁(yè)';
                timer--;
            }
        }, 1000);
    </script>

案例:獲取URL參數(shù)

  • 1551322622640.png
  • 1551322639241.png
    <div></div>
    <script>
        console.log(location.search); // ?uname=andy
        // 1.先去掉?  substr('起始的位置'浪听,截取幾個(gè)字符);
        var params = location.search.substr(1); // uname=andy
        console.log(params);
        // 2. 利用=把字符串分割為數(shù)組 split('=');
        var arr = params.split('=');
        console.log(arr); // ["uname", "ANDY"]
        var div = document.querySelector('div');
        // 3.把數(shù)據(jù)寫入div中
        div.innerHTML = arr[1] + '歡迎您';
    </script>

location對(duì)象的常見方法

  • 1551322750241.png
    <button>點(diǎn)擊</button>
    <script>
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            // 記錄瀏覽歷史螟碎,所以可以實(shí)現(xiàn)后退功能
            // location.assign('http://www.itcast.cn');
            // 不記錄瀏覽歷史,所以不可以實(shí)現(xiàn)后退功能
            // location.replace('http://www.itcast.cn');
            location.reload(true);
        })
    </script>

4.2.8. navigator對(duì)象

? navigator 對(duì)象包含有關(guān)瀏覽器的信息迹栓,它有很多屬性掉分,我們最常用的是 userAgent,該屬性可以返回由客戶機(jī)發(fā)送服務(wù)器的 user-agent 頭部的值克伊。

下面前端代碼可以判斷用戶那個(gè)終端打開頁(yè)面酥郭,實(shí)現(xiàn)跳轉(zhuǎn)

if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
    window.location.href = "";     //手機(jī)
 } else {
    window.location.href = "";     //電腦
 }

4.2.9 history對(duì)象

? window對(duì)象給我們提供了一個(gè) history對(duì)象,與瀏覽器歷史記錄進(jìn)行交互愿吹。該對(duì)象包含用戶(在瀏覽器窗口中)訪問(wèn)過(guò)的URL不从。

  • 1551322885216.png

history對(duì)象一般在實(shí)際開發(fā)中比較少用,但是會(huì)在一些 OA 辦公系統(tǒng)中見到犁跪。

  • 1551322959148.png

4.3. JS執(zhí)行機(jī)制

以下代碼執(zhí)行的結(jié)果是什么椿息?

 console.log(1);
 
 setTimeout(function () {
     console.log(3);
 }, 1000);
 
 console.log(2);

以下代碼執(zhí)行的結(jié)果是什么?

 console.log(1);
 
 setTimeout(function () {
     console.log(3);
 }, 0);
 
 console.log(2);

4.3.1 JS 是單線程

  • 1551415019322.png
    單線程就意味著坷衍,所有任務(wù)需要排隊(duì)寝优,前一個(gè)任務(wù)結(jié)束,才會(huì)執(zhí)行后一個(gè)任務(wù)枫耳。如果前一個(gè)任務(wù)耗時(shí)很長(zhǎng)倡勇,后一個(gè)任務(wù)就不得不一直等著。
    這樣所導(dǎo)致的問(wèn)題是: 如果 JS 執(zhí)行的時(shí)間過(guò)長(zhǎng)嘉涌,這樣就會(huì)造成頁(yè)面的渲染不連貫妻熊,導(dǎo)致頁(yè)面渲染加載阻塞的感覺。

4.3.2 同步任務(wù)和異步任務(wù)

? 單線程導(dǎo)致的問(wèn)題就是后面的任務(wù)等待前面任務(wù)完成仑最,如果前面任務(wù)很耗時(shí)(比如讀取網(wǎng)絡(luò)數(shù)據(jù))扔役,后面任務(wù)不得不一直等待!警医!

? 為了解決這個(gè)問(wèn)題亿胸,利用多核 CPU 的計(jì)算能力,HTML5 提出 Web Worker 標(biāo)準(zhǔn)预皇,允許 JavaScript 腳本創(chuàng)建多個(gè)線程侈玄,但是子線程完全受主線程控制。于是吟温,JS 中出現(xiàn)了同步任務(wù)異步任務(wù)序仙。

同步

? 前一個(gè)任務(wù)結(jié)束后再執(zhí)行后一個(gè)任務(wù),程序的執(zhí)行順序與任務(wù)的排列順序是一致的鲁豪、同步的潘悼。比如做飯的同步做法:我們要燒水煮飯律秃,等水開了(10分鐘之后),再去切菜治唤,炒菜棒动。

異步

? 你在做一件事情時(shí),因?yàn)檫@件事情會(huì)花費(fèi)很長(zhǎng)時(shí)間宾添,在做這件事的同時(shí)船惨,你還可以去處理其他事情。比如做飯的異步做法缕陕,我們?cè)跓耐瑫r(shí)掷漱,利用這10分鐘,去切菜榄檬,炒菜卜范。

  • 1551434295074.png
JS中所有任務(wù)可以分成兩種,一種是同步任務(wù)(synchronous)鹿榜,另一種是異步任務(wù)(asynchronous)海雪。

同步任務(wù)指的是:
  在主線程上排隊(duì)執(zhí)行的任務(wù),只有前一個(gè)任務(wù)執(zhí)行完畢舱殿,才能執(zhí)行后一個(gè)任務(wù)奥裸;
異步任務(wù)指的是:
  不進(jìn)入主線程、而進(jìn)入”任務(wù)隊(duì)列”的任務(wù)沪袭,當(dāng)主線程中的任務(wù)運(yùn)行完了湾宙,才會(huì)從”任務(wù)隊(duì)列”取出異步任務(wù)放入主線程執(zhí)行。
  • 1551434972778.png

4.3.3 JS執(zhí)行機(jī)制(事件循環(huán))

  • 1551435335464.png
  • 1551435398306.png
  • 1551435449634.png

4.3.4 代碼思考題

 console.log(1);
 document.onclick = function() {
   console.log('click');
 }

 setTimeout(function() {
   console.log(3)
 }, 3000)
 console.log(2);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冈绊,一起剝皮案震驚了整個(gè)濱河市侠鳄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌死宣,老刑警劉巖伟恶,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異毅该,居然都是意外死亡博秫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門眶掌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)挡育,“玉大人,你說(shuō)我怎么就攤上這事朴爬〖春” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蒿叠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蚣常,這世上最難降的妖魔是什么市咽? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮抵蚊,結(jié)果婚禮上施绎,老公的妹妹穿的比我還像新娘。我一直安慰自己贞绳,他們只是感情好谷醉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冈闭,像睡著了一般俱尼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上萎攒,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天遇八,我揣著相機(jī)與錄音,去河邊找鬼耍休。 笑死刃永,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的羊精。 我是一名探鬼主播斯够,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼喧锦!你這毒婦竟也來(lái)了读规?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤燃少,失蹤者是張志新(化名)和其女友劉穎掖桦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體供汛,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡枪汪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怔昨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雀久。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖趁舀,靈堂內(nèi)的尸體忽然破棺而出赖捌,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布越庇,位于F島的核電站罩锐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏卤唉。R本人自食惡果不足惜涩惑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桑驱。 院中可真熱鬧竭恬,春花似錦、人聲如沸熬的。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)押框。三九已至岔绸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橡伞,已是汗流浹背亭螟。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留骑歹,地道東北人预烙。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像道媚,于是被迫代替她去往敵國(guó)和親扁掸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355