H5路由控制

// 前端很多MVC都有路由模块,但兼容多浏览器的代码比较多。
// 这里根据H5新api popstate,监听路由变化,注册一到多个处理函数,没有兼容旧版浏览器的部分,代码量更少更简单,可独立使用。
// 处理函数接收hash部分,可参考backbone自行解析
// 已在线上运行
var Router = (function () {
    var win = window;
    /*
     * 设置路由
     */
    var getHash = function (url) {
        url = url || win.location.href;
        var match = url.match(/#(.*)$/);
        return match ? match[1] : '';
    };

    var routeHandleCache = [];

    function iterateRegistry(handles) {
        var hash = getHash();
        for (var i = 0, len = handles.length; i < len; i++) {

            var handleFunc = handles[i];
            if (!handleFunc) {
                continue
            } else {
                var result = handleFunc(hash);
                if (result === true) {
                    return
                } else {
                    continue
                }
            }
        }
    }

    return {
        getHash: getHash,
        //这里的注册将处理函数push进数组,hash发生改变是依次调用数组里的每个处理函数,处理函数自己决定如何处理,感觉这是最通用的
        registry: function (handles) {
            if ((typeof handles) == 'function') {
                handles = [handles]
            }
            routeHandleCache = routeHandleCache.concat(handles);
            if (this.started) {
                iterateRegistry(handles);
            }
            //console.log('注册处理函数', routeHandleCache)
        },
        navigate: function (hash) {
            hash = hash || '';
            var url = hash.indexOf('#') == 1 ? hash : '#' + hash;
            location.href = url;
        },
        toView: function (path) {
            Router.navigate(path)
        },
        /**
         * 页面一开始没有hash,这个时候page或许也都没注册,所以需要一个启动函数,在page注册后处理hash为''的情况
         */
        start: function () {
            var __initRegistry = false;
            win.addEventListener('popstate', function () {
                this.started = true;
                iterateRegistry(routeHandleCache);
                __initRegistry = true;
            }.bind(this));

            //修复部分浏览器默认  首次进入页面会执行次popstate,某些不会的差异情况修复
            setTimeout(()=> {
                if (!__initRegistry) {
                    iterateRegistry(routeHandleCache);
                }
            }, 200);

            this.navigate(getHash())
        }
    };
})();
module.exports = Router;

你可能感兴趣的:(H5路由控制)