首次开发H5长图页总结.数组
资源统一加载, 分开获取app
src/resources
目录下 定义各个资源模块.Asset.js
中获取定义好的全部模块, 循环出具体的文件路径, 统一数组.在全局app.init的时候, 进行资源的初始化, 并把初始化的资源对象挂载到Global对象上, 方面后续其余页面的资源获取.(Global用做全局属性管理).代码的执行顺序为:ide
app.init()
=> new Asset()
=> asset.load()
=> asset.onComplete()
=> initStage()
=> ....函数
全局只存在两个container; 全部页面交替出现this
全部的页面均在initStage()
初始化舞台时, 进行建立, 以确保资源所有加载完成. 舞台初始化完成, 全部的页面也均初始化完成.设计
initStage()过程包括:rest
在建立舞台的时候, 会初始化场景, 咱们的页面整体分红: 舞台 > 场景 > 部分(页面)code
初始化场景的过程, 也就是初始化全部页面的过程:
new Scene() => init partMap() => partMap.push(new Part)对象
partMap是全部页面的集合, 按照显示顺序进行建立.索引
正序执行过程: p1.start => p1.next => p2.start => p1.end => p2.next => ....
倒序执行过程: p2.prev => p1.restart => p2.end => ....
每次声明周期函数, 为避免计算错误, 只在特定的时间执行一次, 故须要一些关键的状态管理
addTo()
添加到舞台中addTo(stage, 0)
, 让页面插入到舞台的最底层位置reStart()
从新展现start()
方法end: 页面展现结束, 从父元素中remove出来, 并重置方法执行状态.
除next方法, 须要在页面内具体实现外, 其余方法均为统一处理
shouldUpdate: 监听到滚动, 执行页面内具体逻辑
在
initStage
的时候, 绑定滚动事件. 并广播全局事件.
new part
的时候, 都会累加整个页面须要的总高度, 并以此设计可以滑动的高度.当前页面滚动的位置 = 总共滚动过的高度 - 当前页面开始的高度
<0
的部分还和上一个页面重叠>0
以后, 本身彻底出现合适的时机
调用, next
, 下一个页面就能够开始<0的过程了.// 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;