JavaScript模拟原生的页面切换效果

8次阅读

共计 2068 个字符,预计需要花费 6 分钟才能阅读完成。

标题文字

<!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>

正文完
 0