We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
本文写于2016.12.25,当时实习公司要实现手动返回,故看源码寻找解决方案
SUI-mobile基于Framework7实现的,这一点从Router模块与其他模块的封装方式可以看得出来。
Picker模块
var Picker = function(params) { var p = this; var defaults={ //基本设置 } p.setValue = function(arrValues, transition) { // setValue 代码块 } }
以Picker模块为例,所有的封装都基于this来实现,其他模块类似
Router模块
var EVENTS = { // 事件名称 } // 一些获取路径以及检测函数 var Util = { getUrlFragment: function(url) { // getUrlFragment 代码块 }, // 以下类似 } // Router 的构造函数 var Router = function(){} // 通过prototype来进行Router封装 Router.prototype._init = function () {} // 以下雷同_
Router 的封装是通过prototype,最后通过
var router = $.router =new Router();
绑定在了zepto上
在这,先讲的是在SUI中,返回和前进的实现。 在Router构造函数中,有一段代码
window.addEventListener('popstate', this._onPopState.bind(this));
在这句代码中,注册了一个popstate事件,SUI的回退和前进都是基于这个实现的
popstate
在讲popstate,先来说明下返回和前进按钮,它其实是简单封装了history.back和history.go,并没有什么特殊。
返回
前进
history.back
history.go
但是在触发history.back和history.go的时候,就会触发popstate事件
Router.prototype._onPopState = function(event) { var state = event.state; //代码忽略 if (state.id < lastState.id) { this._back(state, lastState); } else { this._forward(state, lastState); } }
在popstate触发的_onPopState方法里,有一个event的回调,如果你进入一个页面在按返回触发这个方法然后log出来,是这样的
_onPopState
{ id:3, pageId:"page-home", url: [obj]// 存储各种路径 }
那么这些数据是怎么来的呢,就是不管是内嵌页面切换还是外链页面切换都会进入一个_pushNewState
_pushNewState
Router.prototype._pushNewState = function(url, sectionId) { var state = { id: this._getNextStateId(), pageId: sectionId, url: Util.toUrlObject(url) }; theHistory.pushState(state, '', url); this._saveAsCurrentState(state); this._incMaxStateId(); };
通过theHistory.pushState(state, '', url);即window.history.pushState把信息存入state,这个state的信息只有在触发history.back和history.go才会从回调中取得。
theHistory.pushState(state, '', url);
window.history.pushState
在SUI中,规定要把页面放在page-group类下。 在点击外链的时候,跳入_switchToDocument,会触发Ajax,获取链接页面,并取得其中的page-group类的内容,然后跳入_doSwitchDocument渲染在新的页面,刷新href,然后pushState。 因此,其实整个的“跳转”并不是传统意义上的跳转页面,只是同个页面Ajax请求后刷新的假象。
page-group
_switchToDocument
_doSwitchDocument
pushState
点击链接后,跳入Router.prototype.load,并传入url
Router.prototype.load
Router.prototype.load = function(url, ignoreCache, $link) { // 默认使用缓存 if (ignoreCache === undefined) { ignoreCache = false; } // 检查base url是否相同,相同则锚点切换, 否则 Ajax 切换 if (this._isTheSameDocument(location.href, url)) { this._switchToSection(Util.getUrlFragment(url), $link); } else { // 在外链切换,多了这么一项动作,是存储当前的页面和地址 this._saveDocumentIntoCache($(document), location.href); this._switchToDocument(url, ignoreCache); } };
_saveDocumentIntoCache
Router.prototype._saveDocumentIntoCache = function(doc, url) { // 代码忽略 this.cache[urlAsKey] = { $doc: $doc, $content: $doc.find('.' + routerConfig.sectionGroupClass) }; }
在这里,点击外链的时候,把整个旧页面存入了$.router.cache中,在返回的时候就会调用里面的dom渲染旧页面。这一点加上SUI对于页面回退的实现方法,是整个滑动返回实现的难点所在。
$.router.cache
加载完页面紧接着是获取当前页面$currentDoc为然后渲染新页面为$newDoc,接着进入_animateDocument。 如果是返回的话,$newDoc则在$.router.cache中获取,然后渲染为$newDoc
_animateDocument
// 四个参数为 当前页面,新页面,可见块,切换方向 this._animateDocument($currentDoc, $newDoc, $visibleSection, direction);
内嵌页面切换
内嵌页面的切换就没有那么多的步骤,只是获取id拿到那段section渲染为newPage,当前页面为currentPage然后传入_animateSection接着再传入_animateElement做class切换就结束了。
newPage
currentPage
_animateSection
_animateElement
back&&forward
在上面所述的back和forward,其实动画的实现方式也是一样,只是多了一层判断是否为外链之间的切换,其他的也是通过渲染成newPage和currentPage作为参数传入_animateSection或者_animateDocument处理就能形成切换了。
之前见过Framework7的滑动返回,它都是基于内嵌页面的层叠关系来实现的,并且没有路由跳转,单纯在本页面的切换。 在SUI中,想要实现滑动返回需要解决的最大的是路由和state。基于SUI做的话,除了解决CSS方面的问题,还有保留路由和state去实现的话,暂时还没有想到很好的办法。
路由
state
The text was updated successfully, but these errors were encountered:
No branches or pull requests
SUI-mobile Router浅析
封装方式
SUI-mobile基于Framework7实现的,这一点从Router模块与其他模块的封装方式可以看得出来。
Picker模块
以Picker模块为例,所有的封装都基于this来实现,其他模块类似
Router模块
Router 的封装是通过prototype,最后通过
绑定在了zepto上
返回和前进的实现(重点)
在这,先讲的是在SUI中,返回和前进的实现。
在Router构造函数中,有一段代码
在这句代码中,注册了一个
popstate
事件,SUI的回退和前进都是基于这个实现的在讲
popstate
,先来说明下返回
和前进
按钮,它其实是简单封装了history.back
和history.go
,并没有什么特殊。但是在触发
history.back
和history.go
的时候,就会触发popstate
事件在
popstate
触发的_onPopState
方法里,有一个event的回调,如果你进入一个页面在按返回触发这个方法然后log出来,是这样的那么这些数据是怎么来的呢,就是不管是内嵌页面切换还是外链页面切换都会进入一个
_pushNewState
通过
theHistory.pushState(state, '', url);
即window.history.pushState
把信息存入state,这个state的信息只有在触发history.back
和history.go
才会从回调中取得。内嵌页面和外链页面的实现与区别
在SUI中,规定要把页面放在
page-group
类下。在点击外链的时候,跳入
_switchToDocument
,会触发Ajax,获取链接页面,并取得其中的page-group
类的内容,然后跳入_doSwitchDocument
渲染在新的页面,刷新href,然后pushState
。因此,其实整个的“跳转”并不是传统意义上的跳转页面,只是同个页面Ajax请求后刷新的假象。
点击链接后,跳入
Router.prototype.load
,并传入urlRouter.prototype.load
_saveDocumentIntoCache
在这里,点击外链的时候,把整个旧页面存入了
$.router.cache
中,在返回的时候就会调用里面的dom渲染旧页面。这一点加上SUI对于页面回退的实现方法,是整个滑动返回实现的难点所在。加载完页面紧接着是获取当前页面$currentDoc为然后渲染新页面为$newDoc,接着进入
_animateDocument
。如果是返回的话,$newDoc则在
$.router.cache
中获取,然后渲染为$newDoc内嵌页面切换
内嵌页面的切换就没有那么多的步骤,只是获取id拿到那段section渲染为
newPage
,当前页面为currentPage
然后传入_animateSection
接着再传入_animateElement
做class切换就结束了。back&&forward
在上面所述的back和forward,其实动画的实现方式也是一样,只是多了一层判断是否为外链之间的切换,其他的也是通过渲染成
newPage
和currentPage
作为参数传入_animateSection
或者_animateDocument
处理就能形成切换了。滑动返回实现评估
之前见过Framework7的滑动返回,它都是基于内嵌页面的层叠关系来实现的,并且没有路由跳转,单纯在本页面的切换。
在SUI中,想要实现滑动返回需要解决的最大的是
路由
和state
。基于SUI做的话,除了解决CSS方面的问题,还有保留路由
和state
去实现的话,暂时还没有想到很好的办法。The text was updated successfully, but these errors were encountered: