zoukankan      html  css  js  c++  java
  • TreeSaver.js 的工作流程逻辑

    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);
    
      }
    
    };
  • 相关阅读:
    P2617 Dynamic Rankings (动态开点权值线段树 + 树状数组)
    2019HDU多校 Round5
    2019牛客多校 Round6
    2019牛客多校 Round5
    2019HDU多校 Round4
    [转]SQLServer : EXEC和sp_executesql的区别
    无法执行 FunctionImport“entitys.xx”,因为未将它映射到存储函数。EF
    【终极解决方案】为应用程序池“XXX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误。该进程 ID 为“XXXX”。数据字段包含错误号。
    IE11 Windows7下F12 DOC资源管理器不能用Exception in window.onload: Error: An error has ocurredJSPlugin.3005
    VS2015编译错误:调用的目标发生了异常--->此实现不是Windows平台FLPS验证的加密算法的一部分。
  • 原文地址:https://www.cnblogs.com/ghj1976/p/2119729.html
Copyright © 2011-2022 走看看