博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
首次开发H5长图页总结
阅读量:5020 次
发布时间:2019-06-12

本文共 5977 字,大约阅读时间需要 19 分钟。

首次开发H5长图页总结.

资源统一加载

资源统一加载, 分开获取

定义资源标识符

  • src/resources目录下 定义各个资源模块.
  • Asset.js中获取定义好的所有模块, 循环出具体的文件路径, 统一数组.
  • 按照一定规则组件文件id, 方便页面中获取.

暴露方法, 挂载全局

在全局app.init的时候, 进行资源的初始化, 并把初始化的资源对象挂载到Global对象上, 方面后续其他页面的资源获取.(Global用作全局属性管理).代码的执行顺序为:

app.init() => new Asset() => asset.load() => asset.onComplete() => initStage() => ....

  • load: 可开始加载全部资源
  • onComplete: 资源全部加载完成
  • getAsset: 获取指定资源

切换思想

全局只存在两个container; 所有页面交替出现

创建舞台的过程

所有的页面均在initStage()初始化舞台时, 进行创建, 以确保资源全部加载完成. 舞台初始化完成, 所有的页面也均初始化完成.

initStage()过程包括:

  1. initBus(): 初始化全局的事件订阅系统
  2. createStage(): 创建舞台, 在创建舞台的时候, 就和绑定好了滚动函数.
  3. initScene: 因为刚开始的代码逻辑出现问题, 全局只有一个场景, 是起初没有考虑到的
  4. 完成, 即可把第一个页面推出显示栈.

页面创建过程

在创建舞台的时候, 会初始化场景, 我们的页面总体分成: 舞台 > 场景 > 部分(页面)

初始化场景的过程, 也就是初始化所有页面的过程:

new Scene() => init partMap() => partMap.push(new Part)

partMap是所有页面的集合, 按照显示顺序进行创建.

  • 每当执行new part时, 就是页面执行自身constructor, 并调用init方法的过程.
  • 因每一个页面都是通过push方法, 放入到parMap中的, 故初始化过程的中partMap的长度就是, 当前页面所在partMap中的位置
  • 页面创建后, 会包含所有后续需要的属性, 以及页面声明周期中所有状态的初始化.
  • 并在创建过程中完成各个模块的监听

页面生命周期

正序执行过程: p1.start => p1.next => p2.start => p1.end => p2.next => ....

倒序执行过程: p2.prev => p1.restart => p2.end => ....

每次声明周期函数, 为避免计算错误, 只在特定的时间执行一次, 故需要一些关键的状态管理

  • start: 页面开始函数, 即让页面执行addTo()添加到舞台中
  • reStart: 重新展示页面, 让页面的执行addTo(stage, 0), 让页面插入到舞台的最底层位置
  • prev: 上一个页面战术, 即让上一个页面执行reStart()重新展示
  • next: 下一个页面战术, 即下一个页面执行start()方法
  • end: 页面展示结束, 从父元素中remove出来, 并重置方法执行状态.

    除next方法, 需要在页面内具体实现外, 其他方法均为统一处理

  • shouldUpdate: 监听到滚动, 执行页面内具体逻辑

滑动高度

initStage的时候, 绑定滚动事件. 并广播全局事件.

动态计算

  • 全局总高度: 每一次new part的时候, 都会累加整个页面需要的总高度, 并以此设计能够滑动的高度.
  • 页面高度计算方式: 页面的高度, 是通过参数传入的.
  • 页面开始高度:
    • 从全局看: 当前页面高度是, 之前所有页面的累加高度, 也就是全局的高度.
    • 从页面看: 所有的页面都是从0开始.

当前页面的滚动位置

当前页面滚动的位置 = 总共滚动过的高度 - 当前页面开始的高度

  • <0的部分还和上一个页面重叠
  • >0之后, 自己完全出现
  • 合适的时机 调用, next, 下一个页面就可以开始<0的过程了.
  • 当滚动的高度大于当前页面的高度时, 就是执行end的时候了.

附上核心实现函数

// Part.js// 注: 此函数依赖全局模块import Global from './Global'const Part = Hilo.Class.create({  Mixes: Hilo.EventMixin,  constructor: function (properties) {    this.parentNode = properties.parentNode || null; // 页面所属场景    this.parentContainer = properties.parentNode ? properties.parentNode.content : null; // 页面所属容器    this.parentName = properties.parentNode ? properties.parentNode.name : ''; // 页面所属场景名称    this.name = properties.name || ''; // 页面名称    this.partHeight = properties.height || 0; // 页面的总高度    this.disappearNext = properties.disappear || 0; // 页面需要消失的距离    this.state = 'hide'; // 当前页面是否展示    this.nextDone = false; // next函数是否执行过    this.prevDone = false; // prev函数是否执行过    this.index = this.parentNode.partMap.length; // 此处为核心概念, 根据数组长度确定当前索引!!    this.content = new Hilo.Container({      id: this.name    });    this.initStartHeight(); // 计算当前页面的在全局中的开始高度    if (this.init instanceof Function) this.init();    // 监听用户滚动, 高度变化.    Global.bus.on('changeTouchHeight', this.changeTouchHeight.bind(this));  },  initStartHeight: function () {    // 获得当前页面在全剧中的高度    var perNode = this.getPrevNode()    this.startHeight = perNode ? Global.totalHeight += perNode.partHeight : Global.totalHeight;    // 页面能够滚动到的最大高度    var maxHeight = (this.startHeight + this.partHeight - Global.height) / Global.touchSpeed;    Global.scroller.setDimensions(0, 0, 0, maxHeight)  },  changeTouchHeight: function (info) { // 监听高度变化    if (this.state === 'show' && this.shouldUpdate instanceof Function) {      var touchHeight = info.detail.distance - this.startHeight; // 页面内的高度变化值      var direction = info.detail.direction; // 滚动的方向      if (direction === 'up' && touchHeight <= 0) { // 向上滚动, 且高度小于0, 上一个页面展示        this.prev();      }      if (direction === 'down' && touchHeight >= this.partHeight) { // 向下滚动, 超过当前页面最大高度, 从父容器中抽出        console.log(this.name, 'down end')        this.end()      }      if (direction === 'up' && this.getPrevNode()  && touchHeight < -this.getDisappearPrev()) { // 向上滚动, 超过上一个页面的消失高度, 从父元素中抽出        console.log(this.name, 'up end')        this.end()      }      // 调用生命周期, 通知页面内变化      this.shouldUpdate(touchHeight, direction);    }  },  start: function () { // 开始展示    if (this.state === 'show') return;    this.state = 'show';    console.log(this.name, 'start');    if (this.onStart instanceof Function) this.onStart();    this.content.addTo(this.parentContainer);  },  reStart: function () { // 再次展示, 也就是向上滑动, 展示到舞台的最底层    if (this.state === 'show') return;    this.state = 'show';    console.log(this.name, 'reStart');    if (this.onreStart instanceof Function) this.onreStart();    this.content.addTo(this.parentContainer, 0);  },  prev: function () { // 展示上一个页面    if (this.state === 'hide' || this.prevDone) return;    if (this.getPrevNode() && this.getPrevNode().state === 'show') return;    this.prevDone = true;    console.log(this.name, 'prev')    if (this.onPrev instanceof Function) this.onPrev();    this.getPrevNode() && this.getPrevNode().reStart();  },  next: function () { // 展示下一个页面    if (this.state === 'hide' || this.nextDone) return;    if (this.getNextNode() && this.getNextNode().state === 'show') return;    this.nextDone = true;    console.log(this.name, 'next')    if (this.onNext instanceof Function) this.onNext();    this.getNextNode() && this.getNextNode().start();  },  end: function () { // 页面展示结束, 抽出    if (this.state === 'hide') return;    console.log(this.name, 'end')    if (this.onEnd instanceof Function) this.onEnd();    this.state = 'hide';    this.content.removeFromParent();    this.getNextNode() && (this.getNextNode().prevDone = false);    this.getPrevNode() && (this.getPrevNode().nextDone = false);  },  getPrevNode: function () { // 获取上一个页面节点    var map = this.parentNode.partMap;    var index = this.index;    return map[index - 1];  },  getNextNode: function () { // 获取下一个页面节点    var map = this.parentNode.partMap;    var index = this.index;    return map[index + 1];  },  getDisappearNext: function () { // 向下滚动消失需要的距离    return this.disappearNext;  },  getDisappearPrev: function () { // 向上滚动消失需要的距离    return (this.getPrevNode() && this.getPrevNode().getDisappearNext()) || 0;  },});export default Part;

转载于:https://www.cnblogs.com/zhangrunhao/p/10711449.html

你可能感兴趣的文章
【转】VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application”...
查看>>
函数中关于const关键字使用的注意事项
查看>>
微信架构(转)
查看>>
Web项目中的路径问题
查看>>
js随机数的取整
查看>>
关于解析漏洞
查看>>
十大经典预测算法(六)---集成学习(模型融合算法)
查看>>
用php做一个简单的注册用户功能
查看>>
一款基于css3的3D图片翻页切换特效
查看>>
Feign使用Hystrix无效原因及解决方法
查看>>
Sizeof与Strlen的区别与联系
查看>>
hadoop2.2.0_hbase0.96_zookeeper3.4.5全分布式安装文档下载
查看>>
Flutter 贝塞尔曲线切割
查看>>
golang 的编译安装以及supervisord部署
查看>>
easyui源码翻译1.32--Dialog(对话框窗口)
查看>>
阿里架构师,讲述基于微服务的软件架构模式
查看>>
Eclipse导入maven项目时,Pom.xml文件报错处理方法
查看>>
01、JAVA开发准备
查看>>
asp.net mvc 错误处理 - 自定义报错处理,生成错误日志
查看>>
Linux centos ssh
查看>>