BOM瀏覽器對象模型:什么是BOM鱼蝉、BOM的構(gòu)成洒嗤、window的常見事件:窗口加載事件、調(diào)整窗口大小事件魁亦、定時器渔隶、5秒后自動關(guān)閉的廣告案例、倒計時案例洁奈、發(fā)送信息的案例间唉、this指向問題绞灼、JS執(zhí)行...

1.1什么是BOM

BOM即瀏覽器對象模型,它提供了獨立于內(nèi)容而與瀏覽器窗口進行交互的對象呈野,其核心對象是window镀赌。
BOM由一系列相關(guān)的對象構(gòu)成,并且每個對象都提供了很多方法與屬性际跪。
BOM缺乏標準,JS語法的標準化組織是ECMA喉钢,DOM的標準化組織是W3C姆打,BOM最初是Netscape瀏覽器標準的一部分。


Snipaste_2020-07-10_14-33-01.png

1.2BOM的構(gòu)成

BOM比DOM更大肠虽,它包含DOM


Snipaste_2020-07-10_14-36-10.png

window對象是瀏覽器的頂級對象幔戏,它具有雙重角色。
1税课、它是JS訪問瀏覽器窗口的一個接口
2闲延、它是一個全局對象。定義在全局作用域中的變量韩玩、函數(shù)都會變成window對象的屬性和方法垒玲。
在調(diào)用的時候可以省略window,前面學習的對話框都屬于window對象方法找颓,如alert()合愈、prompt()等

1.2window的常見事件

1.2.1窗口加載事件

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

window.onload是窗口(頁面)加載事件,當文檔內(nèi)容完全加載完成會觸發(fā)該事件(包括圖像击狮、腳本文件佛析、CSS文件等),就調(diào)用的處理函數(shù)彪蓬。
注意:

  • 有了window.onload就可以把JS代碼寫道頁面元素的任何地方寸莫,因為onload是等頁面內(nèi)容全部加載完畢,再去執(zhí)行處理函數(shù)档冬。
  • window.onload傳統(tǒng)注冊事件方式只能寫一次膘茎,如果有多個,會以最后一個window.onload為準捣郊。
  • 如果使用addEventListener則沒有限制

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

DOMContentLoaded事件觸發(fā)時辽狈,僅當DOM加載完成,不包括樣式表呛牲,圖片刮萌,flash等等。i9以上支持娘扩。
如果頁面圖片很多的話着茸,從用戶訪問到onload觸發(fā)可能需要較長的時間壮锻,交互效果就不能實現(xiàn),必然影響用戶體驗涮阔,此時用DOMContentLoaded事件比較合適猜绣。

   <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 等頁面內(nèi)容全部加載完畢,包含頁面dom元素 圖片 flash  css 等等
            // DOMContentLoaded 是DOM 加載完畢敬特,不包含圖片 falsh css 等就可以執(zhí)行 加載速度比 load更快一些
    </script>
</head>

<body>

    <button>點擊</button>

</body>
1.2.2調(diào)整窗口大小事件

window.onresize = function(){}
window.addEventListener("resize",function(){});

window.onresize是調(diào)節(jié)窗口大小加載事件掰邢,當觸發(fā)時就調(diào)用的處理函數(shù)。
注意:1伟阔、只要窗口大小發(fā)生像素變化辣之,就會觸發(fā)這個事件。
2皱炉、我們經(jīng)常利用這個事件完成響應(yīng)式布局怀估。window.innerWidth當前屏幕的寬度

  div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }
 <script>
        window.addEventListener('load', function() {
            var div = document.querySelector('div');
            window.addEventListener('resize', function() {
                console.log(window.innerWidth);

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

            })
        })
    </script>
    <div></div>
1.2.3定時器

window對象給我們提供了兩個非常好用的方法-定時器

  • setTimeout()
  • setInterval()
    window.setTimeout(調(diào)用函數(shù),[延遲的毫秒數(shù)]);
    setTimeout()方法用于設(shè)置一個定時器,該定時器在定時器到期后執(zhí)行調(diào)用函數(shù)合搅。
    setRimeout()這個調(diào)用函數(shù)我們也稱為回調(diào)函數(shù)callback多搀。普通函數(shù)是按照代碼順序直接調(diào)用。而這個函數(shù)灾部,需要等待事件康铭,時間到了才去調(diào)用這個函數(shù),因此稱為回調(diào)函數(shù)梳猪。
    注意:1麻削、window可以省略
    2、這個調(diào)用函數(shù)可以直接寫函數(shù)春弥,或者寫函數(shù)名呛哟。
    3、延遲的毫秒數(shù)省略默認是0匿沛,如果寫扫责,必須是毫秒。
    4逃呼、因為定時器可能很多鳖孤,所以我們經(jīng)常給定時器賦值一個標識符。
 // 1. setTimeout 
        // 語法規(guī)范:  window.setTimeout(調(diào)用函數(shù), 延時時間);
        // 1. 這個window在調(diào)用的時候可以省略
        // 2. 這個延時時間單位是毫秒 但是可以省略抡笼,如果省略默認的是0
        // 3. 這個調(diào)用函數(shù)可以直接寫函數(shù) 還可以寫 函數(shù)名 還有一個寫法 '函數(shù)名()'
        // 4. 頁面中可能有很多的定時器苏揣,我們經(jīng)常給定時器加標識符 (名字)
        // setTimeout(function() {
        //     console.log('時間到了');

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

        }
        var timer1 = setTimeout(callback, 3000);
        var timer2 = setTimeout(callback, 5000);
        // setTimeout('callback()', 3000); // 我們不提倡這個寫法
1.2.4五秒之后自動關(guān)閉的廣告案例
 <img src="images/ad.jpg" alt="" class="ad">
    <script>
        var ad = document.querySelector('.ad');
        setTimeout(function() {
            ad.style.display = 'none';
        }, 5000);
    </script>
1.2.5停止setTimeout()定時器

window.clearTimeout(timeoutID)

  <button>點擊停止定時器</button>
    <script>
        var btn = document.querySelector('button');
        var timer = setTimeout(function() {
            console.log('爆炸了');

        }, 5000);
        btn.addEventListener('click', function() {
            clearTimeout(timer);
        })
    </script>
1.2.6setInterval()定時器

window.setInterval(調(diào)用函數(shù),[延遲的毫秒數(shù)]);
setInterval()方法重復(fù)調(diào)用一個函數(shù),每隔這個時間推姻,就去調(diào)用一次回調(diào)函數(shù)平匈。

  setInterval(function() {
            console.log('繼續(xù)輸出');

        }, 1000);
1.2.7倒計時案例
Snipaste_2020-07-14_16-04-01.png

Snipaste_2020-07-14_16-09-00.png
  div {
            margin: 200px;
        }
        
        span {
            display: inline-block;
            width: 40px;
            height: 40px;
            background-color: #333;
            font-size: 20px;
            color: #fff;
            text-align: center;
            line-height: 40px;
        }
<div>
        <span class="hour">1</span>
        <span class="minute">2</span>
        <span class="second">3</span>
    </div>
    <script>
        // 1. 獲取元素 
        var hour = document.querySelector('.hour'); // 小時的黑色盒子
        var minute = document.querySelector('.minute'); // 分鐘的黑色盒子
        var second = document.querySelector('.second'); // 秒數(shù)的黑色盒子
        var inputTime = +new Date('2019-5-1 18:00:00'); // 返回的是用戶輸入時間總的毫秒數(shù)
        countDown(); // 我們先調(diào)用一次這個函數(shù),防止第一次刷新頁面有空白 
        // 2. 開啟定時器
        setInterval(countDown, 1000);

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

window.clearInterval(intervalID)

Snipaste_2020-07-14_16-14-01.png

  <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>
1.2.9發(fā)送短信的案例
Snipaste_2020-07-14_16-14-55.png

Snipaste_2020-07-14_16-16-26.png
 手機號碼: <input type="number"> <button>發(fā)送</button>
    <script>
        // 按鈕點擊之后,會禁用 disabled 為true 
        // 同時按鈕里面的內(nèi)容會變化增炭, 注意 button 里面的內(nèi)容通過 innerHTML修改
        // 里面秒數(shù)是有變化的忍燥,因此需要用到定時器
        // 定義一個變量,在定時器里面隙姿,不斷遞減
        // 如果變量為0 說明到了時間梅垄,我們需要停止定時器,并且復(fù)原按鈕初始狀態(tài)
        var btn = document.querySelector('button');
        var time = 3; // 定義剩下的秒數(shù)
        btn.addEventListener('click', function() {
            btn.disabled = true;
            var timer = setInterval(function() {
                if (time == 0) {
                    // 清除定時器和復(fù)原按鈕
                    clearInterval(timer);
                    btn.disabled = false;
                    btn.innerHTML = '發(fā)送';
                } else {
                    btn.innerHTML = '還剩下' + time + '秒';
                    time--;
                }
            }, 1000);

        })
    </script>

1.3this指向問題

this 指向問題 一般情況下this的最終指向的是那個調(diào)用它的對象

  1. 全局作用域或者普通函數(shù)中this指向全局對象window( 注意定時器里面的this指向window)
  2. 方法調(diào)用中誰調(diào)用this指向誰
  3. 構(gòu)造函數(shù)中this指向構(gòu)造函數(shù)的實例
 <button>點擊</button>
    <script>
        // this 指向問題 一般情況下this的最終指向的是那個調(diào)用它的對象

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

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

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

        }, 1000);
        // 2. 方法調(diào)用中誰調(diào)用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. 構(gòu)造函數(shù)中this指向構(gòu)造函數(shù)的實例
        function Fun() {
            console.log(this); // this 指向的是fun 實例對象

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

1.4JS執(zhí)行機制

JS是單線程

JavaScript語言的一大特點就是單線程输玷,也就是說队丝,同一個時間只能做一件事。這是因為Javascript這門腳本語言誕生的使命所致---javascript是為處理頁面中用戶的交互欲鹏,以及操作DOM而誕生的炭玫。比如我們對某個DOM元素進行添加和刪除操作,不能同時進行貌虾。就應(yīng)該先進行添加,之后再刪除裙犹。

單線程就意味著所有任務(wù)需要排隊尽狠,前一個任務(wù)結(jié)束,才會執(zhí)行下一個任務(wù)叶圃。這樣所導(dǎo)致的問題是:如果JS執(zhí)行時間過長袄膏,這樣就會造成頁面的渲染不連貫,導(dǎo)致頁面渲染加載阻塞的感覺掺冠。

同步和異步

為了解決這個問題沉馆,利用多核cpu的計算能力,HTML5提出Web Worker標準德崭,允許JavaScript腳本創(chuàng)建多個線程斥黑。于是,JS中出現(xiàn)了同步和異步眉厨。

同步

前一個任務(wù)結(jié)束后再執(zhí)行后一個任務(wù)锌奴,程序的執(zhí)行順序與任務(wù)排列順序一致、同步的憾股。比如做飯的同步做法:我們要燒水煮飯鹿蜀,等水開了(10分鐘之后),再去切菜炒菜。

異步

你在做一件事情時服球,因為這件事情會花費很長時間茴恰,在做這件事的同時,你還可以去處理其他事情斩熊。比如做飯的異步做法往枣,我們在燒水的同時娱挨,利用這10分鐘去切菜炒菜粗梭。

同步任務(wù)

同步任務(wù)都在主線程上執(zhí)行,形成一個執(zhí)行棧。

異步任務(wù)

JS的異步是通過回調(diào)函數(shù)實現(xiàn)的扛点,
一般而言,異步任務(wù)有以下三種類型:
1狮辽、普通事件烁巫,如click、resize等
2蘑秽、資源加載饺著,如load、error等
3肠牲、定時器幼衰,包括setInterval、setTimeout等
異步任務(wù)相關(guān)回調(diào)函數(shù)添加到任務(wù)隊列中(任務(wù)隊列也稱為消息隊列缀雳。


Snipaste_2020-07-14_16-48-10.png
JS執(zhí)行機制

1渡嚣、先執(zhí)行執(zhí)行棧中的同步任務(wù)。
2肥印、異步任務(wù)(回調(diào)函數(shù))放入任務(wù)隊列中识椰。
3、一旦執(zhí)行棧中的所有同步任務(wù)執(zhí)行完畢深碱,系統(tǒng)會按次序讀取任務(wù)隊列中的異步任務(wù)腹鹉,于是被讀取的異步任務(wù)結(jié)束等待狀態(tài),進入執(zhí)行棧敷硅,開始執(zhí)行功咒。


Snipaste_2020-07-14_16-51-22.png
Snipaste_2020-07-14_17-04-27.png

輸出結(jié)果:不點擊 123
點擊 123 click*點擊次數(shù)


Snipaste_2020-07-14_17-06-14.png

由于主線程不斷的重復(fù)獲得任務(wù)、執(zhí)行任務(wù)绞蹦、再獲得任務(wù)力奋、再執(zhí)行,所以這種機制被稱為事件循環(huán)(event loop)

1.5location對象

window對象給我們提供了一個location屬性用于獲取或設(shè)置窗體的URL幽七,并且可以用于解析URL刊侯。因為這個屬性返回的是一個對象,所以我們將這個屬性也稱為location屬性

1.5.1URL

統(tǒng)一資源定位符(Uniform Resource Locator锉走,URL)是互聯(lián)網(wǎng)上標準資源的地址滨彻。互聯(lián)網(wǎng)上的每個文件都有唯一URL挪蹭,它包含的信息指出文件的位置以及瀏覽器應(yīng)該怎么處理它亭饵。
URL的一般語法格式為:


Snipaste_2020-07-14_17-41-13.png
1.5.2location對象的屬性
Snipaste_2020-07-14_17-45-19.png

重點記住href和search

1.5.3 5秒之后自動跳轉(zhuǎn)頁面案例
Snipaste_2020-07-14_17-51-18.png
   <button>點擊</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)到首頁';
                timer--;
            }

        }, 1000);
    </script>
1.5.4 獲取URL參數(shù)案例
Snipaste_2020-07-14_17-56-53.png

index.html

<div></div>
    <script>
        console.log(location.search); // ?uname=andy
        // 1.先去掉?  substr('起始的位置'梁厉,截取幾個字符);
        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>

login.html

<form action="index.html">
        用戶名: <input type="text" name="uname">
        <input type="submit" value="登錄">
    </form>
1.5.5location對象的方法
Snipaste_2020-07-14_18-04-22.png

location.assign 記錄瀏覽歷史辜羊,所以可以實現(xiàn)后退功能
location.replace 不記錄瀏覽歷史踏兜,所以不可以實現(xiàn)后退功能。

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

1.6 navigator對象

navigator對象包含有關(guān)瀏覽器的信息,它有很多屬性昔驱,我們最常用的是userAgent疹尾,該屬性可以返回由客戶機發(fā)送服務(wù)器的user-agent頭部的值。
下面前端代碼可以判斷用戶哪個終端打開頁面骤肛,實現(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 = ""; //手機
        }else{
          window.location.href="";  //電腦}

1.7 history對象

window對象給我們提供了一個history對象,與瀏覽器歷史記錄進行交互腋颠。該對象包含用戶(在瀏覽器窗口中)訪問過的URL繁成。


Snipaste_2020-07-14_18-17-27.png

index.html

  <a href="list.html">點擊我去往列表頁</a>
    <button>前進</button>
    <script>
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            // history.forward();
            history.go(1);
        })
    </script>

list.html

<a href="index.html">點擊我去往首頁</a>
    <button>后退</button>
    <script>
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            // history.back();
            history.go(-1);
        })
    </script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市淑玫,隨后出現(xiàn)的幾起案子巾腕,更是在濱河造成了極大的恐慌,老刑警劉巖絮蒿,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祠墅,死亡現(xiàn)場離奇詭異,居然都是意外死亡歌径,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門亲茅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來回铛,“玉大人,你說我怎么就攤上這事克锣∫鹚啵” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵袭祟,是天一觀的道長验残。 經(jīng)常有香客問我,道長巾乳,這世上最難降的妖魔是什么您没? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮胆绊,結(jié)果婚禮上氨鹏,老公的妹妹穿的比我還像新娘。我一直安慰自己压状,他們只是感情好仆抵,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般镣丑。 火紅的嫁衣襯著肌膚如雪舔糖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天莺匠,我揣著相機與錄音金吗,去河邊找鬼。 笑死慨蛙,一個胖子當著我的面吹牛辽聊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播期贫,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼跟匆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了通砍?” 一聲冷哼從身側(cè)響起玛臂,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎封孙,沒想到半個月后迹冤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡虎忌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年泡徙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膜蠢。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡堪藐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挑围,到底是詐尸還是另有隱情礁竞,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布杉辙,位于F島的核電站模捂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蜘矢。R本人自食惡果不足惜狂男,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望品腹。 院中可真熱鬧并淋,春花似錦、人聲如沸珍昨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至兔毙,卻和暖如春唾琼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背澎剥。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工锡溯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哑姚。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓祭饭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親叙量。 傳聞我的和親對象是個殘疾皇子倡蝙,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345