前端单页应用以及状态保持的探索

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端单页应用以及状态保持的探索相关的知识,希望对你有一定的参考价值。

工作中对单页应用和状态保持有些研究希望和大家分享一下:

我们主要探讨两个内容:单页应用、状态保持

一、单页应用

先说第一个:单页应用,单页应用就是指应用所有的交互都是在一个页面中进行的,当然实现方式有多种:

1、页面中放多个div对应多个虚拟页面,通过显示隐藏来切换

  优点:切换速度快,状态可保持

  缺点:所有的虚拟页面都放到一个真实页面里,先不说浏览器能不能受得了,开发时可能遇到各种id,class冲突,事件冲突等等,少量页面估计还行。

2、通过类似android的activity生命周期来管理虚拟页面,这里详细介绍一下:

  每个页面对应一个js对象,类似android前端.xml都有一个.java文件对应一样,如下:

    XXX.page.index = new XXX.view({
             cache:true, //如果页面需要保持状态设置为true
             init:function(){
                 //调用时机:路由到此页面时基类调用此方法
             //作用:主要是初始化相关属性 例如:pageindex  pagesize等
                 this.render();
             },
             render:function(){
             //调用时机:init方法调用
                 //作用:渲染页面(拉取数据配合模板引擎生成html放到页面中)
                 this.bindEvent();
             },
             bindEvent:function(){
             //调用时机:1、render方法调用 2、基类页面会在调用resume后调用此事件
                //作用:绑定事件
             },
             resume:function(){
                 //调用时机:cache:true则检查如果有缓存则基类恢复页面基本信息后调用此方法
             //作用:手动恢复页面上比较特殊的地方。 例如:倒计时时间的重新计算
             },
             dispose:function(){
                 //调用时机:下一个页面init时 基类主动调用此方法。
                 //作用:销毁不需要的对象,例如定时器
             },
       })    

 

页面基类如下:

 //页面基类
    XXX.view = function(opt){
        _extend(this,opt);
        this._cache = null;//cache实例的字符串
        this._cacheKey = "";
        this.disposeTime = 0;//页面销毁时间
        //路由调用baseInit方法
        this._baseInit = function(){this._cacheKey = XXX.page.getPageCacheKey();
            //检查是否有缓存  
            this._cache = sessionStorage[this._cacheKey];
            if(this.cache === true && this._cache){
                this._cache = JSON.parse(this._cache);
                this._cache.instance = JSON.parse(this._cache.instance);
                //把_baseInit参数继续传入_baseResume
                this._baseResume.apply(this,arguments);
            }
            else{
                if(typeof this.init === "function"){
                    this.init.apply(this,arguments);
                }
                else{
                    console.log("no init method");
                }
            }
        };
        this._baseResume = function(){
            //恢复事件
            var cache = this._cache;
            var renderDom = $("#"+XXX);
            renderDom.html(cache.html);
            $("body").scrollTop(cache.scrollTop);
            //还原各个属性
            for(var key in cache.instance){
                this[key] = cache.instance[key];
            }
            //离开的时间
            this.disposeTime = cache.disposeTime;
            //执行resume恢复事件
            if(typeof this.resume === "function"){
                //arguments为_baseInit的参数
                this.resume.apply(this,arguments);
            }
            else{
                console.log("no resume method");
            }
            //重新执行bindEvent
            if(typeof this.bindEvent === "function"){
                this.bindEvent();
            }
            else{
                console.log("no bindEvent method");
            }
        };
        this._baseDispose = function(){
            var html = $("#"+XXX).html();
            if(this.cache === true && html && html.length > 0){
                //添加或更新缓存
                var cache = {
                    html:$("#"+meishijia.page.renderId).html(),
                    disposeTime:+new Date,
                    scrollTop:$("body").scrollTop(),
                    instance:JSON.stringify(this)
                }
                sessionStorage[this._cacheKey] = JSON.stringify(cache);
            }
            if(typeof this.dispose === "function"){
                this.dispose();
            }
            else{
                console.log("no dispose method");
            }
        };
        this.clearCache = function(){
            if(this._cacheKey){
                //检查是否有缓存
                sessionStorage.removeItem(this._cacheKey);
            }
        }
    }

  这下基本知道基类的工作原理了吧。

 

二、状态保持(比如滚动高度、按钮点击状态,pageindex等)

  咱们可以用chrome切换到手机调试模式,查看京东或淘宝的商品列表,当你滑啊滑,找到一个感兴趣的商品时点进去,待会再返回来可就坑爹了,不在刚才的位置了,还得重新找。手机浏览器上即使可以也是浏览器帮做的,而且各个手机浏览器又不太一致。这就是状态保持的问题(可不仅仅是滚动高度的问题)。

  按照咱们上面讨论的方案,基类已经做了状态保持的大部分工作,特殊的可以手动还原,这样就做到了真正的状态保持。当然这里只是最基本的功能,很多细节问题还得实践中不断发现并解决,也希望大家提出更好的方案。

以上是关于前端单页应用以及状态保持的探索的主要内容,如果未能解决你的问题,请参考以下文章

单页应用的数据流方案多思路探索

使用 Vue + Flask 搭建单页应用

一个单页应用的部署

vue单页应用在页面刷新时保留状态数据的方法

对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 错误解决一例。(代码片段

在 .NET 后端函数中使用 React 状态作为参数