原生开发移动web单页面(step by step)6——history api应用

简介: 以上几篇的内容成功的将多页面合成到单页面上,然而还是有很多区别的, 多页面切换的时候,通过浏览器的自带后退前进键可以进行导航,然而到目前为止,是没有办法进行的导航的,这一篇主要是引入了这个功能。

以上几篇的内容成功的将多页面合成到单页面上,然而还是有很多区别的, 多页面切换的时候,通过浏览器的自带后退前进键可以进行导航,然而到目前为止,是没有办法进行的导航的,这一篇主要是引入了这个功能。

在进入正题之前,我们还需要对整体做一下调整, 一般情况下, 一个页面分为两个部分,一部分是静态部分,只要起到布局作用,还有一部分为改变部分,主要用来切换页面的作用。在布局中设置一块改动的区域,放置动态页面, 不同的动态页面调用静态部分提供的方法来调整不同的布局。 这样的结构如下图所示。

界面的布局

这里的做法就是让静态布局部分和动态部分都是Page实例对象,通过App的实例对象初始化并渲染首页,如以下代码:

app.initialize(staticPage, indexPage);

切换页面的代码与之前的一样, 介绍了这个后,接下来介绍history api。

浏览器history记录是类似一个数组, 通过一个索引值代表当前的页面,如果按后退键,将会索引值减一, 跳到之前的页面,按前进键则相反,如下图所示。


history栈

浏览器history api提供了两个方法来操作这个历史数据的数组: pushState和replaceState。 pushState方法的作用为在当前页面所在的索引值插入一个新的记录,然后移除所有后面的记录,与用户单击一个链接大致相同, 并将历史的索引值转到新的记录。如下图所示


pushState操作

replaceState方法的作用为替换当前的记录,不影响历史记录数组中其它数据的更改,如下图所示


replaceState操作

当点击浏览器的前进后退键的时候,就会触发popstate的事件, 通过监听事件获取到的历史数组中状态的改变而动态更改页面,调用history的方法也会触发popstate事件。
下面介绍了如何把它集成到App对象中,App构造函数的代码如下

function App() {
    this.currentPage = null;
    this.staticPage = null;
    this.pageContainer = null;
    this.routeObj = {};
}

staticPage存放静态布局页面,可以调用其方法更改外部布局
pageContainer是可变页面的容器
routeObj对象放置页面对象,key代表页面的url, value为Page对象
nitialize方法代码如下

initialize: function (staticPage, indexPage) {
    staticPage = this.staticPage = staticPage || App.emptyPage;
    var that = this;

    staticPage.render(function (html) {
        var body = document.body;
        body.insertAdjacentHTML("afterbegin", html);
        staticPage._initialize(body);
        if (staticPage.domList.pageContainer) {
            that.pageContainer = staticPage.domList.pageContainer;
        }
        else {
            console.error("staticPage must have pageContainer");
        }
        that.render(indexPage, true);

        window.addEventListener("popstate", function (ev) {
            if (ev.state && ev.state.data) {
                var url = ev.state.data;
                var page = that.routeObj[url];
                that._renderPage(page);
            }
        }, false);
    });
},

这里需要静态布局页面有个PageContainer,让动态页面放置。
_attachHistory方法的代码如下

_attachHistory: function (page, isBack) {
    var newUrl =  page.url;
    
    if (isBack) {
        history.replaceState({data: newUrl}, "", newUrl);
    }
    else {
        history.pushState({data: newUrl}, "", newUrl);
    }
},

_renderPage方法的代码如下

_renderPage: function (page) {
    if (this.currentPage) this.currentPage._dispose();
    this.currentPage = page;
    page.app = this;

    document.title = page.title;
    var pageContainer = this.pageContainer;
    page.render(function (html) {
        pageContainer.innerHTML = html;
        page._initialize(pageContainer);
    });
}

修改Page构造函数与App.createPage函数
Page构造函数如下

function Page(title, url) {
    this.title = title;
    this.url = url;
    this.domList = {};
    this.eventList = [];
}

App.createPage代码如下

App.createPage = function (title, url, options) {
    var page = new Page(title, url);
    App.extend(page, options);
    return page;
}

然后对应创建一个App.emptyPage, 代码如下

App.emptyPage = App.createPage("", "", {
    render: function (fn) {
        fn("<div class='pageContainer'></div>");
    },
    getDomObj: function (dom) {
        this.attachDom(".pageContainer", "pageContainer", dom);
    }
});

修改entry.js, login.js, register.js和goal.js,定义各自Page实例对象的时候,增加url的字段,
分别为/serve/entry, /serve/login, /serve/register和/serve/goal, 以serve开头的,是为了页面刷新的时候,服务器检索到url以/serve开头,然后跳转到首页。

更改提供后台服务页面的serverFile.js修改exports.getFile方法,代码如下

exports.getFile = function (req, res, key, root) {
    if (key.indexOf("/public/")  === 0) {
        serveFile(req, res, root + key, root);
    }
    else if (key.indexOf("/serve") === 0) {
        serveFile(req, res, root + "/public/serve/index.html", root);
    }
    else {
        res.statusCode = 404;
        res.end("404");
    }
}

修改index.js的代码,如下

var app = new App();
app.initialize(null, entryPage);

如果想要刷新跳到当前页面,那就需要在类似在sessionStorage的存储机制中存放当前的页面url,然后在初始化的时候,将entryPage替换为该url的page对象即可。

总结: 加入history api后,页面表现和普通的多页面相差无几了,可以跳转, 可以后退。 改变页面后title和url也随着改变,刷新直接跳到首页也可以跳到当前页。到了这篇为止,单页面改造完毕,然而,单页面的灵活性远非多页面可比的, 如果处理得到,复杂性却不会增加很多。 接下来的篇章就是为了让单页面更加出彩, 甚至达到原生app的水准。

后续更新:下一篇将重点介绍css3的animation, 配合页面切换, 让页面切换动态化。css3的animation模块在后面的部分使用的非常频繁,为理解后面的代码做一下基础。

案例链接


原生开发移动web单页面(step by step)1——传统页面的开发
原生开发移动web单页面(step by step)2——Page对象
原生开发移动web单页面(step by step)3——App对象
原生开发移动web单页面(step by step)4——tap事件与slide事件
原生开发移动web单页面(step by step)5——nodejs服务器的搭建

相关文章
|
6天前
|
移动开发 开发者 HTML5
构建响应式Web界面:Flexbox与Grid的实战应用
【10月更文挑战第22天】随着互联网的普及,用户对Web界面的要求越来越高,不仅需要美观,还要具备良好的响应性和兼容性。为了满足这些需求,Web开发者需要掌握一些高级的布局技术。Flexbox和Grid是现代Web布局的两大法宝,它们分别由CSS3和HTML5引入,能够帮助开发者构建出更加灵活和易于维护的响应式Web界面。本文将深入探讨Flexbox和Grid的实战应用,并通过具体实例来展示它们在构建响应式Web界面中的强大能力。
21 3
|
1天前
|
前端开发 JavaScript 安全
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第27天】本文介绍了HTTP/2和HTTPS在前端性能调优中的应用。通过多路复用、服务器推送和头部压缩等特性,HTTP/2显著提升了Web性能。同时,HTTPS确保了数据传输的安全性。文章提供了示例代码,展示了如何使用Node.js创建一个HTTP/2服务器。
8 2
|
2天前
|
前端开发 安全 应用服务中间件
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第26天】随着互联网的快速发展,前端性能调优成为开发者的重要任务。本文探讨了HTTP/2与HTTPS在前端性能优化中的应用,介绍了二进制分帧、多路复用和服务器推送等特性,并通过Nginx配置示例展示了如何启用HTTP/2和HTTPS,以提升Web应用的性能和安全性。
12 3
|
2天前
|
前端开发 JavaScript API
前端框架新探索:Svelte在构建高性能Web应用中的优势
【10月更文挑战第26天】近年来,前端技术飞速发展,Svelte凭借独特的编译时优化和简洁的API设计,成为构建高性能Web应用的优选。本文介绍Svelte的特点和优势,包括编译而非虚拟DOM、组件化开发、状态管理及响应式更新机制,并通过示例代码展示其使用方法。
11 2
|
2天前
|
测试技术 持续交付 PHP
PHP在Web开发中的应用与最佳实践###
【10月更文挑战第25天】 本文将深入探讨PHP在现代Web开发中的应用及其优势,并分享一些最佳实践来帮助开发者更有效地使用PHP。无论是初学者还是有经验的开发者,都能从中受益。 ###
11 1
|
3天前
|
负载均衡 监控 算法
论负载均衡技术在Web系统中的应用
【11月更文挑战第4天】在当今高并发的互联网环境中,负载均衡技术已经成为提升Web系统性能不可或缺的一环。通过有效地将请求分发到多个服务器上,负载均衡不仅能够提高系统的响应速度和处理能力,还能增强系统的可扩展性和稳定性。本文将结合我参与的一个实际软件项目,从项目概述、负载均衡算法原理以及实际应用三个方面,深入探讨负载均衡技术在Web系统中的应用。
21 2
|
3天前
|
JSON API 数据格式
如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架
本文介绍了如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架,适合小型项目和微服务。文章从环境准备、创建基本Flask应用、定义资源和路由、请求和响应处理、错误处理等方面进行了详细说明,并提供了示例代码。通过这些步骤,读者可以快速上手构建自己的RESTful API。
13 2
|
6天前
|
JavaScript 前端开发 持续交付
构建现代Web应用:Vue.js与Node.js的完美结合
【10月更文挑战第22天】随着互联网技术的快速发展,Web应用已经成为了人们日常生活和工作的重要组成部分。前端技术和后端技术的不断创新,为Web应用的构建提供了更多可能。在本篇文章中,我们将探讨Vue.js和Node.js这两大热门技术如何完美结合,构建现代Web应用。
13 4
|
2天前
|
API 持续交付 PHP
PHP在现代Web开发中的应用与未来展望####
【10月更文挑战第25天】 本文深入探讨了PHP作为服务器端脚本语言在现代Web开发中的关键作用,分析了其持续流行的原因,并展望了PHP在未来技术趋势中的发展方向。通过实例解析和对比分析,揭示了PHP如何适应快速变化的技术环境,保持其在动态网站构建中的核心地位。 ####
|
3天前
|
存储 人工智能 大数据
拼多多详情API的价值与应用解析
拼多多作为中国电商市场的重要参与者,其开放平台提供的商品详情API接口为电商行业带来了新的机遇和挑战。该接口允许开发者通过编程方式获取商品的详细信息,包括标题、价格、描述、图片、规格参数和库存等,推动了电商运营的智能化和高效化。本文将深入解析拼多多详情API的价值与应用,帮助商家和开发者更好地理解和利用这一宝贵资源。
8 0