JavaScript模擬原生的頁面切換效果

標題文字

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>模擬原生的頁面切換效果</title>
    <style>
        body,html{
            height: 100%;
        }
        .pages{
            height: 100%;
            -webkit-overflow-scrolling: touch; /* 開啓回彈 */
        }
        .pages > div {
            height: 100%;
        }
        .page-home{
            background-color: red;
        }
        .page-start{
            background-color: blue;
        }
        .enter {
            position: absolute;
            top: 0; right: 0; bottom: 0; left: 0;
            z-index: 1;
            animation:  slideIn .5s forwards; /* 設置動畫參數 */
        }
        @keyframes slideIn {
            from {
                transform: translate3d(100%, 0, 0);
            }
            to {
                transform: translate3d(0, 0, 0); /* 結束狀態 X軸到達原點 */
                opacity: 1; /* 結束狀態透明度 */
            }
        }
    </style>
</head>
<body>
    <div class="pages">
        <div class="page page-home"></div>
        <div class="page page-start"></div>
    </div>
    <script>
        // 實現極簡路由功能
        var Router = function() { // 構造函數
            this._routers = []; // 路由隊列
            this._get = function(hash) { // 返回匹配路由
                var router = this._routers.filter(function(item) { // 查詢隊列
                    return '#' + item.url === hash; // 匹配
                });
                return router[0] || {}; // 返回
            }.bind(this); // 改變內部 this 指向
        }

        /** 
        * 推入 routers 隊列
        * @param {Object} route
        * @return {Router}
        */
        Router.prototype.push = function(route) { // 推入隊列方法
            this._routers.push(route); // 推入一個路由對象
            return this;  // 返回 this 實現鏈式調用
        }

        /** 
        * 路由初始化
        * @return {Router}
        */
       Router.prototype.init = function() { // 路由初始化方法
            this.go(this._get(location.hash));  // 對匹配路由進行跳轉
            window.addEventListener('hashchange', function() { // 監聽 hash 變化
                this.go(this._get(location.hash)); // 變化時進行跳轉
            }.bind(this), false); // 改變內部 this 指向
            return this; // 返回 this 實現鏈式調用
       }

       /**
        * 路由跳轉
        * @param {String} page
        * @return {Router} 
        */
       Router.prototype.go = function(page) { // 路由初始化方法
            var entry_page = document.querySelector(page.selector); // 查找進場 DOM 元素
            if (!entry_page) return false; // 未查到結果終止
            entry_page.classList.add('enter'); // 加入進場動畫
            if(page.hasOwnProperty('handle')) { // 是否存在 handle 成員
                page.handle.call(this); // 調用 handle 方法
            }
       }

    // 裝載須要切換的頁面
    var home_page = {   // 首頁
        url: '/', // 對應路徑
        selector: '.page_home', // 對應層名
        handle: function() { // 進場時調用的方法
            console.log('home page enter.')
        }
    };
    var start_page = { // 遊戲開始頁面
        url: '/start', // 對應路徑
        selector: '.page_start', // 對應層名
        handle: function() {
            console.log('start page enter.') // 進場時調用的方法
        }
    }

    var r = new Router(); // 建立路由實例
    r.push(home_page).push(start_page).init(); // 裝載
    </script>
</body>
</html>
相關文章
相關標籤/搜索