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" 转载请保留原文链接及作者。