1. 程式人生 > 實用技巧 >彈框不影響定時器的繼續執行

彈框不影響定時器的繼續執行

因為 js 為單執行緒語言,所以在一般情況下,當彈框出現時,定時器是必定會停止的,如以下例項

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>土狗一號</title>
</head>
<body>
    <div></div>
    <button>彈框</button>
    <script>
        var div = document.body.children[0]
        var test = 100
        // 簡單的定時器,讓倒數繼續
        setInterval(function (){
            test -= 1
            div.innerHTML = test
        }, 1000)
        var button = document.body.children[1]
        button.onclick = function (){
            alert("test")
        }
    </script>
</body>
</html>

為了做到彈出彈框也讓遞減繼續,必須要在js中使用多執行緒
需使用H5中提供的Web Worker物件

什麼是Web Worker?

當在 HTML 頁面中執行指令碼時,頁面的狀態是不可響應的,直到指令碼已完成。
web worker 是執行在後臺的 JavaScript,獨立於其他指令碼,不會影響頁面的效能。您可以繼續做任何願意做的事情:點選、選取內容等等,而此時 web worker 在後臺執行。

也就是說,我們可以使用 web worker 建立一個例項,通過這個例項呼叫外部 JS。
這個外部 JS 此時正執行在後臺,即使主頁面出現了彈框,也不會影響後臺的程序。

接下來我們對上面的例子進行改寫:

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>土狗一號</title>
</head>
<body>
    <div></div>
    <button>ss</button>
    <script>
        // 建立例項,括號內跟路徑
        var worker1 = new Worker('./test.js')
        var div = document.body.children[0]
        // 向 web worker 新增一個 "onmessage" 事件監聽器
        // 箭頭函式獲得的 e.data 為 js 檔案中 self.postMessage()返回的值
        worker1.onmessage = e => {
            // 把 js 檔案中拿到的值賦給 div
            div.innerHTML = e.data
        }
        /*
        *   上面的操作就是把 js 中拿到的值賦給 div
        */
        var button = document.body.children[1]
        button.onclick = function (){
            alert("test")
        }

         // 在 HTML 關閉指令碼
        // worker1.terminate()
    </script>
</body>
</html>

JS:

var test = 100
    // 設定定時器,每過一秒執行一次
    self.setInterval(function(){
        test -= 1
        // 將拿到的值傳給 HTML 頁面
        self.postMessage(test)
        // 如果 test 走到0則 Worker 關閉自身,也就是停止執行該檔案
        if(test == 0){
            // 在 Worker 內部關閉自身,如想在 HTML 中關閉則需用其他方法
            self.close()
        }
    }, 1000)

:最好部署在伺服器上進行此操作(IE 某些版本也可以)否則可能會出現以下錯誤

由於谷歌的安全機制,此操作會被當做跨域......不允許在本地直接執行

但此方法有個很大的缺點!!!

因為 JS 本為單執行緒語言,所以上述程式碼的執行效率並不高,甚至可以說是很低...
在執行上述案例的時候就會發現,當點開彈窗後,數字遞減的顯示是有卡頓的。
但如果把彈窗關閉,卡頓則會消失(遞減的次數不會受卡頓影響)
因此,在選用本方法時,一定要考慮應用場景。