JavaScript從入門到精通系列(10)

Web APIs(四)

1.1. 常用的鍵盤事件

1.1.1 鍵盤事件

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

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

1.1.2 鍵盤事件對象

使用keyCode屬性判斷用戶按下哪個鍵

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

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

當我們按下 s 鍵, 光標就定位到搜索框(文本框獲得焦點)番枚。

注意:觸發(fā)獲得焦點事件蝗锥,可以使用 元素對象.focus()

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

1.1.4 案例:模擬京東快遞單號查詢

要求:當我們在文本框中輸入內(nèi)容時喘帚,文本框上面自動顯示大字號的內(nèi)容诡壁。

    <div class="search">
        <div class="con">123</div>
        <input type="text" placeholder="請輸入您的快遞單號" class="jd">
    </div>
    <script>
        // 獲取要操作的元素
        var con = document.querySelector('.con');
        var jd_input = document.querySelector('.jd');
        // 給輸入框注冊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;
                }
            })
        // 給輸入框注冊失去焦點事件,隱藏放大提示盒子
        jd_input.addEventListener('blur', function() {
                con.style.display = 'none';
            })
        // 給輸入框注冊獲得焦點事件
        jd_input.addEventListener('focus', function() {
            // 判斷輸入框內(nèi)容是否為空
            if (this.value !== '') {
                // 不為空則顯示提示盒子
                con.style.display = 'block';
            }
        })
    </script>

1.2. BOM

1.2.1. 什么是BOM

? BOM(Browser Object Model)即瀏覽器對象模型疙挺,它提供了獨立于內(nèi)容而與瀏覽器窗口進行交互的對象扛邑,其核心對象是 window。

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

? BOM 缺乏標準恶座,JavaScript 語法的標準化組織是 ECMA,DOM 的標準化組織是 W3C舱殿,BOM 最初是Netscape 瀏覽器標準的一部分奥裸。

1.2.2. BOM的構(gòu)成

BOM 比 DOM 更大险掀,它包含 DOM沪袭。

1.2.3. 頂級對象window

1.2.4. window對象的常見事件

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

第1種

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

第2種

? DOMContentLoaded 事件觸發(fā)時埠啃,僅當DOM加載完成死宣,不包括樣式表,圖片碴开,flash等等毅该。

? IE9以上才支持!A逝!眶掌!

? 如果頁面的圖片很多的話, 從用戶訪問到onload觸發(fā)可能需要較長的時間, 交互效果就不能實現(xiàn),必然影響用戶的體驗巴碗,此時用 DOMContentLoaded 事件比較合適朴爬。

    <script>
        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);
        })
    </script>

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

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

注意:

  1. 只要窗口大小發(fā)生像素變化橡淆,就會觸發(fā)這個事件召噩。

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

    <script>
        // 注冊頁面加載事件
        window.addEventListener('load', function() {
            var div = document.querySelector('div');
            // 注冊調(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>

1.2.5. 定時器(兩種)

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

  • setTimeout()

  • setInterval()

setTimeout() 炸彈定時器

開啟定時器

普通函數(shù)是按照代碼順序直接調(diào)用具滴。

簡單理解: 回調(diào),就是回頭調(diào)用的意思师倔。上一件事干完抵蚊,再回頭再調(diào)用這個函數(shù)。
例如:定時器中的調(diào)用函數(shù)溯革,事件處理函數(shù)贞绳,也是回調(diào)函數(shù)。

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

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

         }, 2000);
        function callback() {
            console.log('爆炸了');
        }
        // 回調(diào)函數(shù)是一個有名函數(shù)
        var timer1 = setTimeout(callback, 3000);
        var timer2 = setTimeout(callback, 5000);
    </script>
案例:5秒后關(guān)閉廣告
<body>
    <img src="images/ad.jpg" alt="" class="ad">
    <script>
        // 獲取要操作的元素
        var ad = document.querySelector('.ad');
        // 開啟定時器
        setTimeout(function() {
            ad.style.display = 'none';
        }, 5000);
    </script>
</body>
停止定時器
    <button>點擊停止定時器</button>
    <script>
        var btn = document.querySelector('button');
        // 開啟定時器
        var timer = setTimeout(function() {
            console.log('爆炸了');
        }, 5000);
        // 給按鈕注冊單擊事件
        btn.addEventListener('click', function() {
            // 停止定時器
            clearTimeout(timer);
        })
    </script>

setInterval() 鬧鐘定時器

開啟定時器
    <script>
        // 1. setInterval 
        setInterval(function() {
            console.log('繼續(xù)輸出');
        }, 1000);
    </script>
案例:倒計時
    <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>
停止定時器

案例:發(fā)送短信倒計時

? 點擊按鈕后,該按鈕60秒之內(nèi)不能再次點擊抖单,防止重復(fù)發(fā)送短信萎攒。

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

1.2.6. this指向問題

? this的指向在函數(shù)定義的時候是確定不了的,只有函數(shù)執(zhí)行的時候才能確定this到底指向誰耍休,一般情況下this的最終指向的是那個調(diào)用它的對象刃永。

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

  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.addEventListener('click', function() {
                console.log(this); // 事件處理函數(shù)中的this指向的是btn這個按鈕對象
            })
        // 3. 構(gòu)造函數(shù)中this指向構(gòu)造函數(shù)的實例
        function Fun() {
            console.log(this); // this 指向的是fun 實例對象
        }
        var fun = new Fun();
    </script>

1.2.7. location對象

什么是 location 對象

location 對象的屬性

案例:5分鐘自動跳轉(zhuǎn)頁面

    <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>

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

    <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>

location對象的常見方法

    <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.2.8. 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.2.9 history對象

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

history對象一般在實際開發(fā)中比較少用阳液,但是會在一些 OA 辦公系統(tǒng)中見到怕敬。

1.3. JS執(zhí)行機制

以下代碼執(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);

1.3.1 JS 是單線程

    單線程就意味著赖捌,所有任務(wù)需要排隊,前一個任務(wù)結(jié)束矮烹,才會執(zhí)行后一個任務(wù)越庇。如果前一個任務(wù)耗時很長,后一個任務(wù)就不得不一直等著奉狈。
    這樣所導(dǎo)致的問題是: 如果 JS 執(zhí)行的時間過長卤唉,這樣就會造成頁面的渲染不連貫,導(dǎo)致頁面渲染加載阻塞的感覺仁期。

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

? 單線程導(dǎo)致的問題就是后面的任務(wù)等待前面任務(wù)完成桑驱,如果前面任務(wù)很耗時(比如讀取網(wǎng)絡(luò)數(shù)據(jù)),后面任務(wù)不得不一直等待u说啊熬的!

? 為了解決這個問題,利用多核 CPU 的計算能力赊级,HTML5 提出 Web Worker 標準押框,允許 JavaScript 腳本創(chuàng)建多個線程,但是子線程完全受主線程控制理逊。于是橡伞,JS 中出現(xiàn)了同步任務(wù)異步任務(wù)盒揉。

同步

? 前一個任務(wù)結(jié)束后再執(zhí)行后一個任務(wù),程序的執(zhí)行順序與任務(wù)的排列順序是一致的兑徘、同步的刚盈。比如做飯的同步做法:我們要燒水煮飯,等水開了(10分鐘之后)挂脑,再去切菜藕漱,炒菜。

異步

? 你在做一件事情時最域,因為這件事情會花費很長時間谴分,在做這件事的同時锈麸,你還可以去處理其他事情镀脂。比如做飯的異步做法,我們在燒水的同時忘伞,利用這10分鐘薄翅,去切菜,炒菜氓奈。

image.png
JS中所有任務(wù)可以分成兩種翘魄,一種是同步任務(wù)(synchronous),另一種是異步任務(wù)(asynchronous)舀奶。

同步任務(wù)指的是:
  在主線程上排隊執(zhí)行的任務(wù)暑竟,只有前一個任務(wù)執(zhí)行完畢,才能執(zhí)行后一個任務(wù)育勺;
異步任務(wù)指的是:
  不進入主線程但荤、而進入”任務(wù)隊列”的任務(wù),當主線程中的任務(wù)運行完了涧至,才會從”任務(wù)隊列”取出異步任務(wù)放入主線程執(zhí)行腹躁。

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


1.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)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市南蓬,隨后出現(xiàn)的幾起案子纺非,更是在濱河造成了極大的恐慌,老刑警劉巖赘方,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烧颖,死亡現(xiàn)場離奇詭異,居然都是意外死亡窄陡,警方通過查閱死者的電腦和手機炕淮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泳梆,“玉大人鳖悠,你說我怎么就攤上這事榜掌。” “怎么了乘综?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵憎账,是天一觀的道長。 經(jīng)常有香客問我卡辰,道長胞皱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任九妈,我火速辦了婚禮反砌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘萌朱。我一直安慰自己宴树,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布晶疼。 她就那樣靜靜地躺著酒贬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪翠霍。 梳的紋絲不亂的頭發(fā)上锭吨,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音寒匙,去河邊找鬼零如。 笑死,一個胖子當著我的面吹牛锄弱,可吹牛的內(nèi)容都是我干的考蕾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼棵癣,長吁一口氣:“原來是場噩夢啊……” “哼辕翰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起狈谊,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤喜命,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后河劝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體壁榕,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年赎瞎,在試婚紗的時候發(fā)現(xiàn)自己被綠了牌里。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖牡辽,靈堂內(nèi)的尸體忽然破棺而出喳篇,到底是詐尸還是另有隱情,我是刑警寧澤态辛,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布麸澜,位于F島的核電站,受9級特大地震影響奏黑,放射性物質(zhì)發(fā)生泄漏炊邦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一熟史、第九天 我趴在偏房一處隱蔽的房頂上張望馁害。 院中可真熱鬧,春花似錦蹂匹、人聲如沸碘菜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炉媒。三九已至踪区,卻和暖如春昆烁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缎岗。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工静尼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人传泊。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓鼠渺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親眷细。 傳聞我的和親對象是個殘疾皇子拦盹,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • ??JavaScript 是一種極其靈活的語言普舆,具有多種使用風格。 ??一般來說校读,編寫 JavaScript 要么...
    霜天曉閱讀 744評論 0 0
  • ??JavaScript 與 HTML 之間的交互是通過事件實現(xiàn)的澳迫。 ??事件温治,就是文檔或瀏覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,490評論 1 11
  • JavaScript的組成 JavaScript 由以下三部分組成:ECMAScript(核心):JavaScri...
    紋小艾閱讀 3,201評論 0 3
  • 目錄 1、談?wù)勀銓jax的理解雁芙?(概念轧膘、特點钞螟、作用) 2、說說你對延遲對象deferred的理解? 3谎碍、什么是跨...
    w_zhuan閱讀 990評論 1 28
  • 概要 64學(xué)時 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,182評論 0 3