hashchange事件
hashChange 事件其实就是另一种前端路由的处理方法了。
这里承接 history 相关,对于后退键不刷新页面,使用了修改 hash 来模拟实现的方法。
hashchange
其实就是一个 window 的事件,在页面的 hash 被修改时会被触发。下面直接根据代码讲解吧。
popPage.init = function(iScroll, options) {
var self = this;
location.hash = "";
self.showFlag = false;
self.parentEl = $('<div class="pop-page"><div class="user-control" id="user-control"></div></div>');
window.addEventListener("hashchange", function(event) {
event.preventDefault();
if (location.hash == "#poppage") {
//前进键打开(ios),直接清hash
if (!self.showFlag) {
location.hash = "";
return;
}
self.showFlag = false;
//body设置overflow可能会滚到到头部,先保存
self.scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
//安卓需要给body和html都加上才会锁住
$("html").addClass("fix-scroll");
$("body").addClass("fix-scroll");
//小的兼容问题,不设置的页面有几率不回到顶部
document.documentElement.scrollTop = document.body.scrollTop = 0;
$("body").append(self.parentEl);
//android2.3 bug,不加setTimeout初始化iSroll失败
setTimeout(function() {
//class改变得在setTimeout里面
//animation android2.3部分支持,测试无效,最后使用了transction
self.parentEl.addClass("from-right");
//判断iScroll是否传入
if (iScroll != undefined) {
var options = options || { click: true };
new iScroll(document.getElementById("user-control"), options);
}
}, 0);
} else {
//还原,清空
$("html").removeClass("fix-scroll");
$("body").removeClass("fix-scroll");
self.el().empty();
self.parentEl.remove().removeClass("from-right");
document.documentElement.scrollTop = self.scrollTop;
document.body.scrollTop = self.scrollTop;
}
});
};
阻止了页面默认行为,页面的滚动自己来控制,不会有烦人的兼容
切换 hash 触发 window 的 hashchange 事件
body 元素固定住,不让他滚动,原页面最小影响
手机浏览器哪怕 body 设置了
overflow
也是可以滚动的,解决方式是给html
也加上overflow
使用
overflow
有个坑,安卓 2.3 不支持这个属性,所以想做的话,从外部传进一个 iscroll外部传入 iscroll,为了兼容,我传入了元素
document.getElementById('user-control')
iscroll 对于新生成的元素需要写在 settimeout 里面
动画选择使用 transction,animation 在安卓 2.3 支持不好
popPage.newPage = function() {
var self = this;
self.showFlag = true;
//这样来触发hashchange方法
location.hash = "#poppage";
return self.el();
};
popPage.el = function() {
var self = this;
return self.parentEl.children(".user-control");
};
popPage.close = function() {
var self = this;
//这里加了个setTimeout,就可以直接清除了
setTimeout(function() {
if (location.hash == "#poppage") {
history.go(-1);
} else {
console.log("还未添加页面");
}
}, 0);
};
module.exports = popPage;
这里是生成的页面,然后还提供了一个 close 方法,可供外界关闭这个新页面,这里的 close 用setTimeout
包住了,不然会有异步的问题。还提供了一个可以得到内部元素的指针。
还得配合以下的 css 一起使用
.pop-page {
background-color: #fff;
position: absolute;
width: 100%;
height: 100%;
overflow: scroll;
margin: 0px -20px 0px 20px;
opacity: 0.9;
transition: all 0.5s;
-moz-transition: all 0.5s; /* Firefox 4 */
-webkit-transition: all 0.5s; /* Safari and Chrome */
-o-transition: all 0.5s; /* Opera */
}
.from-right {
margin: 0px 0px 0px 0px;
opacity: 1;
}
.fix-scroll {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}
.user-control {
position: relative;
background-color: #fff;
width: 100%;
height: 100%;
}
总结
踩了无数的 android2.3 的坑。包括动画,overflow。
后退时将新页面销毁了,因为这样比较安全。
意味着前进键回不去了,不是做不到支持前进键,而是不安全。
这个模块在勐喆的帮助下修改了很多次,逐渐变得越来越抽象,而且对原页面无痛。支持情况很好。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 981909093@qq.com
推荐文章
文章标题:hashchange事件
文章字数:870
本文作者:泽鹿
发布时间:2019-08-28, 16:45:23
最后更新:2019-08-28, 20:06:25
原始链接:http://panyifei.github.io/2019/08/28/前端技术/js/框架以及规范/HTML5/hashchange事件/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。