最近在開發項目時,遇到了一個屏保需求,項目的頁面是父子關係,在父頁面中嵌套了一個iframe子頁面,要求若是iframe所在的子頁面在10min內沒有任何觸摸操做,則顯示屏保,點擊屏保從新回到主頁面。html
這裏有幾個注意點:chrome
一、怎麼實現定時屏保的效果瀏覽器
這裏須要在頁面加載的時候,就設置一個延遲器(conf.Consts.SCREEN_TIMEOUT是在公共js中定義的常量,值爲10*60*1000,表明10min),當達到延遲器中設置的時間(單位:ms)後,觸發函數(這裏我觸發的函數是ScreenSaver)。app
var action = setTimeout(ScreenSaver, conf.Consts.SCREEN_TIMEOUT);
二、如何監聽頁面上的觸摸操做,從新刷新屏保時間異步
這裏須要爲iframe頁面添加觸摸事件的監聽。通過測試,在父頁面中直接添加對整個document的監聽,不會觸發在iframe頁面中的監聽事件,所以咱們須要這麼作:ide
首先爲iframe指定一個id,這裏個人id是myframe。函數
<iframe id="myframe" src="/page/main-main.html" class="myframe" scrolling="no"></iframe測試
而後經過一個函數判斷瀏覽器類型,確認是不是IE瀏覽器。url
function IEVersion() { var userAgent = navigator.userAgent; //取得瀏覽器的userAgent字符串 var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判斷是否IE<11瀏覽器 var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判斷是否IE的Edge瀏覽器 var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; if (isIE) { var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); reIE.test(userAgent); var fIEVersion = parseFloat(RegExp["$1"]); if (fIEVersion == 7) { return 7; } else if (fIEVersion == 8) { return 8; } else if (fIEVersion == 9) { return 9; } else if (fIEVersion == 10) { return 10; } else { return 6;//IE版本<=7 } } else if (isEdge) { return 'edge';//edge } else if (isIE11) { return 11; //IE11 } else { return -1;//不是ie瀏覽器 } }
若是是IE瀏覽器,則須要監聽:MSPointerDown(觸摸按下)、MSPointerUp(觸摸擡起)等事件。spa
若是是chrome瀏覽器,則須要監聽:touchstart(觸摸按下)、touchend(觸摸擡起)等事件。
若是是其餘瀏覽器,方式相似,這裏再也不列舉。注意iframe是異步加載的,所以須要在iframe.onload函數中,進行事件綁定操做,不然會拋出空指針異常。
var iframe = document.getElementById("myframe") iframe.onload = function () { let iframeWindow = iframe.contentWindow; let ver = IEVersion(); if(ver == -1){ iframeWindow.addEventListener("touchstart", touch, false); iframeWindow.addEventListener("touchend", touch, false); iframeWindow.addEventListener("touchmove", touch, {passive: false}); }else{ iframeWindow.addEventListener("MSPointerDown", touch, false); iframeWindow.addEventListener("MSPointerMove", touch, false); iframeWindow.addEventListener("MSPointerUp", touch, false); } }
添加監聽的時候,須要指定觸發事件後執行的函數,這裏咱們定義一個touch函數,當監聽到觸摸按下事件時,清除原來的延遲器,並從新設置一個新的延遲器。(也能夠在按下時清除,擡起時從新設置延遲器,這裏我是爲了邏輯上最簡便)
var action = setTimeout(ScreenSaver, conf.Consts.SCREEN_TIMEOUT); function touch(e) { switch (e.type) { case "pointerdown": clearTimeout(action); action = setTimeout(ScreenSaver, conf.Consts.SCREEN_TIMEOUT); break; case "pointermove": break; case "pointerup": break; case "touchstart": clearTimeout(action) action = setTimeout(ScreenSaver, conf.Consts.SCREEN_TIMEOUT); break; case "touchend": break; case "touchmove": e.preventDefault(); break; } }
三、怎麼展現屏保、怎麼消除屏保
屏保頁面的顯示比較簡單,當第一次進入屏保頁面時,建立一個div,用來存放屏保圖片,並將整個div的樣式設置爲全屏、展現在最前。當解鎖屏保時,將div隱藏,同時設置z-index爲-1或更低的值(這一步很重要,不然div雖然隱藏,可是還在屏幕最前面,會影響咱們對iframe的監聽)。當div建立後,後續再進入屏保時,再也不建立新的div,只須要調整屏保div的z-index,display,使其從新顯示便可。當點擊這個div時,回到主頁,注意這時候須要從新設置一個延遲器。
function LockScreen(url) { var lockscreen = document.getElementById("lockscreen") if(lockscreen != null){ lockscreen.style.zIndex = "99999" lockscreen.style.display = "block"; }else{ var tabframe = document.createElement("div"); tabframe.id = "lockscreen"; tabframe.name = "lockscreen"; tabframe.style.top = '0px'; tabframe.style.left = '0px'; tabframe.style.height = '100%'; tabframe.style.width = '100%'; tabframe.style.position = "absolute"; tabframe.style.zIndex = "99999"; document.body.appendChild(tabframe); var html = "<img id='screenimg' frameborder=0 style='width:100%;height:100%;' src='" + url + "'/>"; tabframe.innerHTML = html; tabframe.style.display = "block"; document.getElementById("screenimg").onclick = UnlockScreen(); } } function UnlockScreen() { document.getElementById("myframe").src = "/page/main-main.html"; setTimeout(function () { var lockscreen = document.getElementById("lockscreen") if(lockscreen != null{ lockscreen.style.z-index = "-1"; lockscreen.style.display = "none"; } action = setTimeout(ScreenSaver, conf.Consts.SCREEN_TIMEOUT); }, 1000); }
四、最後再簡單說一下setTimeout和setInterval函數的區別,這2個函數的原型以下:
setTimeout(function, milliseconds)
在等待指定的毫秒數後執行一個函數。
setInterval(function, milliseconds)
與setTimeout()相同,可是連續重複執行該函數。
setTimeout()和setInterval()是HTML DOM Window對象的方法。
如何中止執行setTimeout?
clearTimeout()方法中止執行setTimeout()中指定的函數。
myVar = setTimeout(function, milliseconds);
clearTimeout(myVar);
如何中止執行setInterval?
clearInterval()方法中止執行setInterval()方法中指定的函數。
myVar = setInterval(function, milliseconds);
clearInterval(myVar);
更深刻的說明,能夠參考連接: https://www.jianshu.com/p/fc9a08ca2c92