深入淺析JavaScript進階之BOM技術

2022-01-27 19:01:21
本篇文章給給大家帶來了關於JavaScript中BOM的相關知識,BOM 由一系列相關的物件構成,並且每個物件都提供了很多方法與屬性,希望對大家有幫助。

目錄概述

在這裡插入圖片描述

1、BOM概述

  • BOM = Browser Object Model 瀏覽器物件模型
  • 它提供了獨立於內容而與瀏覽器視窗進行互動的物件,其核心物件是 window
  • BOM 由一系列相關的物件構成,並且每個物件都提供了很多方法與屬性
  • BOM 缺乏標準,JavaScript 語法的標準化組織是 ECMA, DOM 的標準化組織是 W3C, BOM最初是Netscape 瀏覽器標準的一部分
DOMBOM
檔案物件模型瀏覽器物件模型
DOM 就是把檔案當作一個物件來看待瀏覽器當作一個物件來看待
DOM 的頂級物件是documentBOM 的頂級物件是window
DOM 主要學習的是操作頁面元素BOM 學習的是瀏覽器視窗互動的一些物件
DOM 是 W3C 標準規範BOM 是瀏覽器廠商在各自瀏覽器上定義的,相容性較差

1.1、BOM的構成

在這裡插入圖片描述

  • BOM 比 DOM 更大。它包含 DOM。

  • window 物件是瀏覽器的頂級物件,它具有雙重角色

  • 它是 JS 存取瀏覽器視窗的一個介面

  • 它是一個全域性物件。定義在全域性作用域中的變數、函數都會變成 window 物件的屬性和方法

  • 在呼叫的時候可以省略 window,前面學習的對話方塊都屬於 window 物件方法,如 alert()、prompt()等。

  • 注意:window下的一個特殊屬性 window.name

// 定義在全域性作用域中的變數會變成window物件的屬性
var num = 10;
console.log(window.num);
// 10

// 定義在全域性作用域中的函數會變成window物件的方法
function fn() {
    console.log(11);
}
console.fn();
// 11

var name = 10;  //不要用這個name變數,window下有一個特殊屬性window.name
console.log(window.num);

2、window 物件的常見事件

2.1、視窗載入事件

window.onload是視窗(頁面)載入事件,當檔案內容完全載入完成會觸發該事件(包括影象,指令碼檔案,CSS檔案等),就呼叫的處理常式。

window.onload = function(){
    };// 或者window.addEventListener("load",function(){});

注意:

  • 有了window.onload就可以把JS程式碼寫到頁面元素的上方

  • 因為onload是等頁面內容全部載入完畢,再去執行處理常式

  • window.onload 傳統註冊事件方式,只能寫一次

  • 如果有多個,會以最後一個window.onload為準

  • 如果使用addEventListener 則沒有限制

document.addEventListener('DOMContentLoaded',function(){})

接收兩個引數:

  • DOMCountentLoaded事件觸發時,僅當DOM載入完成,不包括樣式表,圖片,flash等等

  • 如果頁面的圖片很多的話, 從使用者存取到onload觸發可能需要較長的時間

  • 互動效果就不能實現,必然影響使用者的體驗,此時用 DOMContentLoaded事件比較合適。

2.1.1、區別

  • load等頁面內容全部載入完畢,包括頁面dom元素,圖片,flash,css等
  • DOMContentLoaded 是DOM載入完畢,不包含圖片 flash css 等就可以執行,載入速度比load更快一些
<script>
    // window.onload = function() {
    //     var btn = document.querySelector('button');
    //     btn.addEventListener('click', function() {
    //         alert('點選我');
    //     })
    // }
    // window.onload = function() {
    //     alert(22);
    // }
    
    window.addEventListener('load', function() {
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            alert('點選我');
        })
    })
    window.addEventListener('load', function() {

        alert(22);
    })
    document.addEventListener('DOMContentLoaded', function() {
            alert(33);
        })
        // load 等頁面內容全部載入完畢,包含頁面dom元素 圖片 flash  css 等等
        // DOMContentLoaded 是DOM 載入完畢,不包含圖片 falsh css 等就可以執行 載入速度比 load更快一些</script>

2.2、調整視窗大小事件

window.onresize 是調整視窗大小載入事件,當觸發時就呼叫的處理常式

window.onresize = function() {}// 或者window.addEventListener('resize',function(){});
  • 只要視窗大小發生畫素變化,就會觸發這個事件
  • 我們經常利用這個事件完成響應式佈局。window.innerWidth 當前螢幕的寬度
<body>
    <script>
        window.addEventListener('load', function() {
            var p = document.querySelector('p');
            window.addEventListener('resize', function() {
                console.log(window.innerWidth);

                console.log('變化了');
                if (window.innerWidth <= 800) {
                    p.style.display = 'none';
                } else {
                    p.style.display = 'block';
                }

            })
        })
    </script>
    <p></p></body>

3、定時器

window 物件給我們提供了兩個定時器

  • setTimeout()
  • setInterval()

3.1、setTimeout()定時器

setTimeout()方法用於設定一個定時器,該定時器在定時器到期後執行呼叫函數。

window.setTimeout(呼叫函數,[延遲的毫秒數]);

注意

  • window可以省略
  • 這個呼叫函數
    • 可以直接寫函數
    • 或者寫函數名
    • 或者採取字串 ‘函數名()’ (不推薦)
  • 延遲的毫秒數省略預設是0,如果寫,必須是毫秒
  • 因為定時器可能有很多,所以我們經常給定時器賦值一個識別符號
  • setTimeout() 這個呼叫函數我們也稱為回撥函數callback
  • 普通函數是按照程式碼順序直接呼叫,而這個函數,需要等待事件,事件到了才會去呼叫這個函數,因此稱為回撥函數。
<body>
    <script>
        // 1. setTimeout 
        // 語法規範:  window.setTimeout(呼叫函數, 延時時間);
        // 1. 這個window在呼叫的時候可以省略
        // 2. 這個延時時間單位是毫秒 但是可以省略,如果省略預設的是0
        // 3. 這個呼叫函數可以直接寫函數 還可以寫 函數名 還有一個寫法 '函數名()'
        // 4. 頁面中可能有很多的定時器,我們經常給定時器加識別符號 (名字)
        // setTimeout(function() {
        //     console.log('時間到了');

        // }, 2000);
        function callback() {
            console.log('爆炸了');

        }
        var timer1 = setTimeout(callback, 3000);
        var timer2 = setTimeout(callback, 5000);
        // setTimeout('callback()', 3000); // 我們不提倡這個寫法
    </script></body>

3.2、clearTimeout()停止定時器

  • clearTimeout()方法取消了先前通過呼叫 setTimeout()建立的定時器
window.clearTimeout(timeoutID)

注意

  • window可以省略
  • 裡面的引數就是定時器的識別符號
<body>
    <button>點選停止定時器</button>
    <script>
        var btn = document.querySelector('button');
        var timer = setTimeout(function() {
            console.log('爆炸了');
        }, 5000);
        btn.addEventListener('click', function() {
            clearTimeout(timer);
        })
    </script></body>

3.3、setInterval()定時器

  • setInterval()方法重複呼叫一個函數,每隔這個時間,就去呼叫一次回撥函數
window.setInterval(回撥函數,[間隔的毫秒數]);
  • window可以省略
  • 這個回撥函數:
    • 可以直接寫函數
    • 或者寫函數名
    • 或者採取字元 ‘函數名()’
  • 第一次執行也是間隔毫秒數之後執行,之後每隔毫秒數就執行一次
<body>
    <script>
        // 1. setInterval 
        // 語法規範:  window.setInterval(呼叫函數, 延時時間);
        setInterval(function() {
            console.log('繼續輸出');

        }, 1000);
        // 2. setTimeout  延時時間到了,就去呼叫這個回撥函數,只呼叫一次 就結束了這個定時器
        // 3. setInterval  每隔這個延時時間,就去呼叫這個回撥函數,會呼叫很多次,重複呼叫這個函數
    </script></body>

3.4、clearInterval()停止定時器

  • clearInterval ( ) 方法取消了先前通過呼叫 setInterval() 建立的定時器

注意

  • window可以省略
  • 裡面的引數就是定時器的識別符號
<body>
    <button class="begin">開啟定時器</button>
    <button class="stop">停止定時器</button>
    <script>
        var begin = document.querySelector('.begin');
        var stop = document.querySelector('.stop');
        var timer = null; // 全域性變數  null是一個空物件
        begin.addEventListener('click', function() {
            timer = setInterval(function() {
                console.log('ni hao ma');

            }, 1000);
        })
        stop.addEventListener('click', function() {
            clearInterval(timer);
        })
    </script></body>

3.5、this指向

  • this的指向在函數定義的時候是確定不了的,只有函數執行的時候才能確定this到底指向誰

現階段,我們先了解一下幾個this指向

  • 全域性作用域或者普通函數中this指向全域性物件window(注意定時器裡面的this指向window)
  • 方法呼叫中誰呼叫this指向誰
  • 建構函式中this指向建構函式範例
<body>
    <button>點選</button>
    <script>
        // this 指向問題 一般情況下this的最終指向的是那個呼叫它的物件

        // 1. 全域性作用域或者普通函數中this指向全域性物件window( 注意定時器裡面的this指向window)
        console.log(this);

        function fn() {
            console.log(this);

        }
        window.fn();
        window.setTimeout(function() {
            console.log(this);

        }, 1000);
        // 2. 方法呼叫中誰呼叫this指向誰
        var o = {
            sayHi: function() {
                console.log(this); // this指向的是 o 這個物件

            }
        }
        o.sayHi();
        var btn = document.querySelector('button');
        // btn.onclick = function() {
        //     console.log(this); // this指向的是btn這個按鈕物件

        // }
        btn.addEventListener('click', function() {
                console.log(this); // this指向的是btn這個按鈕物件

            })
            // 3. 建構函式中this指向建構函式的範例
        function Fun() {
            console.log(this); // this 指向的是fun 範例物件

        }
        var fun = new Fun();
    </script></body>

4、JS執行機制

4.1、JS是單執行緒

  • JavaScript 語言的一大特點就是單執行緒,也就是說,同一個時間只能做一件事。這是因為 Javascript 這門指令碼語言誕生的使命所致——JavaScript 是為處理頁面中使用者的互動,以及操作 DOM 而誕生的。比如我們對某個 DOM 元素進行新增和刪除操作,不能同時進行。 應該先進行新增,之後再刪除。
  • 單執行緒就意味著,所有任務需要排隊,前一個任務結束,才會執行後一個任務。這樣所導致的問題是: 如果 JS 執行的時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染載入阻塞的感覺。

4.2、一個問題

以下程式碼執行的結果是什麼?

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

那麼以下程式碼執行的結果又是什麼?

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

4.3、同步和非同步

  • 為了解決這個問題,利用多核 CPU 的計算能力,HTML5 提出 Web Worker 標準,允許 JavaScript 指令碼建立多個執行緒
  • 於是,JS 中出現了同步和非同步。
  • 同步:
    • 前一個任務結束後再執行後一個任務
  • 非同步
    • 在做這件事的同時,你還可以去處理其他事情

同步任務

  • 同步任務都在主執行緒上執行,形成一個執行棧

非同步任務

  • JS中的非同步是通過回撥函數實現的
  • 非同步任務有以下三種型別
    • 普通事件,如click,resize
    • 資源載入,如load,error
    • 定時器,包括setInterval,setTimeout
  • 非同步任務相關回撥函數新增到任務佇列

在這裡插入圖片描述

  1. 先執行執行棧中的同步任務
  2. 非同步任務(回撥函數)放入任務佇列中
  3. 一旦執行棧中的所有同步任務執行完畢,系統就會按次序讀取任務佇列中的非同步任務,於是被讀取的非同步任務結束等待狀態,進入執行棧,開始執行

在這裡插入圖片描述

此時再來看我們剛才的問題:

console.log(1);setTimeout(function() {
    console.log(3);},1000);console.log(2);
  • 執行的結果和順序為 1、2、3
console.log(1);setTimeout(function() {
    console.log(3);},0);console.log(2);
  • 執行的結果和順序為 1、2、3
// 3. 第三個問題console.log(1);document.onclick = function() {
    console.log('click');}console.log(2);setTimeout(function() {
    console.log(3)}, 3000)

在這裡插入圖片描述

同步任務放在執行棧中執行,非同步任務由非同步程序處理放到任務佇列中,執行棧中的任務執行完畢會去任務佇列中檢視是否有非同步任務執行,由於主執行緒不斷的重複獲得任務、執行任務、再獲取任務、再執行,所以這種機制被稱為事件迴圈( event loop)。

5、location物件

  • window 物件給我們提供了一個 location屬性用於獲取或者設定表單的url,並且可以解析url。因為這個屬性返回的是一個物件,所以我們將這個屬性也稱為 location 物件。

5.1、url

==統一資源定位符(uniform resouce locator)==是網際網路上標準資源的地址。網際網路上的每個檔案都有一個唯一的 URL,它包含的資訊指出檔案的位置以及瀏覽器應該怎麼處理它。

url 的一般語法格式為:

protocol://host[:port]/path/[?query]#fragment

http://www.itcast.cn/index.html?name=andy&age=18#link
組成說明
protocol通訊協定 常用的http,ftp,maito等
host主機(域名) www.itheima.com
port埠號,可選
path路徑 由零或多個'/'符號隔開的字串
query引數 以鍵值對的形式,通過&符號分隔開來
fragment片段 #後面內容 常見於連結 錨點

5.2、location物件屬性

location物件屬性返回值
location.href獲取或者設定整個URL
location.host返回主機(域名)www.baidu.com
location.port返回埠號,如果未寫返回空字串
location.pathname返回路徑
location.search返回引數
location.hash返回片段 #後面內容常見於連結 錨點

重點記住:hrefsearch

需求:5s之後跳轉頁面

<body>
    <button>點選</button>
    <p></p>
    <script>
        var btn = document.querySelector('button');
        var p = document.querySelector('p');
        var timer = 5;
        setInterval(function() {
            if (timer == 0) {
                location.href = 'http://www.itcast.cn';
            } else {
                p.innerHTML = '您將在' + timer + '秒鐘之後跳轉到首頁';
                timer--;
            }

        }, 1000);
    </script></body>

5.3、location物件方法

location物件方法返回值
location.assign()跟href一樣,可以跳轉頁面(也稱為重定向頁面)
location.replace()替換當前頁面,因為不記錄歷史,所以不能後退頁面
location.reload()重新載入頁面,相當於重新整理按鈕或者 f5 ,如果引數為true 強制重新整理 ctrl+f5
<body>
    <button>點選</button>
    <script>
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            // 記錄瀏覽歷史,所以可以實現後退功能
            // location.assign('http://www.itcast.cn');
            // 不記錄瀏覽歷史,所以不可以實現後退功能
            // location.replace('http://www.itcast.cn');
            location.reload(true);
        })
    </script></body>

5.4、獲取URL引數

我們簡單寫一個登入框,點選登入跳轉到 index.html

<body>
    <form action="index.html">
        使用者名稱: <input type="text" name="uname">
        <input type="submit" value="登入">
    </form></body>

接下來我們寫 index.html

<body>
    <p></p>
    <script>
        console.log(location.search); // ?uname=andy
        // 1.先去掉?  substr('起始的位置',擷取幾個字元);
        var params = location.search.substr(1); // uname=andy
        console.log(params);
        // 2. 利用=把字串分割為陣列 split('=');
        var arr = params.split('=');
        console.log(arr); // ["uname", "ANDY"]
        var p = document.querySelector('p');
        // 3.把資料寫入p中
        p.innerHTML = arr[1] + '歡迎您';
    </script></body>

這樣我們就能獲取到路徑上的URL引數

6、navigator物件

  • navigator 物件包含有關瀏覽器的資訊,它有很多屬性
  • 我們常用的是userAgent,該屬性可以返回由客戶機傳送伺服器的user-agent頭部的值

下面前端程式碼可以判斷使用者是用哪個終端開啟頁面的,如果是用 PC 開啟的,我們就跳轉到 PC 端的頁面,如果是用手機開啟的,就跳轉到手機端頁面

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 = "";     //手機
 } else {
    window.location.href = "";     //電腦
 }

7、history物件

  • window 物件給我們提供了一個 history 物件,與瀏覽器歷史記錄進行互動
  • 該物件包含使用者(在瀏覽器視窗中)存取過的 URL。
history物件方法作用
back()可以後退功能
forward()前進功能
go(引數)前進後退功能,引數如果是 1 前進1個頁面 如果是 -1 後退1個頁面
<body>
    <a href="list.html">點選我去往列表頁</a>
    <button>前進</button>
    <script>
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            // history.forward();
            history.go(1);
        })
    </script></body>

相關推薦:

以上就是深入淺析JavaScript進階之BOM技術的詳細內容,更多請關注TW511.COM其它相關文章!