由屏保需求來談延遲器、觸摸事件、iframe的使用

最近在開發項目時,遇到了一個屏保需求,項目的頁面是父子關係,在父頁面中嵌套了一個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; //判斷是否IEEdge瀏覽器
    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

相關文章
相關標籤/搜索