history之学习联想

3,454 阅读2分钟

1.history.back() 通过这个方法我们可以像点击浏览器的返回按钮,实现页面的返回。 2.history.forward() 通过这个方法我们可以如果点击浏览器的前进按钮。 3.history.go() 跳转到session历史中的一个页面。

history.go(1); //向前一页
history.go(-1); //向后一页
//通过传入参数可以前进退后多页(session中的历史页面)

4.history.pushState() pushState可以传入三个参数,第一个参数为state对象,第二个参数为标题(试了好像不管用),第三个参数为跳转的url。

state可以让我们存储一些json对象的值,我们可以在history.state中获取到值。 url可以传入一个相对路径,会在当前的路径下加上传入的url:

//路径为http://localhost:3000
history.pushState({name: 'moneyinto'}, '页面标题', '#another');
//之后的路径为http://localhost:3000/#another

5.history.replaceState() replaceState和pushState用法很像,只是replaceState是修改当前的history,而pushState是创建新的history。

6.window.onpopstate 监听浏览器的返回或history.back()

window.addEventListener("popstate", function() {
	//返回后执行的代码
});

关于popstate和pushstate我们来联想一下angular的应用,是不是他的单页应用就是通过这样实现的呢?这个吗,我们可以自己试着来实现一个简单的单页应用。不过问题还存在很多 ######simpleSinglePageApp ######demo 我们有个首页index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>simpleSinglePageApp</title>
    <link rel="stylesheet" href="lib/singlePage/singlePage.css" />
    <link rel="stylesheet" href="css/style.css" />
    <script src="router.js"></script>
    <script src="lib/singlePage/singlePage.js"></script>
</head>
<body>

</body>
</html>

我们也建个router.js:

var router = {
    home: {
        template: 'tpl/home.html',
        controller: 'js/home.js'
    },
    
    detail: {
        template: 'tpl/detail.html',
        controller: 'js/detail.js'
    },
    
    about: {
        template: 'tpl/about.html',
        controller: 'js/about.js'
    }
};

var routerHome = router.home;

我们创建各自tpl和js。

  • home.html
<div class="list">
    <div class="item">
        我是第一条
    </div>

    <div class="item">
        我是第二条
    </div>

    <div class="item">
        我是第三条
    </div>

    <div class="item">
        我是第四条
    </div>

    <div class="item">
        我是第五条
    </div>
</div>
  • home.js
(function () {
    var items = document.getElementsByClassName('item');
    items[0].onclick = function () {
        single.go('detail',{id: 1});
    };

    items[1].onclick = function () {
        single.go('detail',{id: 2});
    };

    items[2].onclick = function () {
        single.go('detail',{id: 3});
    };

    items[3].onclick = function () {
        single.go('detail',{id: 4});
    };

    items[4].onclick = function () {
        single.go('detail',{id: 5});
    };
})();
  • detail.html
<div>
    我是第 <span class="detail"></span></div>
  • detail.js
(function () {
    var num = single.getParams();
    console.log(num);
    document.getElementsByClassName('detail')[0].innerText = num.id;
})();

然后我们看看实现脚本(loadjs会在页面添加重复的脚本,还没想好怎么解决)

var single = (function () {
    var singlePageZIndex = 1;

    var singlePage = {
   	//页面初始化
        init: function () {
            var self = this;
            var link = window.location.href;
            var routerName = link.split('#')[1] || '';
            window.onload = function () {
                if (routerName != '' && routerName != routerHome.home) {
                    singlePage.replace(routerName, history.state);
                } else {
                    self.renderPage(routerHome);
                    singlePage.loadJs(routerHome);
                }
            }
        },
		//根据url传入router的值渲染页面
        renderPage: function (singleData) {
            var html = '<div class="singleContentBox" style="z-index: ' + singlePageZIndex + '">';
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", singleData.template, true);
            xmlhttp.send();
            xmlhttp.onreadystatechange = function() {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    var div = document.createElement('div');
                    div.innerHTML = html + xmlhttp.responseText + '</div>';
                    document.getElementsByTagName("body")[0].appendChild(div);
                    singlePageZIndex++;
                }
            }
        },
		//动态加载脚本
        loadJs: function (singleData) {
            var oHead = document.getElementsByTagName('head').item(0);
            var oScript= document.createElement("script");
            oScript.type = "text/javascript";
            oScript.src=singleData.controller;
            oHead.appendChild(oScript);
        },
		//返回后去掉加载进来的页面模块
        removePage: function () {
            var pages = document.getElementsByClassName('singleContentBox');
            if (pages.length > 1) {
                pages[pages.length - 1].remove()
            }
            singlePageZIndex--;
        },
		//页面跳转
        go: function (key, params) {
            singlePage.loadJs(router[key]);
            singlePage.renderPage(router[key]);
            if (params != undefined && typeof params === "object") {
                history.pushState(params, key, '#' + key);
            } else {
                history.pushState({}, key, '#' + key);
            }
        },
        //页面返回
        back: function () {
            this.removePage();
            history.back();
        },

        replace: function (key, params) {
            singlePage.loadJs(router[key]);
            singlePage.renderPage(router[key]);
            if (params != undefined && typeof params === "object") {
                history.replaceState(params, key, '#' + key);
            } else {
                history.replaceState({}, key, '#' + key);
            }
        },
		//获取传值
        getParams: function () {
            return history.state;
        }
    };

    singlePage.init();

    window.addEventListener('popstate', function(e){
    	//返回触发后调用移除页面模块
        singlePage.removePage();
    },false);

    return {
        go: singlePage.go,
        back: singlePage.back,
        replace: singlePage.replace,
        getParams: singlePage.getParams
    }
})();