首页 > 其他分享 >TreeSaver.js 的工作流程逻辑

TreeSaver.js 的工作流程逻辑

时间:2023-06-22 19:34:54浏览次数:48  
标签:case return ArticleManager 流程 treesaver js ui TreeSaver events

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

相关文章

  • Win7环境下TreeSaver编译环境的搭配
    首先你需要先搭配出”Win7环境下TreeSaver例子环境的搭配”然后才能继续下一步编译环境。例子环境搭配后,你可以在源代码目录下执行paver命令,搭配例子测试环境,也可以执行paverdebug生成带调试注释信息的treesaver脚本,当然也可以使用paverclean删除生成的文件。这些可以......
  • js中的预解析
    1.js中的声明声明就是变量的声明和函数的声明,其目的是让js解释引擎知道有什么东西.声明时不参与运算的,是不参与执行的,是在预解析阶段就完成的.变量的声明//变量的声明就是var变量名.varnum=123;//这是一个语法糖,可以理解成varnum;num=123;函数的......
  • 定义一个JS数组去重的方法
    1、思路:定义一个新数组,并存放原数组的第一个元素,然后将元素组一一和新数组的元素对比,若不同则存放在新数组中functionunique(arr){letnewArr=[arr[0]];for(leti=1;i<arr.length;i++){letrepeat=false;for(le......
  • Android系统服务 AMS 启动流程
    背景当SystemServer启动的时候,从Zygote进程fork()出SystemServer进程,经过初始化后,会通过反射调用SystemServer.java的mian()方法,其中会启动一系列系统服务。AMS就是其中的一个。一、缘起SystemServer进程SystemServer的main():/***Themainentrypointfromzygote......
  • 20230428 24. 职责链模式 - 审批流程
    介绍职责链模式(ChainofResponsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。Handler类,定义一个处理请示的接口ConcreteHandler类,具体处理者类,处理它所负责的请......
  • 【代码设计】链表结构解决多流程校验
    目的使用合理的代码设计,解决业务场景的中的实际问题。背景介绍在实际的业务场景中,用户的一个操作行为,是否允许真正被执行,往往会涉及到多流程的校验,一旦有条件不满足将会被中止。以下面流程图为例:用户点击了打赏按钮,会进行是否有网络检查,没有网络,会有网络连接弹框,等待用户连接结果......
  • 在sql中使用函数,遇到net.sf.jsqlparser.parser.ParseException异常
    异常详情如下Causedby:net.sf.jsqlparser.parser.ParseException:Encountered""->""->""atline1,column31.Wasexpectingoneof:"AS"..."DO"..."ANY"..."KEY"...……(中间省略很多符号)atnet.......
  • MYSQL8 处理JSON 我不再是豆包,我是干粮
    最近来了一个项目,本身如果用MONGODB有点大材小用,所以为了避免某些表继续使用text字段来处理JSON数据的方式,让技术水平上一个档次,并且公司也不在上MYSQL5.7的新项目,全部是8.018这个版本。继续上一篇文字,那就看看MYSQL8的野心到底是如何展现的。顺便研究完,给开发一个靠谱的方案,......
  • Mongodb GeoJSON 地理数据处理 其实我也很厉害
    相信如果提起地理数据的处理,首先想起的数据库就是postgis,对大名鼎鼎的postgresql + 插件的方式来将POSTGRESQL变成纯纯的地理数据处理的数据库,这是人尽皆知和童叟无欺的功能。 那么世界上如果我不想使用POSTGRESQL的 postgis来处理我的地理数据以外的选择,那么NO.2的选择......
  • Python | import json模块详解
    json是Python内置的一个用于处理JSON数据的模块。JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,常用于Web应用程序之间的数据传输。json模块提供了四个主要的方法:json.dumps()-将Python对象转换为JSON格式的字符串。json.loads()-将JSON格式的字符串转换为Py......