hashchange事件

  1. 总结

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

目录
×

喜欢就点赞,疼爱就打赏