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