Treesaver 是浏览器大小尺寸敏感(size-sensitive)的,会就着当前的浏览器尺寸(browser size),选用不同的分栏表格(grid)做排版。
初始化
TreeSaver.js 框架的入口源代码在后面可以看到:https://github.com/Treesaver/treesaver/blob/master/src/init.js
这里的代码用到了Google开发的JS库:Closure Library,Closure Library的一个显著特点就是支持namespacing system(命名空间)。用过.Net和Java的对这个很熟悉。
这里init.js 文件的goog.provide('treesaver'); 就是表明以后如果你想用这个文件,你只需要引用名称空间:treesaver。goog.require('treesaver.boot');则是引用名称空间。
Closure 代码 | .net等同代码 | java等同代码 |
goog.provide('treesaver'); | namespace treesaver | package treesaver |
goog.require('treesaver.boot'); | using treesaver.boot; | import treesaver.boot; |
初始化最核心的代码在:treesaver.ui.ArticleManager.load = function(initialHTML) {}
这个函数的调用堆栈如下,调用者在前面,被调用者在后面:
https://github.com/Treesaver/treesaver/blob/master/src/init.js
treesaver.boot.load = function() {}
treesaver.boot.loadProgress_ = function() {}
treesaver.core.load = function() {}
treesaver.ui.ArticleManager.load = function(initialHTML) {}
treesaver.ui.ArticleManager.load 传入的参数是我们页面的Html代码的Body部分。这个代码在显示上最核心的几段代码我加了中文注释。
/**
* Initialize all content
* @param {?string} initialHTML
*/
treesaver.ui.ArticleManager.load = function(initialHTML) {
// Initialize state
treesaver.ui.ArticleManager.currentArticle = null;
treesaver.ui.ArticleManager.currentPosition = null;
treesaver.ui.ArticleManager.currentPageIndex = -1;
treesaver.ui.ArticleManager.currentArticleIndex = null;
treesaver.ui.ArticleManager.currentTransitionDirection = null;
treesaver.ui.ArticleManager.currentPageWidth = null;
// Data store
treesaver.ui.ArticleManager.articleOrder = [];
treesaver.ui.ArticleManager.articleMap = {};
treesaver.ui.ArticleManager.articles = {};
treesaver.ui.ArticleManager.toc = [];
/**
* @private
*/
treesaver.ui.ArticleManager.grids_ = treesaver.ui.ArticleManager.getGrids_();
if (!treesaver.ui.ArticleManager.grids_) {
treesaver.debug.error('No grids');
return false;
}
// Set up the loading & error pages
treesaver.ui.ArticleManager.initLoadingPage();
treesaver.ui.ArticleManager.initErrorPage();
treesaver.ui.ArticleManager.initialUrl = treesaver.network.stripHash(document.location.href);
treesaver.ui.ArticleManager.initialHTML = initialHTML;
// Set the display to the current article?
if (initialHTML) {
// ×××××× 开始构造显示 ××××××××××
var initialArticle = new treesaver.ui.Article(treesaver.ui.ArticleManager.initialUrl,
document.title,
treesaver.ui.ArticleManager.grids_,
initialHTML);
if (!initialArticle.error) {
// 缓存
treesaver.ui.ArticleManager.articles[treesaver.ui.ArticleManager.initialUrl] = initialArticle;
treesaver.ui.ArticleManager._setArticle(initialArticle, null, 0, true);
}
else {
treesaver.debug.warn('Error in initial article');
// Unload and show plain content
treesaver.core.unload();
}
}
else {
treesaver.debug.warn('No initial article');
// What to do here?
}
// Set up event handlers
// *********** 文章分页,下一篇文章等的事件捆绑 **********
treesaver.ui.ArticleManager.watchedEvents.forEach(function(evt) {
treesaver.events.addListener(document, evt, treesaver.ui.ArticleManager.handleEvent);
});
window['onpopstate'] = treesaver.ui.ArticleManager.onPopState;
// Download the table of contents
treesaver.ui.ArticleManager.generateTOC();
return true;
};
每次调整浏览器尺寸后
上面初始化代码中我们可以看到下面的代码:
// Set up event handlers
treesaver.ui.ArticleManager.watchedEvents.forEach(function(evt) {
treesaver.events.addListener(document, evt, treesaver.ui.ArticleManager.handleEvent);
});
treesaver.ui.ArticleManager.handleEvent 函数的实现如下:
/**
* @param {Object} e
*/
treesaver.ui.ArticleManager.handleEvent = function(e) {
if (e.type === treesaver.ui.Article.events.PAGINATIONPROGRESS) {
// We have new pages to display
// TODO
// Fire event
treesaver.events.fireEvent(document, treesaver.ui.ArticleManager.events.PAGESCHANGED);
return;
}
if (e.type === treesaver.ui.Article.events.LOADED) {
// TODO
// If it's the current article, kick off pagination?
// If it's the next, kick it off too?
// Where does size come from?
treesaver.events.fireEvent(document, treesaver.ui.ArticleManager.events.PAGESCHANGED);
return;
}
if (e.type === treesaver.ui.Article.events.LOADFAILED &&
e.article === treesaver.ui.ArticleManager.currentArticle) {
// The current article failed to load, redirect to it
treesaver.ui.ArticleManager._redirectToArticle(treesaver.ui.ArticleManager.currentArticle);
return;
}
};
TreeSaver的根控件就是 Chrome, 所以上面发出的事件会被下面代码拦截到:事件调度入口:
https://github.com/Treesaver/treesaver/blob/master/src/ui/chrome.js
这里的下面函数是所有事件的调度入口:
/**
* Event dispatcher for all events
* @param {Event} e
*/
treesaver.ui.Chrome.prototype['handleEvent'] = function(e) {
switch (e.type) {
// Both these events mean that the pages we are displaying
// (or trying to display) may have changed. Make sure to
// fetch them again
// Article changed and TOC changed will affect nav indicators
case treesaver.ui.ArticleManager.events.PAGESCHANGED:
return this.selectPagesDelayed();
case treesaver.ui.ArticleManager.events.TOCUPDATED:
this.updateTOCDelayed();
return this.selectPagesDelayed();
case treesaver.ui.ArticleManager.events.ARTICLECHANGED:
this.updateTOCActive(e);
return this.updatePageURL(e);
case 'mouseover':
return this.mouseOver(e);
case 'touchstart':
return this.touchStart(e);
case 'touchmove':
return this.touchMove(e);
case 'touchend':
return this.touchEnd(e);
case 'touchcancel':
return this.touchCancel(e);
case 'keydown':
return this.keyDown(e);
case 'click':
return this.click(e);
case 'mousewheel':
case 'DOMMouseScroll':
return this.mouseWheel(e);
}
};
标签:case,return,ArticleManager,流程,treesaver,js,ui,TreeSaver,events
From: https://blog.51cto.com/u_15588078/6535327