手机h5网页高仿app的web框架(一)无刷新返回,监听返回键的实现

1 篇文章 0 订阅
1 篇文章 0 订阅

手机网页和app性能差别很大,而且我们经常会遇到从列表打开详细页,返回再打开另一个详细页的情况

如果按常规href 或者 location.href=""方式,有以下缺点

1.页面每次都会跳转,返回时,前页重新加载不方便记录上次位置,而且会有一段时间白屏

2.无法监听手机返回事件,阻止返回

我写了一个仿app的框架解决这样的问题

原理就是h5增加了hash栈特性

history.pushState(state, title, url); 添加一条历史记录,不刷新页面

window.addEventListener('popstate', handlePopstate);//监听状态改变

具体实现方法

index.html页面有一个 arrwin数组 记录所有打开的页面(目前用iframe实现打开新的页面)

一.打开新的页面(比如detail.html)的时候 向arrwin数组中插入一个对象,并且在index.html页面增加一个全宽高的div覆盖在index.html上,里面为src为detail.html的iframe标签。


function openwin(key,src,title) {
    if (title) document.title = title || "";
    pushHash({
        key:key,
        title:title
    });
    //修改objwin
    objdata.objwin[key] = {
        wintype:'win',
        key:key
    };
    if (!src) {
        src = key + '.html?v=' + Arg('v');
    }
    var str =
        '<div class="oneopenpage" style="border:none;z-index:' + objdata.curzindex + '">\
            <div class="oneopenpage_overlay"></div>\
            <iframe class="oneopenpage_frame" id="frame' + key + '" src="" name="' + key + '"></iframe>\
        </div>';
    var _obj = $(str);
    objdata.curzindex += 1;
    if (!title) {
        setTimeout(function () {
            var win = $('#frame' + key).length?$('#frame' + key)[0].contentWindow:null;
            if (win && win.document && win.document.title) {
                objdata.arrwin[objdata.arrwin.length - 1].title = win.document.title;
                document.title = win.document.title;
            }
        },2000);
    }
    $('body').append(_obj);
    _obj.show();
    _obj.width();
    _obj.addClass('oneopenpage--visible');
    var _frame = _obj.find('.oneopenpage_frame');
    _frame.width();
    _frame.transitionEnd(function () {
        _frame.prop('src',src);
    });
}

function pushHash(obj) {
    objdata.arrwin.push(obj);
    window.history.pushState(null,obj.title,"#" + obj.key);
}

二.正常关闭页面的时候 监听"popstate"事件 (obj.onPageBack为null),直接调用 $("#frame" + obj.key).parent().remove(); 将index页面的div移除。


function initEvent() {
    window.addEventListener("popstate",function (e) {
        if (objdata.arrwin && objdata.arrwin.length > 1) {
            var obj = objdata.arrwin[objdata.arrwin.length - 1];
            objdata.curhash = objdata.arrwin[objdata.arrwin.length - 1].key;
            if (obj.onPageBack) {
                window.history.pushState(null,obj.title,"#" + obj.key);
                obj.onPageBack(function () {
                    obj.onPageBack = null;
                    history.back();
                });
            } else {
                objdata.arrwin.pop();
                backEvent(obj);
            }
        }

    },false);
}
function backEvent(obj) {
    if (objdata.curhash) {
        closewin(obj);
    }
    document.title = objdata.arrwin[objdata.arrwin.length - 1].title || '';
}
function closewin(obj) {
    if (obj && obj.wintype) {
        if(obj.wintype == 'layer'){
            closelayer(obj);
        } else if(obj.wintype == 'popup'){
            closepopupevent(obj);
        }
    } else {
        $("#frame" + obj.key).parent().remove();
    }
}

三.关闭页面时需要拦截返回按钮事件 

首先要清楚,用户点击android返回按钮时,页面url的hash值是肯定会回退到上一个hash历史的,这个我们无法阻止。

那咱们拦截返回的思路是

   1.如果某页面需要监听返回事件,则注册setOnPageBack方法,给页面的obj增加obj.onPageBack属性。

   2.用户点击返回时,hash值被改变,但此时,页面尚未关闭。我们监听到 "popstate" 事件,如果obj.onPageBack属性,我们立刻向栈内再次push该页面hash(window.history.pushState(null,obj.title,"#" + obj.key);),保证当前打开的页面和hash值是对应的。

   3.等用户点击确认关闭的时候,将该页面的obj.onPageBack 修改为 null,再次调用history.back();

   4.因为已经将obj.onPageBack 修改为 null 再次监听"popstate"的时候,将不再走第2步,直接进行页面的关闭。

window.addEventListener("popstate",function (e) {
        if (objdata.arrwin && objdata.arrwin.length > 1) {
            var obj = objdata.arrwin[objdata.arrwin.length - 1];
            objdata.curhash = objdata.arrwin[objdata.arrwin.length - 1].key;
            if (obj.onPageBack) {
                window.history.pushState(null,obj.title,"#" + obj.key);
                obj.onPageBack(function () {
                    obj.onPageBack = null;
                    history.back();
                });
            } else {
                objdata.arrwin.pop();
                backEvent(obj);
            }
        }

    },false);
parent.setOnPageBack(function (backEvent) {
        if (objdata.needconfirm) {
            $.confirm("确认关闭吗",function () {
                backEvent();
            })
        } else {
            backEvent();
        }
    })
    $("#btnback").click(function () {
        history.back();
    })

function setOnPageBack(backevent) {
    objdata.arrwin[objdata.arrwin.length - 1].onPageBack = backevent;
}

目前我们项目css框架为weui,js框架jquery-weui,列表都是用mescroll实现

框架代码

https://download.csdn.net/download/qinghechaoge/11209132

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值