首次開發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;