outline.js - 自动生成文章导读(Table of Contents)导航的 JavaScript 工具。会自动分析文章中的标题( h1~h6 )标签,并生成文章段落层次结构的导读导航菜单。
创作灵感
AnchorJS 是 outline.js 的创作灵感来源。既然 AnchorJS 可创建标题的链接,为什么不直接给文章生成一个文章导读(Table of Contents)导航呢? 于是就有了outline.js。
特点(Features)
- 原生 JavaScript 编写,无需任何依赖;
- 支持 UMD 规范;
- 支持 E6 模块,提供功能独立的 ES6 模块;
- Anchors 模块:类似 AnchorJS 基础功能模块,自动分析段落层级;
- Drawer 模块:独立的侧滑窗口模块;
- Navigator 模块:独立的导航菜单模块;
- Toolbar 模块:独立的固定定位的工具栏模块;
- 拥有 AnchorJS 基础功能;
- 支持中文和英文标题文字生成ID;
- 支持生成独立的侧边栏导航菜单;
- 支持直接在文章中生成文章导读导航;
- 自动分析标题关系,生成段落层级索引值;
- 可以作为 jQuery 插件使用;
- 界面简洁大方;
- 配置灵活,丰富,让你随心所欲掌控 outline.js;
安装说明
outline.js 提供多种安装方式的支持: npm 安装、加载 CDN 资源、以及本地资源调用。
npm install
$ npm install -S @yaohaixiao/outline.js
CDN 调用
<script src="https://cdn.jsdelivr.net/gh/yaohaixiao/outline.js/outline.min.js"></script>
调用本地JS文件
<script src="path/to/outline.min.js"></script>
使用说明
outline.js 既支持在 node.js 环境中以 CommonJS 模块调用,也支持 ES6 模块方式加载。
// Node.js 环境中使用
const Outline = require('@yaohaixiao/outline.js')
// 作为 ES6 模块使用
import Outline from '@yaohaixiao/outline.js/src/outline'
// 调用其他独立模块
import Anchors from '@yaohaixiao/outline.js/src/anchors'
import Navigator from '@yaohaixiao/outline.js/src/navigator'
import Drawer from '@yaohaixiao/outline.js/src/drawer'
import Toolbar from '@yaohaixiao/outline.js/src/toolbar'
import Reader form '@yaohaixiao/outline.js/src/reader'
// 创建 Outline 实例
// 2.0.0 调整了配置参数,配置更加简单
const outline = new Outline({
// 文章显示区域的 DOM 元素或者选择器字符串
articleElement: '#article',
// 要收集的标题选择器
selector: 'h2,h3,h4,h5,h6',
// 负责文章区域滚动的元素
// String 类型 - 选择器字符串,默认值:html,body(window窗口)
// HTMLElement 类型 - DOM 元素
scrollElement: 'html,body',
// 文章导读菜单的位置
// relative - (默认值)创建独立的侧滑菜单
// sticky - 导航菜单将以 sticky 模式布局(需要确保菜单插入位置支持 sticky 模式布局)
// fixed - 导航菜单将以 fixed 模式布局,会自动监听滚动位置,模拟 sticky 布局
// sticky 和 fixed 布局时,需要设置 parentElement
// 2.0.0 暂时不支持在文章开始位置插入 chapters 导航菜单
position: 'sticky',
// 设置 position: relative 时,placment 定义侧滑菜单和 toolbar 导航位置:
// rtl - 菜单位置在窗口右侧,滑动动画为:right to left
// ltr - 菜单位置在窗口左侧,滑动动画为:left to right
// ttb - 菜单位置在窗口上方,滑动动画为:top to bottom
// btt - 菜单位置在窗口下方,滑动动画为:bottom to top
placement: '',
// 导航菜单将要插入的位置(DOM 元素)
// String 类型 - 选择器字符串
// HTMLElement 类型 - 插入的 DOM 元素
// 仅在 position 设置为 sticky 和 fixed 布局时有效
parentElement: '#aside',
// 是否显示段落章节编号
showCode: true,
// 标题图标链接的 URL 地址
// (默认)没有设置定制,点击链接页面滚动到标题位置
// 设置了链接地址,则不会滚动定位
anchorURL: '',
// DIYer的福利
// 独立侧滑菜单时,customClass 会追加到 drawer 侧滑窗口组件
// 在文章中显示导航菜单时,customClass 会追加到 chapters 导航菜单
customClass
});
// 可以在创建导航后,重置配置信息,重新生成新的导航
Outline.reload({
// 调整位直接在文章内生成导航
position: 'sticky',
articleElement: '#article'
})
Options
outline.js 有者丰富的配置选项,以便适应不同的展示方式。
articleElement
Description
- Type:
- String|HTMLElement
- Default:
- '#article'
- String:选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement:'DOM 元素;
可选,用来指定页面中显示文章正文的 DOM 节点或者选择器字符串。
// Default Selector
const outline = new Outline(Outline.DEFAULTS)
// Customize Selector
const outline = new Outline({
articleElement: $('#main')
})
selector
Description
- Type:
- String
- Default:
- 'h1,h2,h3,h4,h5,h6'
可选,用来指定 article 节点下,要生成导航的标题标签的选择器。
// Default selector
new Outline(Outline.DEFAULTS)
// Customize selector
new Outline({
selector: 'h2'
})
title
Description
- Type:
- String|Boolean
- Default:
- '目录'
可选,用来指定文章导读导航菜单的标题文字。设置空字符串或者 false,则不显示标题。在插入导航菜单的 DOM 元素已有标题时,可以设置 title: '' 或者 false。
说明:本 API 文档的导航菜单便是使用 outline.js 生成,并且没有设置 title。
(function(){
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = ''
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
outline = new Outline(Outline.DEFAULTS)
})()
scrollElement
Description
- Type:
- String|HTMLElement
- Default:
- 'html,body'
- String: 选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement: DOM 元素;
可选,负责文章区域滚动的元素:
// 默认是当前窗口滚动
new Outline(Outline.DEFAULTS)
// 指定滚动区域是 #main 元素
new Outline({
scrollElement: '#main'
})
position
Description
- Type:
- String
- Default:
- 'relative'
可选,用来指定文章导读导航菜单的显示位置:
- relative: (默认值)创建独立的侧滑菜单;
- sticky: 导航菜单将以 sticky 模式布局(需要确保菜单插入位置(DOM 节点)支持 sticky 模式布局);
- fixed: 导航菜单将模拟 sticky 布局,起初是普通定位,会自动监听滚动位置,但滚动到导航菜单顶部时,以 fixed 模式布局,模拟 sticky 布局效果;
当设置为 sticky 和 fixed 布局时,需要设置 parentElement。
注意:2.0.0 暂时不支持之前版本那种 inside 模式,不会自动在文章开始位置插入 chapters 导航菜单
// 默认生成独立的侧滑弹窗导航菜单
new Outline(Outline.DEFAULTS)
// 在页面内部插入导航菜单
new Outline({
// 在(文章的)侧边栏显示导航菜单
parentElement: '#aside',
// 或者 sticky 定位
position: 'fixed'
})
parentElement
Description
- Type:
- String
- Default:
- '#aside'
- String: 选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement: DOM 元素;
可选,导航菜单将要插入的位置(DOM 元素)。仅在 position 设置为 sticky 和 fixed 布局时有效。
// 在页面内部插入导航菜单
new Outline({
// 在(文章的)侧边栏显示导航菜单
parentElement: '#aside',
// 或者 sticky 定位
position: 'fixed'
})
placement
Description
- Type:
- String
- Default:
- 'rtl'
可选,设置 position: relative 时,placement 定义侧滑菜单和 toolbar 导航位置:
- rtl - 菜单位置在窗口右侧,滑动动画为:right to left(默认值);
- ltr - 菜单位置在窗口左侧,滑动动画为:left to right;
- ttb - 菜单位置在窗口上方,滑动动画为:top to bottom;
- btt - 菜单位置在窗口下方,滑动动画为:bottom to top;
// 默认是在窗口右侧显示侧滑导航菜单
new Outline(Outline.DEFAULTS)
// 调整为在窗口右侧显示侧滑导航菜单
new Outline({
placement: 'ltr'
})
stickyHeight
Description
- Type:
- Number
- Default:
- 0
可选,用来指定页面中其它 sticky 或者模拟 skicky 的 fiexed 定位的 DOM 元素的高度。
这些 sticky 元素脱离了正常的流布局后,原来 h1~h6 标题标签的 offsetTop 计算会出现偏差。sticky 元素会遮挡标题,因此针对页面中有其它sticky 节点时,需要设置 stickyHeight 高度。以便 outline.js 根据 stickyHeight 和计算出的标题的 offsetTop 值重新计算滚动定位。
说明:outline.js 主要用于文章详情页面,stickyHeight 仅针对 top: 0,且 sticky 定位元素在文章内容区域上方的位置;
const defaults = Outline.DEFAULTS
// 设置 stickyHeight(outline.js 的示例页面的主标题元素的高度)
defaults.stickyHeight = 86
// 默认生成独立的侧滑弹窗导航菜单
new Outline(defaults)
showCode
Description
- Type:
- Boolean
- Default:
- true
可选,是否显示段落章节编号(注意:3.38.2 开始 showCode 默认为 false):
- false - 显示编号;
- false - 不显示编号(默认值);
animationCurrent
Description
- Type:
- Boolean
- Default:
- true
可选,是否采用动画定位高亮当前的章节标题:
- true - 采用动画定位高亮(默认值);
- false - 采用高亮当前章节标题的链接文字并加粗文字;
hasToolbar
Description
- Type:
- Boolean
- Default:
- true
可选,是否显示侧边的按钮工具栏:
- true - 显示按钮工具栏(默认值);
- false - 不显示按钮工具栏;
closeOnClickModal
Description
- Type:
- Boolean
- Default:
- true
可选,点击空白处(非独立导航菜单),收起导航菜单:
- true - 点击空白处,收起菜单(默认值);
- false - 点击空白处,不收起菜单;
showNavModalFirst
Description
- Type:
- Boolean
- Default:
- false
可选,有独立导航菜单时,是否默认显示菜单:
- false - 默认先显示按钮工具栏(默认值);
- true - 默认先显示独立导航菜单弹窗;
anchorURL
Description
- Type:
- String
- Default:
- ''
可选,用来指定文章标题锚点链接图标的链接地址:
// Default URL - 默认链接,点击图标,页面会滚动到当前标题位置
new Outline()
// Customize URL - 直接打开链接了
new Outline({
anchorURL: 'http://www.yaohaixiao.com/'
})
homepage
Description
- Type:
- String
- Default:
- ''
可选,用来指定文章标题锚点链接图标的链接地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 Homepage 图标的按钮
outline.reload({
homepage: 'http://www.yaohaixiao.com/'
})
git
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 git 图标的按钮
outline.reload({
git: 'https://github.com/yaohaixiao/outline.js'
})
tags
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库 tags 页面地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 tags 图标的按钮
outline.reload({
tags: 'https://github.com/yaohaixiao/outline.js/tags'
})
issues
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库 issues 页面地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 issues 图标的按钮
outline.reload({
issues: 'https://github.com/yaohaixiao/outline.js/issues'
})
tools
Description
- Type:
- Array
- Default:
- []
可选,自定义的按钮配置项。tools 中的按钮会排列显示在 homepage, git, tags, issues 等按钮之后。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
// 侧边栏的 Toolbar 会多出一个 git 图标的按钮
outline.reload({
git: 'https://github.com/yaohaixiao/outline.js',
tools: [
{
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
}
]
})
reader
Since
3.32.0
说明:3.32.0 以前的版本,此属性的原名为 print,另外,reader.element 属性也调整为了 reader.target。请升级后在初始化配置参数时注意调整。
Description
- Type:
- Object
- Default:
- {target: '', title: '', enterReadingTip: ‘进入阅读模式,按 ESC 键可退出阅读模式’, allowSpeak: false}
可选,自定义的是否自动为文章页面创建打印样式。
- target:
- (必须)要打印的文章区域,DOM 元素或者选择器字符串;
- title:
- (可选)要打印的文章标题。如果 element 区域有 h1 标签则无需设置。可以直接设置标题文本,也可以是文章页的主标题 DOM 元素;
- enterReadingTip:
- (可选)进入阅读模式的提示文本,默认值:‘进入阅读模式,按 ESC 键可退出阅读模式’;
- allowSpeak:
- (可选)针对现代浏览器支持 Web Speech API,是否开启语音阅读功能。默认值:false;
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式',
// 开启语音阅读
allowSpeak: true
}
outline = new Outline(defaults)
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
customClass
Description
- Type:
- String
- Default:
- ''
可选,(DIYer福利)设置自定义样式的 class 名称:
- '' - 采用默认 outline.js 的 UI 界面(默认值);
- 设置自定义样式 - 自己根据需求设置个性化的 UI 界面;
// Default UI
new Outline(Outline.DEFAULTS)
// Customized
new Outline({
// 设置深色配置界面
customClass: 'theme-dark'
})
afterScroll
Description
- Type:
- Function
- Default:
- null
可选,当点击导航菜单、文章中的 anchor 图标(#)或者上下滚动按钮会触发滚动,afterScroll() 回调函数会在滚动结束后触发执行。
Parameters
target
- Type:
- String
afterScroll() 回调函数有一个参数 target,返回的是当前点击的 DOM 元素的名称:
- 'anchor':表示点击的是 anchor 图标,即文章中标题前的 “#” 图标,此时的 this 上下文指向 outline.anchors;
- 'chapter':表示点击的是导航菜单的链接,此时的 this 上下文指向 outline.chapters;
- 'up':表示点击的是工具栏的向上按钮,此时的 this 上下文指向 outline.toolbar;
- 'down':表示点击的是工具栏的向下按钮,此时的 this 上下文指向 outline.toolbar;
注意:因为配置 afterScroll 回调函数会因为 4 个不同的 DOM 触发,所以需要根据 target 返回的值和此时的 this 指向判断处理。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterScroll = function(target) {
// 当然,如果你希望无论是点击什么都执行,就不需要判断了
// 直接些通用的滚动结束的逻辑即可
switch(target){
case 'anchor':
// 针对点击 # 的处理逻辑
break
case 'chapter':
// 针对点击导航菜单的处理逻辑
break
case 'up':
// 针对点击向上滚动按钮的处理逻辑
break
case 'down':
// 针对点击向下滚动按钮的处理逻辑
break
}
}
outline = new Outline(Outline.DEFAULTS)
afterSticky
Description
- Type:
- Function
- Default:
- null
可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。
说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。
Parameters
closed
- Type:
- Boolean
closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态
isSticky
- Type:
- Boolean
isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。
const $header = document.querySelector('#header')
const HEADER_STICKY = 'header_sticky'
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterSticky = function(closed, isStickying) {
const $nav = this.$el
const BORDER_RIGHT = 'utils-border-right'
if (closed) {
return false
}
if (isStickying) {
$nav.classList.add(BORDER_RIGHT)
$header.classList.add(HEADER_STICKY)
} else {
$nav.classList.remove(BORDER_RIGHT)
$header.classList.remove(HEADER_STICKY)
}
}
defaults.afterToggle = function(closed, isStickying) {
if (!isStickying) {
return false
}
if (closed) {
$header.classList.remove(HEADER_STICKY)
} else {
$header.classList.add(HEADER_STICKY)
}
}
outline = new Outline(Outline.DEFAULTS)
afterToggle
Description
- Type:
- Function
- Default:
- null
可选,当导航菜单隐藏或者显示的时候,会触发执行 afterToggle 回调函数。
说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。
Parameters
closed
- Type:
- Boolean
closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态
isSticky
- Type:
- Boolean
isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。
const $header = document.querySelector('#header')
const HEADER_STICKY = 'header_sticky'
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterSticky = function(closed, isStickying) {
const $nav = this.$el
const BORDER_RIGHT = 'utils-border-right'
if (closed) {
return false
}
if (isStickying) {
$nav.classList.add(BORDER_RIGHT)
$header.classList.add(HEADER_STICKY)
} else {
$nav.classList.remove(BORDER_RIGHT)
$header.classList.remove(HEADER_STICKY)
}
}
defaults.afterToggle = function(closed, isStickying) {
if (!isStickying) {
return false
}
if (closed) {
$header.classList.remove(HEADER_STICKY)
} else {
$header.classList.add(HEADER_STICKY)
}
}
outline = new Outline(Outline.DEFAULTS)
chapterTextFilter
Description
- Type:
- Function
- Default:
- null
可选,API 文档中,正文的方法会添加参数等信息,例如:getChapters(headings, showCode, chapterTextFilter)。而在 chapters 导航菜单,我希望显示为 getChapters(),这时我们就可以借助 chapterTextFilter 回调函数。对原始的文本进行过滤,返回我们期望的 getChapters() 文本。
Parameters
text
- Type:
- String
chapterTextFilter() 回调函数有一个参数 text,返回的是当前 hx 标题中的文本。
Returns
- Type:
- String
返回最终希望生成的标题文本内容。
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = false
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
defaults.chapterTextFilter = (text) => {
return text.replace(/\(.*?\)/, '()')
}
outline = new Outline(defaults)
anchorLinkFilter
Description
- Type:
- Function
- Default:
- null
可选,API 文档中,正文标题的锚点链接地址生成函数。
Parameters
tag
- Type:
- String
当前标题的 tagName。小写的:h1~6。
title
- Type:
- String
当前标题的文本内容。
id
- Type:
- Number
outline.js 为当前标题生成 id 号。
Returns
- Type:
- String
返回最终希望生成锚点链接的文本内容。
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = false
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
defaults.chapterTextFilter = (text) => {
return text.replace(/\(.*?\)/, '()')
}
defaults.anchorLinkFilter = (tag, title, id) => {
return `${tag}-${title}-${id}`
}
outline = new Outline(defaults)
Properties
outline.js 重构后,对外放 4 个重要的属性:anchors、drawer、chapters、reader 和 toolbar。它们都是独立的对象实例,提供了 outline.js 所有的能力(属性和方法)。
attrs
Description
- Type:
- Object
存储的是 Outline 对象当前使用中的配置选项:
说明:建议使用 attr(prop) 方法来获取属性,避免直接调用属性。
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 查看全部配置信息
outline.attrs
$article
Since
3.32.0
Description
- Type:
- HTMLElement
存储的是 Outline 对象要分析的文章正文内容显示区域的 DOM 元素:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 获取文章正文内容显示区域的 DOM 元素
outline.$article
$scrollElement
Since
3.34.0
Description
- Type:
- HTMLElement
存储的是 Outline 对象要分析的控制文章内容滚动的 DOM 元素:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 获取文章正文内容显示区域的 DOM 元素
outline.$scrollElement
buttons
Description
- Type:
- Array
存储的是 Outline 对象当前工具栏的完整的按钮配置信息:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 查看全部按钮配置信息
outline.buttons
anchors
Description
- Type:
- Object
Anchors 模块:类似 AnchorJS 基础功能模块,自动分析段落层级。
// 仅展示 API 中对外公开的方法和属性
class Anchors extends Base {
constructor(options) {
super()
this.attrs = Anchors.DEFAULTS
this.$articleElement = null
this.$scrollElement = null
this.$headings = []
this.chapters = []
// 省略其它逻辑...
}
getChapters(isTreeStructured = false) {
const chapters = this.chapters
return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters
}
count() {
return this.chapters.length
}
attr(prop, value) {
const attrs = this.attrs
if (isString(prop)) {
// 只能扩展 attrs 中已有的属性
if (value && hasOwn(attrs, prop)) {
// 更新单个配置信息
attrs[prop] = value
return this
}
// 只传递 prop 参数,则返回对应的属性值
return attrs[prop]
} else if (isObject(prop)) {
// 批量更新配置信息
extend(attrs, prop)
return this
} else if (arguments.length === 0) {
// 不传递参数,直接返回整个
return attrs
}
return this
}
render() {
// 省略其它逻辑...
return this
}
scrollTo(top, after) {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Anchors.DEFAULTS = {
scrollElement: 'html,body',
articleElement: '#article',
selector: 'h1,h2,h3,h4,h5,h6',
anchorURL: '',
hasAnchor: true,
isAtStart: true,
showCode: false,
created: null,
mounted: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Anchors
navigator
Description
- Type:
- Object
Navigator 模块:独立的导航菜单模块;
// 仅展示 API 中对外公开的方法和属性
class Navigator extends Base {
constructor(options) {
super()
this.attrs = Navigator.DEFAULTS
this.$el = null
this.$title = null
this.$main = null
this.$list = null
this.$placeholder = null
this.$parentElement = null
this.$scrollElement = null
this.chapters = []
this.closed = false
this.active = 0
this.offsetTop = 0
this.$active = null
this.timer = null
this.playing = false
// 省略其它逻辑...
}
isClosed() {
return this.closed
}
isSticky() {
const position = this.attr('position')
return position === 'sticky'
}
isFixed() {
const position = this.attr('position')
return position === 'fixed'
}
isInside() {
return this.isFixed() || this.isSticky()
}
isOutside() {
return !this.isInside()
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
highlight(id) {
// 省略其它逻辑...
return this
}
sticky() {
// 省略其它逻辑...
return this
}
scrollTo(top, after) {
// 省略其它逻辑...
return this
}
show() {
// 省略其它逻辑...
return this
}
hide() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Navigator.DEFAULTS = {
parentElement: '',
scrollElement: '',
selector: '',
active: 0,
closed: false,
showCode: true,
position: 'relative',
chapters: [],
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Navigator
drawer
Description
- Type:
- Object
Drawer 模块:独立的侧滑窗口模块。
// 仅展示 API 中对外公开的方法和属性
class Drawer extends Base {
constructor(options) {
super()
this.attrs = Drawer.DEFAULTS
this.title = ''
this.closed = true
this.$el = null
this.$modal = null
this.$header = null
this.$title = null
this.$close = null
this.$main = null
this.$footer = null
this.$overlay = null
this.zIndex = 0
// 省略其它逻辑...
}
isClosed() {
return this.closed
}
setTitle() {
this.attr('title', title)
this.title = title
this.$title.innerHTML = title
return this
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
open() {
// 省略其它逻辑...
return this
}
close() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Drawer.DEFAULTS = {
placement: 'rtl',
title: '标题',
size: 'regular',
hasClose: true,
hasOverlay: true,
hasOffset: false,
hasPadding: true,
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Drawer
reader
Description
- Type:
- Object
Reader 模块:独立的阅读视图模块。
// 仅展示 API 中对外公开的方法和属性
class Drawer extends Base {
constructor(options) {
super()
this.attrs = cloneDeep(Reader.DEFAULTS)
this.reading = false
this.$target = null
this.$paper = null
this.$title = null
this.$article = null
this.$icon = null
// 省略其它逻辑...
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
refresh() {
// 省略其它逻辑...
return this
}
enter() {
// 省略其它逻辑...
return this
}
exit() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
print() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Reader.DEFAULTS = {
target: '',
title: '标题',
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
export default Reader
toolbar
Description
- Type:
- Object
Toolbar 模块:独立的固定定位的工具栏模块;
// 仅展示 API 中对外公开的方法和属性
class Toolbar extends Base {
constructor(options) {
super()
this.attrs = Drawer.DEFAULTS
this.title = ''
this.closed = true
this.$el = null
this.$modal = null
this.$header = null
this.$title = null
this.$close = null
this.$main = null
this.$footer = null
this.$overlay = null
// 省略其它逻辑...
}
isDisabled(name) {
const buttons = this.attr('buttons')
let button
if (name) {
button = buttons.find((option) => option.name === name)
return !!(button && button.disabled)
}
return this.disabled
}
isClosed() {
return this.closed
}
highlight() {
// 省略其它逻辑...
return this
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
add(button) {
// 省略其它逻辑...
return this
}
remove(name) {
// 省略其它逻辑...
return this
}
switch(name, enabled) {
// 省略其它逻辑...
return this
}
enable(name) {
// 省略其它逻辑...
return this
}
disable(name) {
// 省略其它逻辑...
return this
}
show() {
// 省略其它逻辑...
return this
}
hide() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Toolbar.DEFAULTS = {
placement: 'ltr',
closed: false,
disabled: false,
buttons: [],
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterDisabled: null,
afterEnabled: null,
beforeDestroy: null,
afterDestroy: null
}
Drawer.zIndex = 2000
export default Toolbar
Outline.DEFAULTS
Description
- Type:
- Object
静态属性,存储的是 Outline 对象默认配置选项:
Outline.DEFAULTS = {
// 文章显示区域的 DOM 元素或者选择器字符串
articleElement: '#article',
// 要收集的标题选择器
selector: 'h2,h3,h4,h5,h6',
// 指定文章导读导航菜单的标题文字。
// 设置空字符串或者 false,则不显示标题
// 在插入导航菜单的 DOM 元素已有标题时,可以设置 title: '' 或者 false
title: '目录',
// 负责文章区域滚动的元素
// String 类型 - 选择器字符串,默认值:html,body(window窗口)
// HTMLElement 类型 - DOM 元素
// 注意:如果您使用的是比较旧的 chrome 浏览器,例如:Chromium 60.x 版本或者以下版本
// 请手动设置 scrollElement = 'body',否则点击导航无法滚动定位
scrollElement: 'html,body',
// 文章导读菜单的位置
// relative - (默认值)创建独立的侧滑菜单
// sticky - 导航菜单将以 sticky 模式布局(需要确保菜单插入位置支持 sticky 模式布局)
// fixed - 导航菜单将以 fixed 模式布局,会自动监听滚动位置,模拟 sticky 布局
// sticky 和 fixed 布局时,需要设置 parentElement
// 2.0.0 暂时不支持之前版本那种 inside 模式,不会自动在文章开始位置插入 chapters 导航菜单
position: 'sticky',
// 导航菜单将要插入的位置(DOM 元素)
// String 类型 - 选择器字符串
// HTMLElement 类型 - 插入的 DOM 元素
// 仅在 position 设置为 sticky 和 fixed 布局时有效
parentElement: '#aside',
// 设置 position: relative 时,placment 定义侧滑菜单和 toolbar 导航位置:
// rtl - 菜单位置在窗口右侧,滑动动画为:right to left
// ltr - 菜单位置在窗口左侧,滑动动画为:left to right
// ttb - 菜单位置在窗口上方,滑动动画为:top to bottom
// btt - 菜单位置在窗口下方,滑动动画为:bottom to top
placement: 'rtl',
// 页面中其它 sticky 或者模拟 skicky 的 fiexed 定位的 DOM 元素的高度。例如 wordpress 系统中,
// 就会有 sticky 定位的导航菜单。这些 sticky 元素脱离了正常的流布局后,原来 h1~h6 标题标签的
// offsetTop 计算会出现偏差。sticky 元素会遮挡标题,因此针对页面中有其它 sticky 元素会遮挡标题,
// 因此针对 sticky 布局时,需要设置 stickyHeight 高度。outline.js 会根据 stickyHeight 和计
// 算出的标题的 offsetTop 值重新计算滚动定位;
// 说明:outline.js 主要用于文章详情页面,
// 因此 stickyHeight 仅针对 top: 0,且 sticky 定位元素在文章内容区域上方的位置;
stickyHeight: 0,
// 是否显示标题编号(注意:3.38.2 开始 showCode 默认为 false)
showCode: false,
// 是否显示侧边的按钮工具栏
hasToolbar: true,
// 指定是否采用动画定位高亮当前的章节标题,默认值:true
// 当值为 false 时,则采用高亮当前章节标题的链接文字并加粗文字
// 如果喜欢更简洁的高亮效果,可以选择设置为 false
animationCurrent: true,
// 标题图标链接的 URL 地址
// (默认)没有设置定制,点击链接页面滚动到标题位置
// 设置了链接地址,则不会滚动定位
anchorURL: '',
// 指定当前站点主页地址
homepage: '',
// 指定git仓库地址
git: '',
// 指定git仓库中的 tags 地址
tags: '',
// 指定git仓库中的 issues 地址
issues: '',
// 自定义按钮配置
tools: [],
// 为文章页添加基础的打印样式
// 如果您的页面已经有打印样式,就无需设置了
reader: {
//(必须)要打印的文章区域,DOM 元素或者选择器字符串。
target: '',
// (可选)要打印的文章标题。如果 element 区域有 h1 标签则无需设置。
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素
title: '',
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
},
// DIYer的福利
// 独立侧滑菜单时,customClass 会追加到 drawer 侧滑窗口组件
// 在文章中显示导航菜单时,customClass 会追加到 chapters 导航菜单
customClass,
// position: fixed,当导航菜单样式进入 fixed 定位后,触发的回调函数
afterSticky: null,
// 当导航菜单隐藏或者显示后,触发的回调函数
afterToggle: null,
// 当点击上下滚动按钮,导航菜单或者文章中的 # 图标,滚动结束后触发的回调函数
afterScroll: null,
// 文档的标题文本过滤回调函数
// API 文档中,正文的方法会添加参数等信息,例如:getChapters(headings, showCode, chapterTextFilter)
// 而在 chapters 导航菜单,我希望显示为 getChapters(),这时我们就可以借助 chapterTextFilter 回调函数
// 对原始的文本进行过滤,返回我们期望的 getChapters() 文本
chapterTextFilter: null,
// 锚点链接的生成回调函数
// anchorLinkFilter(tag, title, id)
// tag - 当前标题的 tagName 小写:h1~6
// title - 当前标题的文本内容
// id - outline 为当前标题生成的 id 号,是个数值
// 如果设置了 anchorURL,则会统一使用 anchorURL 参数的地址
anchorLinkFilter: null
}
Methods
outline.js 的提供的方法如下:
attr([prop, value])
Description
attr() 方法用来设置或者获取初始化时配置的 attrs 信息的。
Parameters
prop
- Type:
- String|HTMLElement
(可选)options 中的属性名称或者要配置的 attrs 信息。
value
- Type:
- Any
(可选)要设置的 prop 属性的值
- 不传递任何参数:返回完整的 attrs 配置信息;
- 仅传递 prop:
- String: 返回 attrs 配型信息中与 prop 对应的值;
- Object: 用来设置 attrs 配置信息;
- 同时传递 prop 和 value 参数:设置 attrs 配置信息中的某个属性值;
Returns
- Type:
- Any
配置信息 attrs 的属性值或者 Outline 对象。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.attr('title') // -> 'Outline v2.0.0'
outline.attr('title', '目录') // -> 设置 title 配置信息的值为 '目录'
outline.attr() // -> 返回完整配置参数 attrs 信息
isExpanded()
Description
isExpanded() 方法来判断导航菜单是否展开(可见)。
Returns
- Type:
- Boolean
返回菜单展开状态。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 展开
outline.toggle()
outline.isExpanded() // -> true
// 收起
outline.toggle()
outline.isExpanded() // -> false
getChapters([isTreeStructured])
Description
getChapters() 方法来获取 outline.js 分析的文章段落层次数据。
Parameters
isTreeStructured
- Type:
- Boolean
- Default:
- false
(可选)是否为树结构的数据。
- false: (默认值)输出打平的一维数组格式数据;
- true: 输出树结构格式的数据;
Returns
- Type:
- Object
outline.js 分析的文章段落层次数据。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// 一维数组格式数据
// -> [{
{
id: 2,
pid: -1,
level: 1,
rel: "heading-2",
text: "安装说明",
index: 3,
code: "3",
},
{
id: 3,
pid: 2,
level: 2,
rel: "heading-3",
text: "npm install",
index: 1,
code: "3.1",
children: []
},
{
id: 4,
pid: 2,
level: 2,
rel: "heading-4",
text: "CDN 调用",
index: 2,
code: "3.2",
children: []
},
{
id: 5,
pid: 2,
level: 2,
rel: "heading-5",
text: "调用本地JS文件",
index: 3,
code: "3.3",
children: []
}
}]
outline.getChapters(true)
// 有 children 属性的树结构对象数组
// -> [{
code: "3",
id: 2,
index:3,
level:1,
pid:-1,
rel: "heading-2"
text:"安装说明",
children: [
{
id: 3,
pid: 2,
level: 2,
rel: "heading-3",
text: "npm install",
index: 1,
code: "3.1",
children: []
},
{
id: 4,
pid: 2,
level: 2,
rel: "heading-4",
text: "CDN 调用",
index: 2,
code: "3.2",
children: []
},
{
id: 5,
pid: 2,
level: 2,
rel: "heading-5",
text: "调用本地JS文件",
index: 3,
code: "3.3",
children: []
}
]
}]
outline.destroy()
outline.getChapters()
// 调用 destroy() 方法后,所有数据都清空了
// -> []
count()
Description
count() 方法来获取 outline.js 分析的文章段落层次数据的数量。
Returns
- Type:
- Number
outline.js 分析的 chapters 数据数量。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// -> [{
code: "1",
id: 0,
index: 1,
level: 1,
pid: -1
rel: "heading-0"
text: "创作灵感"
}]
outline.count()
// -> 1 就是 getChapters() 返回数据的数量
addButton(button)
Description
addButton() 方法添加自定义的工具栏按钮。
Parameters
button
- Type:
- Object|Array
(必须)单个按钮的配置信息或者多个按钮的配置信息。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
outline.addButton({
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
type: 'click',
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
})
removeButton(name)
Description
removeButton() 方法移除工具栏按钮。
Parameters
name
- Type:
- String
(必须)按钮名称。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
outline.addButton({
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
type: 'click',
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
})
setTimeout(() => {
outline.removeButton('clean')
}, 5000)
toTop([afterScroll])
Description
toTop() 方法会控制页面(scrollElement)滚动到顶部。
Parameters
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toTop() // 页面将滚动到顶部,向上滚动按钮消失
outline.toTop(() => {
console.log('滚动结束‘)
})
toBottom([afterScroll])
Description
toBottom() 方法会控制页面(scrollElement)滚动到顶部。
Parameters
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toBottom() // 页面将滚动到底部,向下滚动按钮消失
outline.toBottom(() => {
console.log('滚动结束‘)
})
scrollTo(top[,afterScroll])
Description
scrollTo() 方法用于将窗口的滚动条滚动到指定 top 值的位置。
Parameters
top
- Type:
- Number
(必选)页面要滚动的 top 数值。
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// -> 页面将滚动到距离顶部 200 像素的位置
outline.scrollTo(200)
outline.scrollTo(200, () => {
console.log('滚动结束‘)
})
expand()
Description
expand() 方法来展开导航菜单。
Returns
- Type:
- Number
Outline 对象,便于链式调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 收起菜单
outline.expand()
outline.isExpanded() // -> true
collapses()
Description
collapses() 方法来收起导航菜单。
Returns
- Type:
- Number
Outline 对象,便于链式调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 收起菜单
outline.collapses()
outline.isExpanded() // -> false
toggle()
Description
toggle() 方法用来隐藏或显示侧边栏菜单。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toggle() // 如果已经隐藏,则显示
outline.toggle() // 如果已显示,则隐藏
print()
Description
print() 方法用于启动打印界面,打印当前文章。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 如果浏览器支持 print() 打印,则启动打印界面
outline.print()
enterReading()
Since
3.32.0
Description
enterReading() 方法来切换进入阅读模式。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
outline.enterReading()
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
exitReading()
Since
3.32.0
Description
exitReading() 方法用来从阅读模式切换回普通文章页面模式。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
outline.enterReading()
outline.exitReading()
演示地址:https://yaohaixiao.github.io/examples/outline.js/flex.html
switchReading()
Since
3.32.0
Description
switchReading() 方法用来在阅读模式和回普通文章页面模式相互切换。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
// 进入阅读模式
outline.switchReading()
// 退出阅读模式
outline.switchReading()
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
destroy()
Description
destroy() 方法用于移除所有绘制的 DOM 节点,并移除绑定的事件处理器,同时重置所有 attrs 配置信息和 data 信息。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// -> [{
code: "1",
id: 0,
index: 1,
level: 1,
pid: -1
rel: "heading-0"
text: "创作灵感"
}]
outline.destroy()
outline.getChapters()
// 调用 destroy() 方法后,所有数据都清空了
// -> []
refresh()
Description
refresh() 方法是(在文章政委内容改变后)重新绘制导航信息的方法:
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
showCode: true
})
const REFRESH_METHOD = '<h3>添加 refresh() 方法</h3>' +
'<p>refresh() 方法是(在文章政委内容改变后)重新绘制导航信息的方法</p>'
outline.$article.innerHTML += REFRESH_METHOD
// 根据新的内容重新绘制导读信息
outline.refresh()
reload(options)
Description
reload (options) 方法是(根据新的配置信息)重启程序方法:
- 先移除所有绘制的 DOM 元素和绑定的事件处理器;
- 重新初始化程序;
Parameters
options
- Type:
- Object
(可选)初始化的配置参数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
showCode: true
})
// 重启后,将不再显示段落层次编号
outline.reload({
showCode: false
})
$emit(topic[, data, async = true])
Description
$emit()方法用来发布订阅主题信息。
outline.js 默认是采用异步方式发布的。以确保在消费者处理主题时,主题的发起者不会被阻止。 当然 $emit() 方法也支持同步主题发布。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
data
- Type:
- Object
(可选)消息传递的数据对象。
async
- Type:
- Boolean
- Default:
- true
(可选) 是否异步发布。默认值:true。
- 当 async 设置为 true(默认) 时,异步发布;
- 当 async 设置为 false 时,同步发布;
Returns
- Type:
- Outline
Outline 对象,以便实现链式调用。
const outline = new Outline(Outline.DEFAULTS)
const handler = (msg) => {
console.log(msg)
}
outline.$on('created', handler)
outline.$on('mounted', handler)
// 异步发布
outline.$emit('mounted') // -> 'ok'
// 同步发布
// 延迟10毫秒:应该看输出 ok 后输出
outline.$emit('created')
$on(topic, handler)
Description
$on() 方法用来订阅主题,并给出处理器函数。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
handler
- Type:
- Function
((必须)主题的处理器函数。
Returns
- Type:
- String。
唯一的 token 字符串,例如:'guid-1'。
const outline = new Outline(Outline.DEFAULTS)
const handler = function(attrs) {
// this 上下文指向 outline 实例
this.attr()
console.log('attrs: ', attrs)
}
outline.$on('created', handler)
// 手动触发 created 事件
outline.$emit('created')
$off(topic[, token])
Description
$off() 用来取消订阅主题。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
token
- Type:
- Function | String
(可选)订阅主题的处理器函数或者唯一 Id 值。
- 为传递 token 参数:取消指定 topic 的订阅;
- 传递 token 参数:仅删除 topic 订阅信息中与 token 对应的事件处理器
Returns
- Type:
- Outline
Outline 对象,以便实现链式调用。
const outline = new Outline(Outline.DEFAULTS)
const handler = (msg) => {
console.log('handler:', msg)
}
outline.$on('created')
// 取消订阅 author 主题
outline.$off('created')
// 不会有任何反应,因为已经取消订阅了
outline.$emit('created')
Events
outline.js 从 3.21.0 开始提供了 6 事件。通过 outline.js 在 3.21.0 新添加的 $on() 方法监听。
created
事件名称 | 说明 | 回调参数 |
---|---|---|
created | Outline 实例配置信息初始化完成后触发,此时 DOM 元素还没有绘制。 | 返回实例最终的 attrs 配置属性的(对象)值。 |
Usage
const outline = new Outline()
outline.$on('created', function(attrs) {
// this 上下文就是 outline 实例
// attrs === outline.attr()
})
// 当 outline 实例的配置信息初始化完毕,就会触发 created 事件
outline.initialize(Outline.DEFAULTS)
mounted
事件名称 | 说明 | 回调参数 |
---|---|---|
mounted | Outline 实例的所有 DOM 元素绘制完毕后触发。 | -- |
Usage
const outline = new Outline()
outline.$on('mounted', function() {
// do something
})
// 当 outline 实例的所有 DOM 绘制完毕,就会触发 mounted 事件
outline.initialize(Outline.DEFAULTS)
enterReading
事件名称 | 说明 | 回调参数 |
---|---|---|
enterReading | 配置了 print 参数,在进入阅读模式后会触发。 | -- |
Usage
const defaults = Outline.DEFAULTS
// 需要配置 print 参数
defaults.print = {
element: '#article',
title: document.querySelector('.title')
}
const outline = new Outline(Outline.DEFAULTS)
outline.$on('enterReading', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
// 手动触发 enterReading 事件
outline.$emit('enterReading')
exitReading
事件名称 | 说明 | 回调参数 |
---|---|---|
exitReading | 配置了 print 参数,在离开阅读模式后会触发。 | -- |
Usage
const defaults = Outline.DEFAULTS
// 需要配置 print 参数
defaults.print = {
element: '#article',
title: document.querySelector('.title')
}
const outline = new Outline(Outline.DEFAULTS)
outline.$on('exitReading', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
// 手动触发 exitReading 事件
outline.$emit('exitReading')
beforeDestroy
事件名称 | 说明 | 回调参数 |
---|---|---|
beforeDestroy | Outline 实例销毁前事件,在调用 Outline 对象的实例 destroy() 方法后会触发。 | -- |
Usage
const outline = new Outline(Outline.DEFAULTS)
outline.$on('beforeDestroy', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
outline.destroy()
destroyed
事件名称 | 说明 | 回调参数 |
---|---|---|
destroyed | Outline 实例销毁后事件,在调用 Outline 对象的实例 destroy() 方法后会触发。 | -- |
Usage
const outline = new Outline(Outline.DEFAULTS)
outline.$on('beforeDestroy', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
outline.destroy()
outline.js - 自动生成文章导读(Table of Contents)导航的 JavaScript 工具。会自动分析文章中的标题( h1~h6 )标签,并生成文章段落层次结构的导读导航菜单。
创作灵感
AnchorJS 是 outline.js 的创作灵感来源。既然 AnchorJS 可创建标题的链接,为什么不直接给文章生成一个文章导读(Table of Contents)导航呢? 于是就有了outline.js。
特点(Features)
- 原生 JavaScript 编写,无需任何依赖;
- 支持 UMD 规范;
- 支持 E6 模块,提供功能独立的 ES6 模块;
- Anchors 模块:类似 AnchorJS 基础功能模块,自动分析段落层级;
- Drawer 模块:独立的侧滑窗口模块;
- Navigator 模块:独立的导航菜单模块;
- Toolbar 模块:独立的固定定位的工具栏模块;
- 拥有 AnchorJS 基础功能;
- 支持中文和英文标题文字生成ID;
- 支持生成独立的侧边栏导航菜单;
- 支持直接在文章中生成文章导读导航;
- 自动分析标题关系,生成段落层级索引值;
- 可以作为 jQuery 插件使用;
- 界面简洁大方;
- 配置灵活,丰富,让你随心所欲掌控 outline.js;
安装说明
outline.js 提供多种安装方式的支持: npm 安装、加载 CDN 资源、以及本地资源调用。
npm install
$ npm install -S @yaohaixiao/outline.js
CDN 调用
<script src="https://cdn.jsdelivr.net/gh/yaohaixiao/outline.js/outline.min.js"></script>
调用本地JS文件
<script src="path/to/outline.min.js"></script>
使用说明
outline.js 既支持在 node.js 环境中以 CommonJS 模块调用,也支持 ES6 模块方式加载。
// Node.js 环境中使用
const Outline = require('@yaohaixiao/outline.js')
// 作为 ES6 模块使用
import Outline from '@yaohaixiao/outline.js/src/outline'
// 调用其他独立模块
import Anchors from '@yaohaixiao/outline.js/src/anchors'
import Navigator from '@yaohaixiao/outline.js/src/navigator'
import Drawer from '@yaohaixiao/outline.js/src/drawer'
import Toolbar from '@yaohaixiao/outline.js/src/toolbar'
import Reader form '@yaohaixiao/outline.js/src/reader'
// 创建 Outline 实例
// 2.0.0 调整了配置参数,配置更加简单
const outline = new Outline({
// 文章显示区域的 DOM 元素或者选择器字符串
articleElement: '#article',
// 要收集的标题选择器
selector: 'h2,h3,h4,h5,h6',
// 负责文章区域滚动的元素
// String 类型 - 选择器字符串,默认值:html,body(window窗口)
// HTMLElement 类型 - DOM 元素
scrollElement: 'html,body',
// 文章导读菜单的位置
// relative - (默认值)创建独立的侧滑菜单
// sticky - 导航菜单将以 sticky 模式布局(需要确保菜单插入位置支持 sticky 模式布局)
// fixed - 导航菜单将以 fixed 模式布局,会自动监听滚动位置,模拟 sticky 布局
// sticky 和 fixed 布局时,需要设置 parentElement
// 2.0.0 暂时不支持在文章开始位置插入 chapters 导航菜单
position: 'sticky',
// 设置 position: relative 时,placment 定义侧滑菜单和 toolbar 导航位置:
// rtl - 菜单位置在窗口右侧,滑动动画为:right to left
// ltr - 菜单位置在窗口左侧,滑动动画为:left to right
// ttb - 菜单位置在窗口上方,滑动动画为:top to bottom
// btt - 菜单位置在窗口下方,滑动动画为:bottom to top
placement: '',
// 导航菜单将要插入的位置(DOM 元素)
// String 类型 - 选择器字符串
// HTMLElement 类型 - 插入的 DOM 元素
// 仅在 position 设置为 sticky 和 fixed 布局时有效
parentElement: '#aside',
// 是否显示段落章节编号
showCode: true,
// 标题图标链接的 URL 地址
// (默认)没有设置定制,点击链接页面滚动到标题位置
// 设置了链接地址,则不会滚动定位
anchorURL: '',
// DIYer的福利
// 独立侧滑菜单时,customClass 会追加到 drawer 侧滑窗口组件
// 在文章中显示导航菜单时,customClass 会追加到 chapters 导航菜单
customClass
});
// 可以在创建导航后,重置配置信息,重新生成新的导航
Outline.reload({
// 调整位直接在文章内生成导航
position: 'sticky',
articleElement: '#article'
})
Options
outline.js 有者丰富的配置选项,以便适应不同的展示方式。
articleElement
Description
- Type:
- String|HTMLElement
- Default:
- '#article'
- String:选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement:'DOM 元素;
可选,用来指定页面中显示文章正文的 DOM 节点或者选择器字符串。
// Default Selector
const outline = new Outline(Outline.DEFAULTS)
// Customize Selector
const outline = new Outline({
articleElement: $('#main')
})
selector
Description
- Type:
- String
- Default:
- 'h1,h2,h3,h4,h5,h6'
可选,用来指定 article 节点下,要生成导航的标题标签的选择器。
// Default selector
new Outline(Outline.DEFAULTS)
// Customize selector
new Outline({
selector: 'h2'
})
title
Description
- Type:
- String|Boolean
- Default:
- '目录'
可选,用来指定文章导读导航菜单的标题文字。设置空字符串或者 false,则不显示标题。在插入导航菜单的 DOM 元素已有标题时,可以设置 title: '' 或者 false。
说明:本 API 文档的导航菜单便是使用 outline.js 生成,并且没有设置 title。
(function(){
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = ''
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
outline = new Outline(Outline.DEFAULTS)
})()
scrollElement
Description
- Type:
- String|HTMLElement
- Default:
- 'html,body'
- String: 选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement: DOM 元素;
可选,负责文章区域滚动的元素:
// 默认是当前窗口滚动
new Outline(Outline.DEFAULTS)
// 指定滚动区域是 #main 元素
new Outline({
scrollElement: '#main'
})
position
Description
- Type:
- String
- Default:
- 'relative'
可选,用来指定文章导读导航菜单的显示位置:
- relative: (默认值)创建独立的侧滑菜单;
- sticky: 导航菜单将以 sticky 模式布局(需要确保菜单插入位置(DOM 节点)支持 sticky 模式布局);
- fixed: 导航菜单将模拟 sticky 布局,起初是普通定位,会自动监听滚动位置,但滚动到导航菜单顶部时,以 fixed 模式布局,模拟 sticky 布局效果;
当设置为 sticky 和 fixed 布局时,需要设置 parentElement。
注意:2.0.0 暂时不支持之前版本那种 inside 模式,不会自动在文章开始位置插入 chapters 导航菜单
// 默认生成独立的侧滑弹窗导航菜单
new Outline(Outline.DEFAULTS)
// 在页面内部插入导航菜单
new Outline({
// 在(文章的)侧边栏显示导航菜单
parentElement: '#aside',
// 或者 sticky 定位
position: 'fixed'
})
parentElement
Description
- Type:
- String
- Default:
- '#aside'
- String: 选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement: DOM 元素;
可选,导航菜单将要插入的位置(DOM 元素)。仅在 position 设置为 sticky 和 fixed 布局时有效。
// 在页面内部插入导航菜单
new Outline({
// 在(文章的)侧边栏显示导航菜单
parentElement: '#aside',
// 或者 sticky 定位
position: 'fixed'
})
placement
Description
- Type:
- String
- Default:
- 'rtl'
可选,设置 position: relative 时,placement 定义侧滑菜单和 toolbar 导航位置:
- rtl - 菜单位置在窗口右侧,滑动动画为:right to left(默认值);
- ltr - 菜单位置在窗口左侧,滑动动画为:left to right;
- ttb - 菜单位置在窗口上方,滑动动画为:top to bottom;
- btt - 菜单位置在窗口下方,滑动动画为:bottom to top;
// 默认是在窗口右侧显示侧滑导航菜单
new Outline(Outline.DEFAULTS)
// 调整为在窗口右侧显示侧滑导航菜单
new Outline({
placement: 'ltr'
})
stickyHeight
Description
- Type:
- Number
- Default:
- 0
可选,用来指定页面中其它 sticky 或者模拟 skicky 的 fiexed 定位的 DOM 元素的高度。
这些 sticky 元素脱离了正常的流布局后,原来 h1~h6 标题标签的 offsetTop 计算会出现偏差。sticky 元素会遮挡标题,因此针对页面中有其它sticky 节点时,需要设置 stickyHeight 高度。以便 outline.js 根据 stickyHeight 和计算出的标题的 offsetTop 值重新计算滚动定位。
说明:outline.js 主要用于文章详情页面,stickyHeight 仅针对 top: 0,且 sticky 定位元素在文章内容区域上方的位置;
const defaults = Outline.DEFAULTS
// 设置 stickyHeight(outline.js 的示例页面的主标题元素的高度)
defaults.stickyHeight = 86
// 默认生成独立的侧滑弹窗导航菜单
new Outline(defaults)
showCode
Description
- Type:
- Boolean
- Default:
- true
可选,是否显示段落章节编号(注意:3.38.2 开始 showCode 默认为 false):
- false - 显示编号;
- false - 不显示编号(默认值);
animationCurrent
Description
- Type:
- Boolean
- Default:
- true
可选,是否采用动画定位高亮当前的章节标题:
- true - 采用动画定位高亮(默认值);
- false - 采用高亮当前章节标题的链接文字并加粗文字;
hasToolbar
Description
- Type:
- Boolean
- Default:
- true
可选,是否显示侧边的按钮工具栏:
- true - 显示按钮工具栏(默认值);
- false - 不显示按钮工具栏;
closeOnClickModal
Description
- Type:
- Boolean
- Default:
- true
可选,点击空白处(非独立导航菜单),收起导航菜单:
- true - 点击空白处,收起菜单(默认值);
- false - 点击空白处,不收起菜单;
showNavModalFirst
Description
- Type:
- Boolean
- Default:
- false
可选,有独立导航菜单时,是否默认显示菜单:
- false - 默认先显示按钮工具栏(默认值);
- true - 默认先显示独立导航菜单弹窗;
anchorURL
Description
- Type:
- String
- Default:
- ''
可选,用来指定文章标题锚点链接图标的链接地址:
// Default URL - 默认链接,点击图标,页面会滚动到当前标题位置
new Outline()
// Customize URL - 直接打开链接了
new Outline({
anchorURL: 'http://www.yaohaixiao.com/'
})
homepage
Description
- Type:
- String
- Default:
- ''
可选,用来指定文章标题锚点链接图标的链接地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 Homepage 图标的按钮
outline.reload({
homepage: 'http://www.yaohaixiao.com/'
})
git
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 git 图标的按钮
outline.reload({
git: 'https://github.com/yaohaixiao/outline.js'
})
tags
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库 tags 页面地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 tags 图标的按钮
outline.reload({
tags: 'https://github.com/yaohaixiao/outline.js/tags'
})
issues
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库 issues 页面地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 issues 图标的按钮
outline.reload({
issues: 'https://github.com/yaohaixiao/outline.js/issues'
})
tools
Description
- Type:
- Array
- Default:
- []
可选,自定义的按钮配置项。tools 中的按钮会排列显示在 homepage, git, tags, issues 等按钮之后。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
// 侧边栏的 Toolbar 会多出一个 git 图标的按钮
outline.reload({
git: 'https://github.com/yaohaixiao/outline.js',
tools: [
{
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
}
]
})
reader
Since
3.32.0
说明:3.32.0 以前的版本,此属性的原名为 print,另外,reader.element 属性也调整为了 reader.target。请升级后在初始化配置参数时注意调整。
Description
- Type:
- Object
- Default:
- {target: '', title: '', enterReadingTip: ‘进入阅读模式,按 ESC 键可退出阅读模式’, allowSpeak: false}
可选,自定义的是否自动为文章页面创建打印样式。
- target:
- (必须)要打印的文章区域,DOM 元素或者选择器字符串;
- title:
- (可选)要打印的文章标题。如果 element 区域有 h1 标签则无需设置。可以直接设置标题文本,也可以是文章页的主标题 DOM 元素;
- enterReadingTip:
- (可选)进入阅读模式的提示文本,默认值:‘进入阅读模式,按 ESC 键可退出阅读模式’;
- allowSpeak:
- (可选)针对现代浏览器支持 Web Speech API,是否开启语音阅读功能。默认值:false;
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式',
// 开启语音阅读
allowSpeak: true
}
outline = new Outline(defaults)
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
customClass
Description
- Type:
- String
- Default:
- ''
可选,(DIYer福利)设置自定义样式的 class 名称:
- '' - 采用默认 outline.js 的 UI 界面(默认值);
- 设置自定义样式 - 自己根据需求设置个性化的 UI 界面;
// Default UI
new Outline(Outline.DEFAULTS)
// Customized
new Outline({
// 设置深色配置界面
customClass: 'theme-dark'
})
afterScroll
Description
- Type:
- Function
- Default:
- null
可选,当点击导航菜单、文章中的 anchor 图标(#)或者上下滚动按钮会触发滚动,afterScroll() 回调函数会在滚动结束后触发执行。
Parameters
target
- Type:
- String
afterScroll() 回调函数有一个参数 target,返回的是当前点击的 DOM 元素的名称:
- 'anchor':表示点击的是 anchor 图标,即文章中标题前的 “#” 图标,此时的 this 上下文指向 outline.anchors;
- 'chapter':表示点击的是导航菜单的链接,此时的 this 上下文指向 outline.chapters;
- 'up':表示点击的是工具栏的向上按钮,此时的 this 上下文指向 outline.toolbar;
- 'down':表示点击的是工具栏的向下按钮,此时的 this 上下文指向 outline.toolbar;
注意:因为配置 afterScroll 回调函数会因为 4 个不同的 DOM 触发,所以需要根据 target 返回的值和此时的 this 指向判断处理。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterScroll = function(target) {
// 当然,如果你希望无论是点击什么都执行,就不需要判断了
// 直接些通用的滚动结束的逻辑即可
switch(target){
case 'anchor':
// 针对点击 # 的处理逻辑
break
case 'chapter':
// 针对点击导航菜单的处理逻辑
break
case 'up':
// 针对点击向上滚动按钮的处理逻辑
break
case 'down':
// 针对点击向下滚动按钮的处理逻辑
break
}
}
outline = new Outline(Outline.DEFAULTS)
afterSticky
Description
- Type:
- Function
- Default:
- null
可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。
说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。
Parameters
closed
- Type:
- Boolean
closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态
isSticky
- Type:
- Boolean
isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。
const $header = document.querySelector('#header')
const HEADER_STICKY = 'header_sticky'
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterSticky = function(closed, isStickying) {
const $nav = this.$el
const BORDER_RIGHT = 'utils-border-right'
if (closed) {
return false
}
if (isStickying) {
$nav.classList.add(BORDER_RIGHT)
$header.classList.add(HEADER_STICKY)
} else {
$nav.classList.remove(BORDER_RIGHT)
$header.classList.remove(HEADER_STICKY)
}
}
defaults.afterToggle = function(closed, isStickying) {
if (!isStickying) {
return false
}
if (closed) {
$header.classList.remove(HEADER_STICKY)
} else {
$header.classList.add(HEADER_STICKY)
}
}
outline = new Outline(Outline.DEFAULTS)
afterToggle
Description
- Type:
- Function
- Default:
- null
可选,当导航菜单隐藏或者显示的时候,会触发执行 afterToggle 回调函数。
说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。
Parameters
closed
- Type:
- Boolean
closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态
isSticky
- Type:
- Boolean
isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。
const $header = document.querySelector('#header')
const HEADER_STICKY = 'header_sticky'
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterSticky = function(closed, isStickying) {
const $nav = this.$el
const BORDER_RIGHT = 'utils-border-right'
if (closed) {
return false
}
if (isStickying) {
$nav.classList.add(BORDER_RIGHT)
$header.classList.add(HEADER_STICKY)
} else {
$nav.classList.remove(BORDER_RIGHT)
$header.classList.remove(HEADER_STICKY)
}
}
defaults.afterToggle = function(closed, isStickying) {
if (!isStickying) {
return false
}
if (closed) {
$header.classList.remove(HEADER_STICKY)
} else {
$header.classList.add(HEADER_STICKY)
}
}
outline = new Outline(Outline.DEFAULTS)
chapterTextFilter
Description
- Type:
- Function
- Default:
- null
可选,API 文档中,正文的方法会添加参数等信息,例如:getChapters(headings, showCode, chapterTextFilter)。而在 chapters 导航菜单,我希望显示为 getChapters(),这时我们就可以借助 chapterTextFilter 回调函数。对原始的文本进行过滤,返回我们期望的 getChapters() 文本。
Parameters
text
- Type:
- String
chapterTextFilter() 回调函数有一个参数 text,返回的是当前 hx 标题中的文本。
Returns
- Type:
- String
返回最终希望生成的标题文本内容。
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = false
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
defaults.chapterTextFilter = (text) => {
return text.replace(/\(.*?\)/, '()')
}
outline = new Outline(defaults)
anchorLinkFilter
Description
- Type:
- Function
- Default:
- null
可选,API 文档中,正文标题的锚点链接地址生成函数。
Parameters
tag
- Type:
- String
当前标题的 tagName。小写的:h1~6。
title
- Type:
- String
当前标题的文本内容。
id
- Type:
- Number
outline.js 为当前标题生成 id 号。
Returns
- Type:
- String
返回最终希望生成锚点链接的文本内容。
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = false
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
defaults.chapterTextFilter = (text) => {
return text.replace(/\(.*?\)/, '()')
}
defaults.anchorLinkFilter = (tag, title, id) => {
return `${tag}-${title}-${id}`
}
outline = new Outline(defaults)
Properties
outline.js 重构后,对外放 4 个重要的属性:anchors、drawer、chapters、reader 和 toolbar。它们都是独立的对象实例,提供了 outline.js 所有的能力(属性和方法)。
attrs
Description
- Type:
- Object
存储的是 Outline 对象当前使用中的配置选项:
说明:建议使用 attr(prop) 方法来获取属性,避免直接调用属性。
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 查看全部配置信息
outline.attrs
$article
Since
3.32.0
Description
- Type:
- HTMLElement
存储的是 Outline 对象要分析的文章正文内容显示区域的 DOM 元素:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 获取文章正文内容显示区域的 DOM 元素
outline.$article
$scrollElement
Since
3.34.0
Description
- Type:
- HTMLElement
存储的是 Outline 对象要分析的控制文章内容滚动的 DOM 元素:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 获取文章正文内容显示区域的 DOM 元素
outline.$scrollElement
buttons
Description
- Type:
- Array
存储的是 Outline 对象当前工具栏的完整的按钮配置信息:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 查看全部按钮配置信息
outline.buttons
anchors
Description
- Type:
- Object
Anchors 模块:类似 AnchorJS 基础功能模块,自动分析段落层级。
// 仅展示 API 中对外公开的方法和属性
class Anchors extends Base {
constructor(options) {
super()
this.attrs = Anchors.DEFAULTS
this.$articleElement = null
this.$scrollElement = null
this.$headings = []
this.chapters = []
// 省略其它逻辑...
}
getChapters(isTreeStructured = false) {
const chapters = this.chapters
return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters
}
count() {
return this.chapters.length
}
attr(prop, value) {
const attrs = this.attrs
if (isString(prop)) {
// 只能扩展 attrs 中已有的属性
if (value && hasOwn(attrs, prop)) {
// 更新单个配置信息
attrs[prop] = value
return this
}
// 只传递 prop 参数,则返回对应的属性值
return attrs[prop]
} else if (isObject(prop)) {
// 批量更新配置信息
extend(attrs, prop)
return this
} else if (arguments.length === 0) {
// 不传递参数,直接返回整个
return attrs
}
return this
}
render() {
// 省略其它逻辑...
return this
}
scrollTo(top, after) {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Anchors.DEFAULTS = {
scrollElement: 'html,body',
articleElement: '#article',
selector: 'h1,h2,h3,h4,h5,h6',
anchorURL: '',
hasAnchor: true,
isAtStart: true,
showCode: false,
created: null,
mounted: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Anchors
navigator
Description
- Type:
- Object
Navigator 模块:独立的导航菜单模块;
// 仅展示 API 中对外公开的方法和属性
class Navigator extends Base {
constructor(options) {
super()
this.attrs = Navigator.DEFAULTS
this.$el = null
this.$title = null
this.$main = null
this.$list = null
this.$placeholder = null
this.$parentElement = null
this.$scrollElement = null
this.chapters = []
this.closed = false
this.active = 0
this.offsetTop = 0
this.$active = null
this.timer = null
this.playing = false
// 省略其它逻辑...
}
isClosed() {
return this.closed
}
isSticky() {
const position = this.attr('position')
return position === 'sticky'
}
isFixed() {
const position = this.attr('position')
return position === 'fixed'
}
isInside() {
return this.isFixed() || this.isSticky()
}
isOutside() {
return !this.isInside()
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
highlight(id) {
// 省略其它逻辑...
return this
}
sticky() {
// 省略其它逻辑...
return this
}
scrollTo(top, after) {
// 省略其它逻辑...
return this
}
show() {
// 省略其它逻辑...
return this
}
hide() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Navigator.DEFAULTS = {
parentElement: '',
scrollElement: '',
selector: '',
active: 0,
closed: false,
showCode: true,
position: 'relative',
chapters: [],
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Navigator
drawer
Description
- Type:
- Object
Drawer 模块:独立的侧滑窗口模块。
// 仅展示 API 中对外公开的方法和属性
class Drawer extends Base {
constructor(options) {
super()
this.attrs = Drawer.DEFAULTS
this.title = ''
this.closed = true
this.$el = null
this.$modal = null
this.$header = null
this.$title = null
this.$close = null
this.$main = null
this.$footer = null
this.$overlay = null
this.zIndex = 0
// 省略其它逻辑...
}
isClosed() {
return this.closed
}
setTitle() {
this.attr('title', title)
this.title = title
this.$title.innerHTML = title
return this
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
open() {
// 省略其它逻辑...
return this
}
close() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Drawer.DEFAULTS = {
placement: 'rtl',
title: '标题',
size: 'regular',
hasClose: true,
hasOverlay: true,
hasOffset: false,
hasPadding: true,
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Drawer
reader
Description
- Type:
- Object
Reader 模块:独立的阅读视图模块。
// 仅展示 API 中对外公开的方法和属性
class Drawer extends Base {
constructor(options) {
super()
this.attrs = cloneDeep(Reader.DEFAULTS)
this.reading = false
this.$target = null
this.$paper = null
this.$title = null
this.$article = null
this.$icon = null
// 省略其它逻辑...
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
refresh() {
// 省略其它逻辑...
return this
}
enter() {
// 省略其它逻辑...
return this
}
exit() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
print() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Reader.DEFAULTS = {
target: '',
title: '标题',
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
export default Reader
toolbar
Description
- Type:
- Object
Toolbar 模块:独立的固定定位的工具栏模块;
// 仅展示 API 中对外公开的方法和属性
class Toolbar extends Base {
constructor(options) {
super()
this.attrs = Drawer.DEFAULTS
this.title = ''
this.closed = true
this.$el = null
this.$modal = null
this.$header = null
this.$title = null
this.$close = null
this.$main = null
this.$footer = null
this.$overlay = null
// 省略其它逻辑...
}
isDisabled(name) {
const buttons = this.attr('buttons')
let button
if (name) {
button = buttons.find((option) => option.name === name)
return !!(button && button.disabled)
}
return this.disabled
}
isClosed() {
return this.closed
}
highlight() {
// 省略其它逻辑...
return this
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
add(button) {
// 省略其它逻辑...
return this
}
remove(name) {
// 省略其它逻辑...
return this
}
switch(name, enabled) {
// 省略其它逻辑...
return this
}
enable(name) {
// 省略其它逻辑...
return this
}
disable(name) {
// 省略其它逻辑...
return this
}
show() {
// 省略其它逻辑...
return this
}
hide() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Toolbar.DEFAULTS = {
placement: 'ltr',
closed: false,
disabled: false,
buttons: [],
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterDisabled: null,
afterEnabled: null,
beforeDestroy: null,
afterDestroy: null
}
Drawer.zIndex = 2000
export default Toolbar
Outline.DEFAULTS
Description
- Type:
- Object
静态属性,存储的是 Outline 对象默认配置选项:
Outline.DEFAULTS = {
// 文章显示区域的 DOM 元素或者选择器字符串
articleElement: '#article',
// 要收集的标题选择器
selector: 'h2,h3,h4,h5,h6',
// 指定文章导读导航菜单的标题文字。
// 设置空字符串或者 false,则不显示标题
// 在插入导航菜单的 DOM 元素已有标题时,可以设置 title: '' 或者 false
title: '目录',
// 负责文章区域滚动的元素
// String 类型 - 选择器字符串,默认值:html,body(window窗口)
// HTMLElement 类型 - DOM 元素
// 注意:如果您使用的是比较旧的 chrome 浏览器,例如:Chromium 60.x 版本或者以下版本
// 请手动设置 scrollElement = 'body',否则点击导航无法滚动定位
scrollElement: 'html,body',
// 文章导读菜单的位置
// relative - (默认值)创建独立的侧滑菜单
// sticky - 导航菜单将以 sticky 模式布局(需要确保菜单插入位置支持 sticky 模式布局)
// fixed - 导航菜单将以 fixed 模式布局,会自动监听滚动位置,模拟 sticky 布局
// sticky 和 fixed 布局时,需要设置 parentElement
// 2.0.0 暂时不支持之前版本那种 inside 模式,不会自动在文章开始位置插入 chapters 导航菜单
position: 'sticky',
// 导航菜单将要插入的位置(DOM 元素)
// String 类型 - 选择器字符串
// HTMLElement 类型 - 插入的 DOM 元素
// 仅在 position 设置为 sticky 和 fixed 布局时有效
parentElement: '#aside',
// 设置 position: relative 时,placment 定义侧滑菜单和 toolbar 导航位置:
// rtl - 菜单位置在窗口右侧,滑动动画为:right to left
// ltr - 菜单位置在窗口左侧,滑动动画为:left to right
// ttb - 菜单位置在窗口上方,滑动动画为:top to bottom
// btt - 菜单位置在窗口下方,滑动动画为:bottom to top
placement: 'rtl',
// 页面中其它 sticky 或者模拟 skicky 的 fiexed 定位的 DOM 元素的高度。例如 wordpress 系统中,
// 就会有 sticky 定位的导航菜单。这些 sticky 元素脱离了正常的流布局后,原来 h1~h6 标题标签的
// offsetTop 计算会出现偏差。sticky 元素会遮挡标题,因此针对页面中有其它 sticky 元素会遮挡标题,
// 因此针对 sticky 布局时,需要设置 stickyHeight 高度。outline.js 会根据 stickyHeight 和计
// 算出的标题的 offsetTop 值重新计算滚动定位;
// 说明:outline.js 主要用于文章详情页面,
// 因此 stickyHeight 仅针对 top: 0,且 sticky 定位元素在文章内容区域上方的位置;
stickyHeight: 0,
// 是否显示标题编号(注意:3.38.2 开始 showCode 默认为 false)
showCode: false,
// 是否显示侧边的按钮工具栏
hasToolbar: true,
// 指定是否采用动画定位高亮当前的章节标题,默认值:true
// 当值为 false 时,则采用高亮当前章节标题的链接文字并加粗文字
// 如果喜欢更简洁的高亮效果,可以选择设置为 false
animationCurrent: true,
// 标题图标链接的 URL 地址
// (默认)没有设置定制,点击链接页面滚动到标题位置
// 设置了链接地址,则不会滚动定位
anchorURL: '',
// 指定当前站点主页地址
homepage: '',
// 指定git仓库地址
git: '',
// 指定git仓库中的 tags 地址
tags: '',
// 指定git仓库中的 issues 地址
issues: '',
// 自定义按钮配置
tools: [],
// 为文章页添加基础的打印样式
// 如果您的页面已经有打印样式,就无需设置了
reader: {
//(必须)要打印的文章区域,DOM 元素或者选择器字符串。
target: '',
// (可选)要打印的文章标题。如果 element 区域有 h1 标签则无需设置。
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素
title: '',
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
},
// DIYer的福利
// 独立侧滑菜单时,customClass 会追加到 drawer 侧滑窗口组件
// 在文章中显示导航菜单时,customClass 会追加到 chapters 导航菜单
customClass,
// position: fixed,当导航菜单样式进入 fixed 定位后,触发的回调函数
afterSticky: null,
// 当导航菜单隐藏或者显示后,触发的回调函数
afterToggle: null,
// 当点击上下滚动按钮,导航菜单或者文章中的 # 图标,滚动结束后触发的回调函数
afterScroll: null,
// 文档的标题文本过滤回调函数
// API 文档中,正文的方法会添加参数等信息,例如:getChapters(headings, showCode, chapterTextFilter)
// 而在 chapters 导航菜单,我希望显示为 getChapters(),这时我们就可以借助 chapterTextFilter 回调函数
// 对原始的文本进行过滤,返回我们期望的 getChapters() 文本
chapterTextFilter: null,
// 锚点链接的生成回调函数
// anchorLinkFilter(tag, title, id)
// tag - 当前标题的 tagName 小写:h1~6
// title - 当前标题的文本内容
// id - outline 为当前标题生成的 id 号,是个数值
// 如果设置了 anchorURL,则会统一使用 anchorURL 参数的地址
anchorLinkFilter: null
}
Methods
outline.js 的提供的方法如下:
attr([prop, value])
Description
attr() 方法用来设置或者获取初始化时配置的 attrs 信息的。
Parameters
prop
- Type:
- String|HTMLElement
(可选)options 中的属性名称或者要配置的 attrs 信息。
value
- Type:
- Any
(可选)要设置的 prop 属性的值
- 不传递任何参数:返回完整的 attrs 配置信息;
- 仅传递 prop:
- String: 返回 attrs 配型信息中与 prop 对应的值;
- Object: 用来设置 attrs 配置信息;
- 同时传递 prop 和 value 参数:设置 attrs 配置信息中的某个属性值;
Returns
- Type:
- Any
配置信息 attrs 的属性值或者 Outline 对象。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.attr('title') // -> 'Outline v2.0.0'
outline.attr('title', '目录') // -> 设置 title 配置信息的值为 '目录'
outline.attr() // -> 返回完整配置参数 attrs 信息
isExpanded()
Description
isExpanded() 方法来判断导航菜单是否展开(可见)。
Returns
- Type:
- Boolean
返回菜单展开状态。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 展开
outline.toggle()
outline.isExpanded() // -> true
// 收起
outline.toggle()
outline.isExpanded() // -> false
getChapters([isTreeStructured])
Description
getChapters() 方法来获取 outline.js 分析的文章段落层次数据。
Parameters
isTreeStructured
- Type:
- Boolean
- Default:
- false
(可选)是否为树结构的数据。
- false: (默认值)输出打平的一维数组格式数据;
- true: 输出树结构格式的数据;
Returns
- Type:
- Object
outline.js 分析的文章段落层次数据。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// 一维数组格式数据
// -> [{
{
id: 2,
pid: -1,
level: 1,
rel: "heading-2",
text: "安装说明",
index: 3,
code: "3",
},
{
id: 3,
pid: 2,
level: 2,
rel: "heading-3",
text: "npm install",
index: 1,
code: "3.1",
children: []
},
{
id: 4,
pid: 2,
level: 2,
rel: "heading-4",
text: "CDN 调用",
index: 2,
code: "3.2",
children: []
},
{
id: 5,
pid: 2,
level: 2,
rel: "heading-5",
text: "调用本地JS文件",
index: 3,
code: "3.3",
children: []
}
}]
outline.getChapters(true)
// 有 children 属性的树结构对象数组
// -> [{
code: "3",
id: 2,
index:3,
level:1,
pid:-1,
rel: "heading-2"
text:"安装说明",
children: [
{
id: 3,
pid: 2,
level: 2,
rel: "heading-3",
text: "npm install",
index: 1,
code: "3.1",
children: []
},
{
id: 4,
pid: 2,
level: 2,
rel: "heading-4",
text: "CDN 调用",
index: 2,
code: "3.2",
children: []
},
{
id: 5,
pid: 2,
level: 2,
rel: "heading-5",
text: "调用本地JS文件",
index: 3,
code: "3.3",
children: []
}
]
}]
outline.destroy()
outline.getChapters()
// 调用 destroy() 方法后,所有数据都清空了
// -> []
count()
Description
count() 方法来获取 outline.js 分析的文章段落层次数据的数量。
Returns
- Type:
- Number
outline.js 分析的 chapters 数据数量。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// -> [{
code: "1",
id: 0,
index: 1,
level: 1,
pid: -1
rel: "heading-0"
text: "创作灵感"
}]
outline.count()
// -> 1 就是 getChapters() 返回数据的数量
addButton(button)
Description
addButton() 方法添加自定义的工具栏按钮。
Parameters
button
- Type:
- Object|Array
(必须)单个按钮的配置信息或者多个按钮的配置信息。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
outline.addButton({
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
type: 'click',
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
})
removeButton(name)
Description
removeButton() 方法移除工具栏按钮。
Parameters
name
- Type:
- String
(必须)按钮名称。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
outline.addButton({
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
type: 'click',
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
})
setTimeout(() => {
outline.removeButton('clean')
}, 5000)
toTop([afterScroll])
Description
toTop() 方法会控制页面(scrollElement)滚动到顶部。
Parameters
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toTop() // 页面将滚动到顶部,向上滚动按钮消失
outline.toTop(() => {
console.log('滚动结束‘)
})
toBottom([afterScroll])
Description
toBottom() 方法会控制页面(scrollElement)滚动到顶部。
Parameters
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toBottom() // 页面将滚动到底部,向下滚动按钮消失
outline.toBottom(() => {
console.log('滚动结束‘)
})
scrollTo(top[,afterScroll])
Description
scrollTo() 方法用于将窗口的滚动条滚动到指定 top 值的位置。
Parameters
top
- Type:
- Number
(必选)页面要滚动的 top 数值。
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// -> 页面将滚动到距离顶部 200 像素的位置
outline.scrollTo(200)
outline.scrollTo(200, () => {
console.log('滚动结束‘)
})
expand()
Description
expand() 方法来展开导航菜单。
Returns
- Type:
- Number
Outline 对象,便于链式调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 收起菜单
outline.expand()
outline.isExpanded() // -> true
collapses()
Description
collapses() 方法来收起导航菜单。
Returns
- Type:
- Number
Outline 对象,便于链式调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 收起菜单
outline.collapses()
outline.isExpanded() // -> false
toggle()
Description
toggle() 方法用来隐藏或显示侧边栏菜单。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toggle() // 如果已经隐藏,则显示
outline.toggle() // 如果已显示,则隐藏
print()
Description
print() 方法用于启动打印界面,打印当前文章。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 如果浏览器支持 print() 打印,则启动打印界面
outline.print()
enterReading()
Since
3.32.0
Description
enterReading() 方法来切换进入阅读模式。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
outline.enterReading()
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
exitReading()
Since
3.32.0
Description
exitReading() 方法用来从阅读模式切换回普通文章页面模式。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
outline.enterReading()
outline.exitReading()
演示地址:https://yaohaixiao.github.io/examples/outline.js/flex.html
switchReading()
Since
3.32.0
Description
switchReading() 方法用来在阅读模式和回普通文章页面模式相互切换。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
// 进入阅读模式
outline.switchReading()
// 退出阅读模式
outline.switchReading()
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
destroy()
Description
destroy() 方法用于移除所有绘制的 DOM 节点,并移除绑定的事件处理器,同时重置所有 attrs 配置信息和 data 信息。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// -> [{
code: "1",
id: 0,
index: 1,
level: 1,
pid: -1
rel: "heading-0"
text: "创作灵感"
}]
outline.destroy()
outline.getChapters()
// 调用 destroy() 方法后,所有数据都清空了
// -> []
refresh()
Description
refresh() 方法是(在文章政委内容改变后)重新绘制导航信息的方法:
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
showCode: true
})
const REFRESH_METHOD = '<h3>添加 refresh() 方法</h3>' +
'<p>refresh() 方法是(在文章政委内容改变后)重新绘制导航信息的方法</p>'
outline.$article.innerHTML += REFRESH_METHOD
// 根据新的内容重新绘制导读信息
outline.refresh()
reload(options)
Description
reload (options) 方法是(根据新的配置信息)重启程序方法:
- 先移除所有绘制的 DOM 元素和绑定的事件处理器;
- 重新初始化程序;
Parameters
options
- Type:
- Object
(可选)初始化的配置参数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
showCode: true
})
// 重启后,将不再显示段落层次编号
outline.reload({
showCode: false
})
$emit(topic[, data, async = true])
Description
$emit()方法用来发布订阅主题信息。
outline.js 默认是采用异步方式发布的。以确保在消费者处理主题时,主题的发起者不会被阻止。 当然 $emit() 方法也支持同步主题发布。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
data
- Type:
- Object
(可选)消息传递的数据对象。
async
- Type:
- Boolean
- Default:
- true
(可选) 是否异步发布。默认值:true。
- 当 async 设置为 true(默认) 时,异步发布;
- 当 async 设置为 false 时,同步发布;
Returns
- Type:
- Outline
Outline 对象,以便实现链式调用。
const outline = new Outline(Outline.DEFAULTS)
const handler = (msg) => {
console.log(msg)
}
outline.$on('created', handler)
outline.$on('mounted', handler)
// 异步发布
outline.$emit('mounted') // -> 'ok'
// 同步发布
// 延迟10毫秒:应该看输出 ok 后输出
outline.$emit('created')
$on(topic, handler)
Description
$on() 方法用来订阅主题,并给出处理器函数。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
handler
- Type:
- Function
((必须)主题的处理器函数。
Returns
- Type:
- String。
唯一的 token 字符串,例如:'guid-1'。
const outline = new Outline(Outline.DEFAULTS)
const handler = function(attrs) {
// this 上下文指向 outline 实例
this.attr()
console.log('attrs: ', attrs)
}
outline.$on('created', handler)
// 手动触发 created 事件
outline.$emit('created')
$off(topic[, token])
Description
$off() 用来取消订阅主题。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
token
- Type:
- Function | String
(可选)订阅主题的处理器函数或者唯一 Id 值。
- 为传递 token 参数:取消指定 topic 的订阅;
- 传递 token 参数:仅删除 topic 订阅信息中与 token 对应的事件处理器
Returns
- Type:
- Outline
Outline 对象,以便实现链式调用。
const outline = new Outline(Outline.DEFAULTS)
const handler = (msg) => {
console.log('handler:', msg)
}
outline.$on('created')
// 取消订阅 author 主题
outline.$off('created')
// 不会有任何反应,因为已经取消订阅了
outline.$emit('created')
Events
outline.js 从 3.21.0 开始提供了 6 事件。通过 outline.js 在 3.21.0 新添加的 $on() 方法监听。
created
事件名称 | 说明 | 回调参数 |
---|---|---|
created | Outline 实例配置信息初始化完成后触发,此时 DOM 元素还没有绘制。 | 返回实例最终的 attrs 配置属性的(对象)值。 |
Usage
const outline = new Outline()
outline.$on('created', function(attrs) {
// this 上下文就是 outline 实例
// attrs === outline.attr()
})
// 当 outline 实例的配置信息初始化完毕,就会触发 created 事件
outline.initialize(Outline.DEFAULTS)
mounted
事件名称 | 说明 | 回调参数 |
---|---|---|
mounted | Outline 实例的所有 DOM 元素绘制完毕后触发。 | -- |
Usage
const outline = new Outline()
outline.$on('mounted', function() {
// do something
})
// 当 outline 实例的所有 DOM 绘制完毕,就会触发 mounted 事件
outline.initialize(Outline.DEFAULTS)
enterReading
事件名称 | 说明 | 回调参数 |
---|---|---|
enterReading | 配置了 print 参数,在进入阅读模式后会触发。 | -- |
Usage
const defaults = Outline.DEFAULTS
// 需要配置 print 参数
defaults.print = {
element: '#article',
title: document.querySelector('.title')
}
const outline = new Outline(Outline.DEFAULTS)
outline.$on('enterReading', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
// 手动触发 enterReading 事件
outline.$emit('enterReading')
exitReading
事件名称 | 说明 | 回调参数 |
---|---|---|
exitReading | 配置了 print 参数,在离开阅读模式后会触发。 | -- |
Usage
const defaults = Outline.DEFAULTS
// 需要配置 print 参数
defaults.print = {
element: '#article',
title: document.querySelector('.title')
}
const outline = new Outline(Outline.DEFAULTS)
outline.$on('exitReading', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
// 手动触发 exitReading 事件
outline.$emit('exitReading')
beforeDestroy
事件名称 | 说明 | 回调参数 |
---|---|---|
beforeDestroy | Outline 实例销毁前事件,在调用 Outline 对象的实例 destroy() 方法后会触发。 | -- |
Usage
const outline = new Outline(Outline.DEFAULTS)
outline.$on('beforeDestroy', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
outline.destroy()
destroyed
事件名称 | 说明 | 回调参数 |
---|---|---|
destroyed | Outline 实例销毁后事件,在调用 Outline 对象的实例 destroy() 方法后会触发。 | -- |
Usage
const outline = new Outline(Outline.DEFAULTS)
outline.$on('beforeDestroy', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
outline.destroy()
outline.js - 自动生成文章导读(Table of Contents)导航的 JavaScript 工具。会自动分析文章中的标题( h1~h6 )标签,并生成文章段落层次结构的导读导航菜单。
创作灵感
AnchorJS 是 outline.js 的创作灵感来源。既然 AnchorJS 可创建标题的链接,为什么不直接给文章生成一个文章导读(Table of Contents)导航呢? 于是就有了outline.js。
特点(Features)
- 原生 JavaScript 编写,无需任何依赖;
- 支持 UMD 规范;
- 支持 E6 模块,提供功能独立的 ES6 模块;
- Anchors 模块:类似 AnchorJS 基础功能模块,自动分析段落层级;
- Drawer 模块:独立的侧滑窗口模块;
- Navigator 模块:独立的导航菜单模块;
- Toolbar 模块:独立的固定定位的工具栏模块;
- 拥有 AnchorJS 基础功能;
- 支持中文和英文标题文字生成ID;
- 支持生成独立的侧边栏导航菜单;
- 支持直接在文章中生成文章导读导航;
- 自动分析标题关系,生成段落层级索引值;
- 可以作为 jQuery 插件使用;
- 界面简洁大方;
- 配置灵活,丰富,让你随心所欲掌控 outline.js;
安装说明
outline.js 提供多种安装方式的支持: npm 安装、加载 CDN 资源、以及本地资源调用。
npm install
$ npm install -S @yaohaixiao/outline.js
CDN 调用
<script src="https://cdn.jsdelivr.net/gh/yaohaixiao/outline.js/outline.min.js"></script>
调用本地JS文件
<script src="path/to/outline.min.js"></script>
使用说明
outline.js 既支持在 node.js 环境中以 CommonJS 模块调用,也支持 ES6 模块方式加载。
// Node.js 环境中使用
const Outline = require('@yaohaixiao/outline.js')
// 作为 ES6 模块使用
import Outline from '@yaohaixiao/outline.js/src/outline'
// 调用其他独立模块
import Anchors from '@yaohaixiao/outline.js/src/anchors'
import Navigator from '@yaohaixiao/outline.js/src/navigator'
import Drawer from '@yaohaixiao/outline.js/src/drawer'
import Toolbar from '@yaohaixiao/outline.js/src/toolbar'
import Reader form '@yaohaixiao/outline.js/src/reader'
// 创建 Outline 实例
// 2.0.0 调整了配置参数,配置更加简单
const outline = new Outline({
// 文章显示区域的 DOM 元素或者选择器字符串
articleElement: '#article',
// 要收集的标题选择器
selector: 'h2,h3,h4,h5,h6',
// 负责文章区域滚动的元素
// String 类型 - 选择器字符串,默认值:html,body(window窗口)
// HTMLElement 类型 - DOM 元素
scrollElement: 'html,body',
// 文章导读菜单的位置
// relative - (默认值)创建独立的侧滑菜单
// sticky - 导航菜单将以 sticky 模式布局(需要确保菜单插入位置支持 sticky 模式布局)
// fixed - 导航菜单将以 fixed 模式布局,会自动监听滚动位置,模拟 sticky 布局
// sticky 和 fixed 布局时,需要设置 parentElement
// 2.0.0 暂时不支持在文章开始位置插入 chapters 导航菜单
position: 'sticky',
// 设置 position: relative 时,placment 定义侧滑菜单和 toolbar 导航位置:
// rtl - 菜单位置在窗口右侧,滑动动画为:right to left
// ltr - 菜单位置在窗口左侧,滑动动画为:left to right
// ttb - 菜单位置在窗口上方,滑动动画为:top to bottom
// btt - 菜单位置在窗口下方,滑动动画为:bottom to top
placement: '',
// 导航菜单将要插入的位置(DOM 元素)
// String 类型 - 选择器字符串
// HTMLElement 类型 - 插入的 DOM 元素
// 仅在 position 设置为 sticky 和 fixed 布局时有效
parentElement: '#aside',
// 是否显示段落章节编号
showCode: true,
// 标题图标链接的 URL 地址
// (默认)没有设置定制,点击链接页面滚动到标题位置
// 设置了链接地址,则不会滚动定位
anchorURL: '',
// DIYer的福利
// 独立侧滑菜单时,customClass 会追加到 drawer 侧滑窗口组件
// 在文章中显示导航菜单时,customClass 会追加到 chapters 导航菜单
customClass
});
// 可以在创建导航后,重置配置信息,重新生成新的导航
Outline.reload({
// 调整位直接在文章内生成导航
position: 'sticky',
articleElement: '#article'
})
Options
outline.js 有者丰富的配置选项,以便适应不同的展示方式。
articleElement
Description
- Type:
- String|HTMLElement
- Default:
- '#article'
- String:选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement:'DOM 元素;
可选,用来指定页面中显示文章正文的 DOM 节点或者选择器字符串。
// Default Selector
const outline = new Outline(Outline.DEFAULTS)
// Customize Selector
const outline = new Outline({
articleElement: $('#main')
})
selector
Description
- Type:
- String
- Default:
- 'h1,h2,h3,h4,h5,h6'
可选,用来指定 article 节点下,要生成导航的标题标签的选择器。
// Default selector
new Outline(Outline.DEFAULTS)
// Customize selector
new Outline({
selector: 'h2'
})
title
Description
- Type:
- String|Boolean
- Default:
- '目录'
可选,用来指定文章导读导航菜单的标题文字。设置空字符串或者 false,则不显示标题。在插入导航菜单的 DOM 元素已有标题时,可以设置 title: '' 或者 false。
说明:本 API 文档的导航菜单便是使用 outline.js 生成,并且没有设置 title。
(function(){
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = ''
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
outline = new Outline(Outline.DEFAULTS)
})()
scrollElement
Description
- Type:
- String|HTMLElement
- Default:
- 'html,body'
- String: 选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement: DOM 元素;
可选,负责文章区域滚动的元素:
// 默认是当前窗口滚动
new Outline(Outline.DEFAULTS)
// 指定滚动区域是 #main 元素
new Outline({
scrollElement: '#main'
})
position
Description
- Type:
- String
- Default:
- 'relative'
可选,用来指定文章导读导航菜单的显示位置:
- relative: (默认值)创建独立的侧滑菜单;
- sticky: 导航菜单将以 sticky 模式布局(需要确保菜单插入位置(DOM 节点)支持 sticky 模式布局);
- fixed: 导航菜单将模拟 sticky 布局,起初是普通定位,会自动监听滚动位置,但滚动到导航菜单顶部时,以 fixed 模式布局,模拟 sticky 布局效果;
当设置为 sticky 和 fixed 布局时,需要设置 parentElement。
注意:2.0.0 暂时不支持之前版本那种 inside 模式,不会自动在文章开始位置插入 chapters 导航菜单
// 默认生成独立的侧滑弹窗导航菜单
new Outline(Outline.DEFAULTS)
// 在页面内部插入导航菜单
new Outline({
// 在(文章的)侧边栏显示导航菜单
parentElement: '#aside',
// 或者 sticky 定位
position: 'fixed'
})
parentElement
Description
- Type:
- String
- Default:
- '#aside'
- String: 选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement: DOM 元素;
可选,导航菜单将要插入的位置(DOM 元素)。仅在 position 设置为 sticky 和 fixed 布局时有效。
// 在页面内部插入导航菜单
new Outline({
// 在(文章的)侧边栏显示导航菜单
parentElement: '#aside',
// 或者 sticky 定位
position: 'fixed'
})
placement
Description
- Type:
- String
- Default:
- 'rtl'
可选,设置 position: relative 时,placement 定义侧滑菜单和 toolbar 导航位置:
- rtl - 菜单位置在窗口右侧,滑动动画为:right to left(默认值);
- ltr - 菜单位置在窗口左侧,滑动动画为:left to right;
- ttb - 菜单位置在窗口上方,滑动动画为:top to bottom;
- btt - 菜单位置在窗口下方,滑动动画为:bottom to top;
// 默认是在窗口右侧显示侧滑导航菜单
new Outline(Outline.DEFAULTS)
// 调整为在窗口右侧显示侧滑导航菜单
new Outline({
placement: 'ltr'
})
stickyHeight
Description
- Type:
- Number
- Default:
- 0
可选,用来指定页面中其它 sticky 或者模拟 skicky 的 fiexed 定位的 DOM 元素的高度。
这些 sticky 元素脱离了正常的流布局后,原来 h1~h6 标题标签的 offsetTop 计算会出现偏差。sticky 元素会遮挡标题,因此针对页面中有其它sticky 节点时,需要设置 stickyHeight 高度。以便 outline.js 根据 stickyHeight 和计算出的标题的 offsetTop 值重新计算滚动定位。
说明:outline.js 主要用于文章详情页面,stickyHeight 仅针对 top: 0,且 sticky 定位元素在文章内容区域上方的位置;
const defaults = Outline.DEFAULTS
// 设置 stickyHeight(outline.js 的示例页面的主标题元素的高度)
defaults.stickyHeight = 86
// 默认生成独立的侧滑弹窗导航菜单
new Outline(defaults)
showCode
Description
- Type:
- Boolean
- Default:
- true
可选,是否显示段落章节编号(注意:3.38.2 开始 showCode 默认为 false):
- false - 显示编号;
- false - 不显示编号(默认值);
animationCurrent
Description
- Type:
- Boolean
- Default:
- true
可选,是否采用动画定位高亮当前的章节标题:
- true - 采用动画定位高亮(默认值);
- false - 采用高亮当前章节标题的链接文字并加粗文字;
hasToolbar
Description
- Type:
- Boolean
- Default:
- true
可选,是否显示侧边的按钮工具栏:
- true - 显示按钮工具栏(默认值);
- false - 不显示按钮工具栏;
closeOnClickModal
Description
- Type:
- Boolean
- Default:
- true
可选,点击空白处(非独立导航菜单),收起导航菜单:
- true - 点击空白处,收起菜单(默认值);
- false - 点击空白处,不收起菜单;
showNavModalFirst
Description
- Type:
- Boolean
- Default:
- false
可选,有独立导航菜单时,是否默认显示菜单:
- false - 默认先显示按钮工具栏(默认值);
- true - 默认先显示独立导航菜单弹窗;
anchorURL
Description
- Type:
- String
- Default:
- ''
可选,用来指定文章标题锚点链接图标的链接地址:
// Default URL - 默认链接,点击图标,页面会滚动到当前标题位置
new Outline()
// Customize URL - 直接打开链接了
new Outline({
anchorURL: 'http://www.yaohaixiao.com/'
})
homepage
Description
- Type:
- String
- Default:
- ''
可选,用来指定文章标题锚点链接图标的链接地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 Homepage 图标的按钮
outline.reload({
homepage: 'http://www.yaohaixiao.com/'
})
git
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 git 图标的按钮
outline.reload({
git: 'https://github.com/yaohaixiao/outline.js'
})
tags
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库 tags 页面地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 tags 图标的按钮
outline.reload({
tags: 'https://github.com/yaohaixiao/outline.js/tags'
})
issues
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库 issues 页面地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 issues 图标的按钮
outline.reload({
issues: 'https://github.com/yaohaixiao/outline.js/issues'
})
tools
Description
- Type:
- Array
- Default:
- []
可选,自定义的按钮配置项。tools 中的按钮会排列显示在 homepage, git, tags, issues 等按钮之后。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
// 侧边栏的 Toolbar 会多出一个 git 图标的按钮
outline.reload({
git: 'https://github.com/yaohaixiao/outline.js',
tools: [
{
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
}
]
})
reader
Since
3.32.0
说明:3.32.0 以前的版本,此属性的原名为 print,另外,reader.element 属性也调整为了 reader.target。请升级后在初始化配置参数时注意调整。
Description
- Type:
- Object
- Default:
- {target: '', title: '', enterReadingTip: ‘进入阅读模式,按 ESC 键可退出阅读模式’, allowSpeak: false}
可选,自定义的是否自动为文章页面创建打印样式。
- target:
- (必须)要打印的文章区域,DOM 元素或者选择器字符串;
- title:
- (可选)要打印的文章标题。如果 element 区域有 h1 标签则无需设置。可以直接设置标题文本,也可以是文章页的主标题 DOM 元素;
- enterReadingTip:
- (可选)进入阅读模式的提示文本,默认值:‘进入阅读模式,按 ESC 键可退出阅读模式’;
- allowSpeak:
- (可选)针对现代浏览器支持 Web Speech API,是否开启语音阅读功能。默认值:false;
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式',
// 开启语音阅读
allowSpeak: true
}
outline = new Outline(defaults)
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
customClass
Description
- Type:
- String
- Default:
- ''
可选,(DIYer福利)设置自定义样式的 class 名称:
- '' - 采用默认 outline.js 的 UI 界面(默认值);
- 设置自定义样式 - 自己根据需求设置个性化的 UI 界面;
// Default UI
new Outline(Outline.DEFAULTS)
// Customized
new Outline({
// 设置深色配置界面
customClass: 'theme-dark'
})
afterScroll
Description
- Type:
- Function
- Default:
- null
可选,当点击导航菜单、文章中的 anchor 图标(#)或者上下滚动按钮会触发滚动,afterScroll() 回调函数会在滚动结束后触发执行。
Parameters
target
- Type:
- String
afterScroll() 回调函数有一个参数 target,返回的是当前点击的 DOM 元素的名称:
- 'anchor':表示点击的是 anchor 图标,即文章中标题前的 “#” 图标,此时的 this 上下文指向 outline.anchors;
- 'chapter':表示点击的是导航菜单的链接,此时的 this 上下文指向 outline.chapters;
- 'up':表示点击的是工具栏的向上按钮,此时的 this 上下文指向 outline.toolbar;
- 'down':表示点击的是工具栏的向下按钮,此时的 this 上下文指向 outline.toolbar;
注意:因为配置 afterScroll 回调函数会因为 4 个不同的 DOM 触发,所以需要根据 target 返回的值和此时的 this 指向判断处理。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterScroll = function(target) {
// 当然,如果你希望无论是点击什么都执行,就不需要判断了
// 直接些通用的滚动结束的逻辑即可
switch(target){
case 'anchor':
// 针对点击 # 的处理逻辑
break
case 'chapter':
// 针对点击导航菜单的处理逻辑
break
case 'up':
// 针对点击向上滚动按钮的处理逻辑
break
case 'down':
// 针对点击向下滚动按钮的处理逻辑
break
}
}
outline = new Outline(Outline.DEFAULTS)
afterSticky
Description
- Type:
- Function
- Default:
- null
可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。
说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。
Parameters
closed
- Type:
- Boolean
closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态
isSticky
- Type:
- Boolean
isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。
const $header = document.querySelector('#header')
const HEADER_STICKY = 'header_sticky'
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterSticky = function(closed, isStickying) {
const $nav = this.$el
const BORDER_RIGHT = 'utils-border-right'
if (closed) {
return false
}
if (isStickying) {
$nav.classList.add(BORDER_RIGHT)
$header.classList.add(HEADER_STICKY)
} else {
$nav.classList.remove(BORDER_RIGHT)
$header.classList.remove(HEADER_STICKY)
}
}
defaults.afterToggle = function(closed, isStickying) {
if (!isStickying) {
return false
}
if (closed) {
$header.classList.remove(HEADER_STICKY)
} else {
$header.classList.add(HEADER_STICKY)
}
}
outline = new Outline(Outline.DEFAULTS)
afterToggle
Description
- Type:
- Function
- Default:
- null
可选,当导航菜单隐藏或者显示的时候,会触发执行 afterToggle 回调函数。
说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。
Parameters
closed
- Type:
- Boolean
closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态
isSticky
- Type:
- Boolean
isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。
const $header = document.querySelector('#header')
const HEADER_STICKY = 'header_sticky'
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterSticky = function(closed, isStickying) {
const $nav = this.$el
const BORDER_RIGHT = 'utils-border-right'
if (closed) {
return false
}
if (isStickying) {
$nav.classList.add(BORDER_RIGHT)
$header.classList.add(HEADER_STICKY)
} else {
$nav.classList.remove(BORDER_RIGHT)
$header.classList.remove(HEADER_STICKY)
}
}
defaults.afterToggle = function(closed, isStickying) {
if (!isStickying) {
return false
}
if (closed) {
$header.classList.remove(HEADER_STICKY)
} else {
$header.classList.add(HEADER_STICKY)
}
}
outline = new Outline(Outline.DEFAULTS)
chapterTextFilter
Description
- Type:
- Function
- Default:
- null
可选,API 文档中,正文的方法会添加参数等信息,例如:getChapters(headings, showCode, chapterTextFilter)。而在 chapters 导航菜单,我希望显示为 getChapters(),这时我们就可以借助 chapterTextFilter 回调函数。对原始的文本进行过滤,返回我们期望的 getChapters() 文本。
Parameters
text
- Type:
- String
chapterTextFilter() 回调函数有一个参数 text,返回的是当前 hx 标题中的文本。
Returns
- Type:
- String
返回最终希望生成的标题文本内容。
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = false
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
defaults.chapterTextFilter = (text) => {
return text.replace(/\(.*?\)/, '()')
}
outline = new Outline(defaults)
anchorLinkFilter
Description
- Type:
- Function
- Default:
- null
可选,API 文档中,正文标题的锚点链接地址生成函数。
Parameters
tag
- Type:
- String
当前标题的 tagName。小写的:h1~6。
title
- Type:
- String
当前标题的文本内容。
id
- Type:
- Number
outline.js 为当前标题生成 id 号。
Returns
- Type:
- String
返回最终希望生成锚点链接的文本内容。
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = false
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
defaults.chapterTextFilter = (text) => {
return text.replace(/\(.*?\)/, '()')
}
defaults.anchorLinkFilter = (tag, title, id) => {
return `${tag}-${title}-${id}`
}
outline = new Outline(defaults)
Properties
outline.js 重构后,对外放 4 个重要的属性:anchors、drawer、chapters、reader 和 toolbar。它们都是独立的对象实例,提供了 outline.js 所有的能力(属性和方法)。
attrs
Description
- Type:
- Object
存储的是 Outline 对象当前使用中的配置选项:
说明:建议使用 attr(prop) 方法来获取属性,避免直接调用属性。
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 查看全部配置信息
outline.attrs
$article
Since
3.32.0
Description
- Type:
- HTMLElement
存储的是 Outline 对象要分析的文章正文内容显示区域的 DOM 元素:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 获取文章正文内容显示区域的 DOM 元素
outline.$article
$scrollElement
Since
3.34.0
Description
- Type:
- HTMLElement
存储的是 Outline 对象要分析的控制文章内容滚动的 DOM 元素:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 获取文章正文内容显示区域的 DOM 元素
outline.$scrollElement
buttons
Description
- Type:
- Array
存储的是 Outline 对象当前工具栏的完整的按钮配置信息:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 查看全部按钮配置信息
outline.buttons
anchors
Description
- Type:
- Object
Anchors 模块:类似 AnchorJS 基础功能模块,自动分析段落层级。
// 仅展示 API 中对外公开的方法和属性
class Anchors extends Base {
constructor(options) {
super()
this.attrs = Anchors.DEFAULTS
this.$articleElement = null
this.$scrollElement = null
this.$headings = []
this.chapters = []
// 省略其它逻辑...
}
getChapters(isTreeStructured = false) {
const chapters = this.chapters
return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters
}
count() {
return this.chapters.length
}
attr(prop, value) {
const attrs = this.attrs
if (isString(prop)) {
// 只能扩展 attrs 中已有的属性
if (value && hasOwn(attrs, prop)) {
// 更新单个配置信息
attrs[prop] = value
return this
}
// 只传递 prop 参数,则返回对应的属性值
return attrs[prop]
} else if (isObject(prop)) {
// 批量更新配置信息
extend(attrs, prop)
return this
} else if (arguments.length === 0) {
// 不传递参数,直接返回整个
return attrs
}
return this
}
render() {
// 省略其它逻辑...
return this
}
scrollTo(top, after) {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Anchors.DEFAULTS = {
scrollElement: 'html,body',
articleElement: '#article',
selector: 'h1,h2,h3,h4,h5,h6',
anchorURL: '',
hasAnchor: true,
isAtStart: true,
showCode: false,
created: null,
mounted: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Anchors
navigator
Description
- Type:
- Object
Navigator 模块:独立的导航菜单模块;
// 仅展示 API 中对外公开的方法和属性
class Navigator extends Base {
constructor(options) {
super()
this.attrs = Navigator.DEFAULTS
this.$el = null
this.$title = null
this.$main = null
this.$list = null
this.$placeholder = null
this.$parentElement = null
this.$scrollElement = null
this.chapters = []
this.closed = false
this.active = 0
this.offsetTop = 0
this.$active = null
this.timer = null
this.playing = false
// 省略其它逻辑...
}
isClosed() {
return this.closed
}
isSticky() {
const position = this.attr('position')
return position === 'sticky'
}
isFixed() {
const position = this.attr('position')
return position === 'fixed'
}
isInside() {
return this.isFixed() || this.isSticky()
}
isOutside() {
return !this.isInside()
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
highlight(id) {
// 省略其它逻辑...
return this
}
sticky() {
// 省略其它逻辑...
return this
}
scrollTo(top, after) {
// 省略其它逻辑...
return this
}
show() {
// 省略其它逻辑...
return this
}
hide() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Navigator.DEFAULTS = {
parentElement: '',
scrollElement: '',
selector: '',
active: 0,
closed: false,
showCode: true,
position: 'relative',
chapters: [],
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Navigator
drawer
Description
- Type:
- Object
Drawer 模块:独立的侧滑窗口模块。
// 仅展示 API 中对外公开的方法和属性
class Drawer extends Base {
constructor(options) {
super()
this.attrs = Drawer.DEFAULTS
this.title = ''
this.closed = true
this.$el = null
this.$modal = null
this.$header = null
this.$title = null
this.$close = null
this.$main = null
this.$footer = null
this.$overlay = null
this.zIndex = 0
// 省略其它逻辑...
}
isClosed() {
return this.closed
}
setTitle() {
this.attr('title', title)
this.title = title
this.$title.innerHTML = title
return this
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
open() {
// 省略其它逻辑...
return this
}
close() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Drawer.DEFAULTS = {
placement: 'rtl',
title: '标题',
size: 'regular',
hasClose: true,
hasOverlay: true,
hasOffset: false,
hasPadding: true,
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Drawer
reader
Description
- Type:
- Object
Reader 模块:独立的阅读视图模块。
// 仅展示 API 中对外公开的方法和属性
class Drawer extends Base {
constructor(options) {
super()
this.attrs = cloneDeep(Reader.DEFAULTS)
this.reading = false
this.$target = null
this.$paper = null
this.$title = null
this.$article = null
this.$icon = null
// 省略其它逻辑...
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
refresh() {
// 省略其它逻辑...
return this
}
enter() {
// 省略其它逻辑...
return this
}
exit() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
print() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Reader.DEFAULTS = {
target: '',
title: '标题',
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
export default Reader
toolbar
Description
- Type:
- Object
Toolbar 模块:独立的固定定位的工具栏模块;
// 仅展示 API 中对外公开的方法和属性
class Toolbar extends Base {
constructor(options) {
super()
this.attrs = Drawer.DEFAULTS
this.title = ''
this.closed = true
this.$el = null
this.$modal = null
this.$header = null
this.$title = null
this.$close = null
this.$main = null
this.$footer = null
this.$overlay = null
// 省略其它逻辑...
}
isDisabled(name) {
const buttons = this.attr('buttons')
let button
if (name) {
button = buttons.find((option) => option.name === name)
return !!(button && button.disabled)
}
return this.disabled
}
isClosed() {
return this.closed
}
highlight() {
// 省略其它逻辑...
return this
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
add(button) {
// 省略其它逻辑...
return this
}
remove(name) {
// 省略其它逻辑...
return this
}
switch(name, enabled) {
// 省略其它逻辑...
return this
}
enable(name) {
// 省略其它逻辑...
return this
}
disable(name) {
// 省略其它逻辑...
return this
}
show() {
// 省略其它逻辑...
return this
}
hide() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Toolbar.DEFAULTS = {
placement: 'ltr',
closed: false,
disabled: false,
buttons: [],
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterDisabled: null,
afterEnabled: null,
beforeDestroy: null,
afterDestroy: null
}
Drawer.zIndex = 2000
export default Toolbar
Outline.DEFAULTS
Description
- Type:
- Object
静态属性,存储的是 Outline 对象默认配置选项:
Outline.DEFAULTS = {
// 文章显示区域的 DOM 元素或者选择器字符串
articleElement: '#article',
// 要收集的标题选择器
selector: 'h2,h3,h4,h5,h6',
// 指定文章导读导航菜单的标题文字。
// 设置空字符串或者 false,则不显示标题
// 在插入导航菜单的 DOM 元素已有标题时,可以设置 title: '' 或者 false
title: '目录',
// 负责文章区域滚动的元素
// String 类型 - 选择器字符串,默认值:html,body(window窗口)
// HTMLElement 类型 - DOM 元素
// 注意:如果您使用的是比较旧的 chrome 浏览器,例如:Chromium 60.x 版本或者以下版本
// 请手动设置 scrollElement = 'body',否则点击导航无法滚动定位
scrollElement: 'html,body',
// 文章导读菜单的位置
// relative - (默认值)创建独立的侧滑菜单
// sticky - 导航菜单将以 sticky 模式布局(需要确保菜单插入位置支持 sticky 模式布局)
// fixed - 导航菜单将以 fixed 模式布局,会自动监听滚动位置,模拟 sticky 布局
// sticky 和 fixed 布局时,需要设置 parentElement
// 2.0.0 暂时不支持之前版本那种 inside 模式,不会自动在文章开始位置插入 chapters 导航菜单
position: 'sticky',
// 导航菜单将要插入的位置(DOM 元素)
// String 类型 - 选择器字符串
// HTMLElement 类型 - 插入的 DOM 元素
// 仅在 position 设置为 sticky 和 fixed 布局时有效
parentElement: '#aside',
// 设置 position: relative 时,placment 定义侧滑菜单和 toolbar 导航位置:
// rtl - 菜单位置在窗口右侧,滑动动画为:right to left
// ltr - 菜单位置在窗口左侧,滑动动画为:left to right
// ttb - 菜单位置在窗口上方,滑动动画为:top to bottom
// btt - 菜单位置在窗口下方,滑动动画为:bottom to top
placement: 'rtl',
// 页面中其它 sticky 或者模拟 skicky 的 fiexed 定位的 DOM 元素的高度。例如 wordpress 系统中,
// 就会有 sticky 定位的导航菜单。这些 sticky 元素脱离了正常的流布局后,原来 h1~h6 标题标签的
// offsetTop 计算会出现偏差。sticky 元素会遮挡标题,因此针对页面中有其它 sticky 元素会遮挡标题,
// 因此针对 sticky 布局时,需要设置 stickyHeight 高度。outline.js 会根据 stickyHeight 和计
// 算出的标题的 offsetTop 值重新计算滚动定位;
// 说明:outline.js 主要用于文章详情页面,
// 因此 stickyHeight 仅针对 top: 0,且 sticky 定位元素在文章内容区域上方的位置;
stickyHeight: 0,
// 是否显示标题编号(注意:3.38.2 开始 showCode 默认为 false)
showCode: false,
// 是否显示侧边的按钮工具栏
hasToolbar: true,
// 指定是否采用动画定位高亮当前的章节标题,默认值:true
// 当值为 false 时,则采用高亮当前章节标题的链接文字并加粗文字
// 如果喜欢更简洁的高亮效果,可以选择设置为 false
animationCurrent: true,
// 标题图标链接的 URL 地址
// (默认)没有设置定制,点击链接页面滚动到标题位置
// 设置了链接地址,则不会滚动定位
anchorURL: '',
// 指定当前站点主页地址
homepage: '',
// 指定git仓库地址
git: '',
// 指定git仓库中的 tags 地址
tags: '',
// 指定git仓库中的 issues 地址
issues: '',
// 自定义按钮配置
tools: [],
// 为文章页添加基础的打印样式
// 如果您的页面已经有打印样式,就无需设置了
reader: {
//(必须)要打印的文章区域,DOM 元素或者选择器字符串。
target: '',
// (可选)要打印的文章标题。如果 element 区域有 h1 标签则无需设置。
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素
title: '',
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
},
// DIYer的福利
// 独立侧滑菜单时,customClass 会追加到 drawer 侧滑窗口组件
// 在文章中显示导航菜单时,customClass 会追加到 chapters 导航菜单
customClass,
// position: fixed,当导航菜单样式进入 fixed 定位后,触发的回调函数
afterSticky: null,
// 当导航菜单隐藏或者显示后,触发的回调函数
afterToggle: null,
// 当点击上下滚动按钮,导航菜单或者文章中的 # 图标,滚动结束后触发的回调函数
afterScroll: null,
// 文档的标题文本过滤回调函数
// API 文档中,正文的方法会添加参数等信息,例如:getChapters(headings, showCode, chapterTextFilter)
// 而在 chapters 导航菜单,我希望显示为 getChapters(),这时我们就可以借助 chapterTextFilter 回调函数
// 对原始的文本进行过滤,返回我们期望的 getChapters() 文本
chapterTextFilter: null,
// 锚点链接的生成回调函数
// anchorLinkFilter(tag, title, id)
// tag - 当前标题的 tagName 小写:h1~6
// title - 当前标题的文本内容
// id - outline 为当前标题生成的 id 号,是个数值
// 如果设置了 anchorURL,则会统一使用 anchorURL 参数的地址
anchorLinkFilter: null
}
Methods
outline.js 的提供的方法如下:
attr([prop, value])
Description
attr() 方法用来设置或者获取初始化时配置的 attrs 信息的。
Parameters
prop
- Type:
- String|HTMLElement
(可选)options 中的属性名称或者要配置的 attrs 信息。
value
- Type:
- Any
(可选)要设置的 prop 属性的值
- 不传递任何参数:返回完整的 attrs 配置信息;
- 仅传递 prop:
- String: 返回 attrs 配型信息中与 prop 对应的值;
- Object: 用来设置 attrs 配置信息;
- 同时传递 prop 和 value 参数:设置 attrs 配置信息中的某个属性值;
Returns
- Type:
- Any
配置信息 attrs 的属性值或者 Outline 对象。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.attr('title') // -> 'Outline v2.0.0'
outline.attr('title', '目录') // -> 设置 title 配置信息的值为 '目录'
outline.attr() // -> 返回完整配置参数 attrs 信息
isExpanded()
Description
isExpanded() 方法来判断导航菜单是否展开(可见)。
Returns
- Type:
- Boolean
返回菜单展开状态。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 展开
outline.toggle()
outline.isExpanded() // -> true
// 收起
outline.toggle()
outline.isExpanded() // -> false
getChapters([isTreeStructured])
Description
getChapters() 方法来获取 outline.js 分析的文章段落层次数据。
Parameters
isTreeStructured
- Type:
- Boolean
- Default:
- false
(可选)是否为树结构的数据。
- false: (默认值)输出打平的一维数组格式数据;
- true: 输出树结构格式的数据;
Returns
- Type:
- Object
outline.js 分析的文章段落层次数据。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// 一维数组格式数据
// -> [{
{
id: 2,
pid: -1,
level: 1,
rel: "heading-2",
text: "安装说明",
index: 3,
code: "3",
},
{
id: 3,
pid: 2,
level: 2,
rel: "heading-3",
text: "npm install",
index: 1,
code: "3.1",
children: []
},
{
id: 4,
pid: 2,
level: 2,
rel: "heading-4",
text: "CDN 调用",
index: 2,
code: "3.2",
children: []
},
{
id: 5,
pid: 2,
level: 2,
rel: "heading-5",
text: "调用本地JS文件",
index: 3,
code: "3.3",
children: []
}
}]
outline.getChapters(true)
// 有 children 属性的树结构对象数组
// -> [{
code: "3",
id: 2,
index:3,
level:1,
pid:-1,
rel: "heading-2"
text:"安装说明",
children: [
{
id: 3,
pid: 2,
level: 2,
rel: "heading-3",
text: "npm install",
index: 1,
code: "3.1",
children: []
},
{
id: 4,
pid: 2,
level: 2,
rel: "heading-4",
text: "CDN 调用",
index: 2,
code: "3.2",
children: []
},
{
id: 5,
pid: 2,
level: 2,
rel: "heading-5",
text: "调用本地JS文件",
index: 3,
code: "3.3",
children: []
}
]
}]
outline.destroy()
outline.getChapters()
// 调用 destroy() 方法后,所有数据都清空了
// -> []
count()
Description
count() 方法来获取 outline.js 分析的文章段落层次数据的数量。
Returns
- Type:
- Number
outline.js 分析的 chapters 数据数量。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// -> [{
code: "1",
id: 0,
index: 1,
level: 1,
pid: -1
rel: "heading-0"
text: "创作灵感"
}]
outline.count()
// -> 1 就是 getChapters() 返回数据的数量
addButton(button)
Description
addButton() 方法添加自定义的工具栏按钮。
Parameters
button
- Type:
- Object|Array
(必须)单个按钮的配置信息或者多个按钮的配置信息。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
outline.addButton({
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
type: 'click',
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
})
removeButton(name)
Description
removeButton() 方法移除工具栏按钮。
Parameters
name
- Type:
- String
(必须)按钮名称。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
outline.addButton({
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
type: 'click',
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
})
setTimeout(() => {
outline.removeButton('clean')
}, 5000)
toTop([afterScroll])
Description
toTop() 方法会控制页面(scrollElement)滚动到顶部。
Parameters
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toTop() // 页面将滚动到顶部,向上滚动按钮消失
outline.toTop(() => {
console.log('滚动结束‘)
})
toBottom([afterScroll])
Description
toBottom() 方法会控制页面(scrollElement)滚动到顶部。
Parameters
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toBottom() // 页面将滚动到底部,向下滚动按钮消失
outline.toBottom(() => {
console.log('滚动结束‘)
})
scrollTo(top[,afterScroll])
Description
scrollTo() 方法用于将窗口的滚动条滚动到指定 top 值的位置。
Parameters
top
- Type:
- Number
(必选)页面要滚动的 top 数值。
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// -> 页面将滚动到距离顶部 200 像素的位置
outline.scrollTo(200)
outline.scrollTo(200, () => {
console.log('滚动结束‘)
})
expand()
Description
expand() 方法来展开导航菜单。
Returns
- Type:
- Number
Outline 对象,便于链式调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 收起菜单
outline.expand()
outline.isExpanded() // -> true
collapses()
Description
collapses() 方法来收起导航菜单。
Returns
- Type:
- Number
Outline 对象,便于链式调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 收起菜单
outline.collapses()
outline.isExpanded() // -> false
toggle()
Description
toggle() 方法用来隐藏或显示侧边栏菜单。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toggle() // 如果已经隐藏,则显示
outline.toggle() // 如果已显示,则隐藏
print()
Description
print() 方法用于启动打印界面,打印当前文章。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 如果浏览器支持 print() 打印,则启动打印界面
outline.print()
enterReading()
Since
3.32.0
Description
enterReading() 方法来切换进入阅读模式。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
outline.enterReading()
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
exitReading()
Since
3.32.0
Description
exitReading() 方法用来从阅读模式切换回普通文章页面模式。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
outline.enterReading()
outline.exitReading()
演示地址:https://yaohaixiao.github.io/examples/outline.js/flex.html
switchReading()
Since
3.32.0
Description
switchReading() 方法用来在阅读模式和回普通文章页面模式相互切换。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
// 进入阅读模式
outline.switchReading()
// 退出阅读模式
outline.switchReading()
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
destroy()
Description
destroy() 方法用于移除所有绘制的 DOM 节点,并移除绑定的事件处理器,同时重置所有 attrs 配置信息和 data 信息。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// -> [{
code: "1",
id: 0,
index: 1,
level: 1,
pid: -1
rel: "heading-0"
text: "创作灵感"
}]
outline.destroy()
outline.getChapters()
// 调用 destroy() 方法后,所有数据都清空了
// -> []
refresh()
Description
refresh() 方法是(在文章政委内容改变后)重新绘制导航信息的方法:
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
showCode: true
})
const REFRESH_METHOD = '<h3>添加 refresh() 方法</h3>' +
'<p>refresh() 方法是(在文章政委内容改变后)重新绘制导航信息的方法</p>'
outline.$article.innerHTML += REFRESH_METHOD
// 根据新的内容重新绘制导读信息
outline.refresh()
reload(options)
Description
reload (options) 方法是(根据新的配置信息)重启程序方法:
- 先移除所有绘制的 DOM 元素和绑定的事件处理器;
- 重新初始化程序;
Parameters
options
- Type:
- Object
(可选)初始化的配置参数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
showCode: true
})
// 重启后,将不再显示段落层次编号
outline.reload({
showCode: false
})
$emit(topic[, data, async = true])
Description
$emit()方法用来发布订阅主题信息。
outline.js 默认是采用异步方式发布的。以确保在消费者处理主题时,主题的发起者不会被阻止。 当然 $emit() 方法也支持同步主题发布。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
data
- Type:
- Object
(可选)消息传递的数据对象。
async
- Type:
- Boolean
- Default:
- true
(可选) 是否异步发布。默认值:true。
- 当 async 设置为 true(默认) 时,异步发布;
- 当 async 设置为 false 时,同步发布;
Returns
- Type:
- Outline
Outline 对象,以便实现链式调用。
const outline = new Outline(Outline.DEFAULTS)
const handler = (msg) => {
console.log(msg)
}
outline.$on('created', handler)
outline.$on('mounted', handler)
// 异步发布
outline.$emit('mounted') // -> 'ok'
// 同步发布
// 延迟10毫秒:应该看输出 ok 后输出
outline.$emit('created')
$on(topic, handler)
Description
$on() 方法用来订阅主题,并给出处理器函数。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
handler
- Type:
- Function
((必须)主题的处理器函数。
Returns
- Type:
- String。
唯一的 token 字符串,例如:'guid-1'。
const outline = new Outline(Outline.DEFAULTS)
const handler = function(attrs) {
// this 上下文指向 outline 实例
this.attr()
console.log('attrs: ', attrs)
}
outline.$on('created', handler)
// 手动触发 created 事件
outline.$emit('created')
$off(topic[, token])
Description
$off() 用来取消订阅主题。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
token
- Type:
- Function | String
(可选)订阅主题的处理器函数或者唯一 Id 值。
- 为传递 token 参数:取消指定 topic 的订阅;
- 传递 token 参数:仅删除 topic 订阅信息中与 token 对应的事件处理器
Returns
- Type:
- Outline
Outline 对象,以便实现链式调用。
const outline = new Outline(Outline.DEFAULTS)
const handler = (msg) => {
console.log('handler:', msg)
}
outline.$on('created')
// 取消订阅 author 主题
outline.$off('created')
// 不会有任何反应,因为已经取消订阅了
outline.$emit('created')
Events
outline.js 从 3.21.0 开始提供了 6 事件。通过 outline.js 在 3.21.0 新添加的 $on() 方法监听。
created
事件名称 | 说明 | 回调参数 |
---|---|---|
created | Outline 实例配置信息初始化完成后触发,此时 DOM 元素还没有绘制。 | 返回实例最终的 attrs 配置属性的(对象)值。 |
Usage
const outline = new Outline()
outline.$on('created', function(attrs) {
// this 上下文就是 outline 实例
// attrs === outline.attr()
})
// 当 outline 实例的配置信息初始化完毕,就会触发 created 事件
outline.initialize(Outline.DEFAULTS)
mounted
事件名称 | 说明 | 回调参数 |
---|---|---|
mounted | Outline 实例的所有 DOM 元素绘制完毕后触发。 | -- |
Usage
const outline = new Outline()
outline.$on('mounted', function() {
// do something
})
// 当 outline 实例的所有 DOM 绘制完毕,就会触发 mounted 事件
outline.initialize(Outline.DEFAULTS)
enterReading
事件名称 | 说明 | 回调参数 |
---|---|---|
enterReading | 配置了 print 参数,在进入阅读模式后会触发。 | -- |
Usage
const defaults = Outline.DEFAULTS
// 需要配置 print 参数
defaults.print = {
element: '#article',
title: document.querySelector('.title')
}
const outline = new Outline(Outline.DEFAULTS)
outline.$on('enterReading', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
// 手动触发 enterReading 事件
outline.$emit('enterReading')
exitReading
事件名称 | 说明 | 回调参数 |
---|---|---|
exitReading | 配置了 print 参数,在离开阅读模式后会触发。 | -- |
Usage
const defaults = Outline.DEFAULTS
// 需要配置 print 参数
defaults.print = {
element: '#article',
title: document.querySelector('.title')
}
const outline = new Outline(Outline.DEFAULTS)
outline.$on('exitReading', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
// 手动触发 exitReading 事件
outline.$emit('exitReading')
beforeDestroy
事件名称 | 说明 | 回调参数 |
---|---|---|
beforeDestroy | Outline 实例销毁前事件,在调用 Outline 对象的实例 destroy() 方法后会触发。 | -- |
Usage
const outline = new Outline(Outline.DEFAULTS)
outline.$on('beforeDestroy', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
outline.destroy()
destroyed
事件名称 | 说明 | 回调参数 |
---|---|---|
destroyed | Outline 实例销毁后事件,在调用 Outline 对象的实例 destroy() 方法后会触发。 | -- |
Usage
const outline = new Outline(Outline.DEFAULTS)
outline.$on('beforeDestroy', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
outline.destroy()
outline.js - 自动生成文章导读(Table of Contents)导航的 JavaScript 工具。会自动分析文章中的标题( h1~h6 )标签,并生成文章段落层次结构的导读导航菜单。
创作灵感
AnchorJS 是 outline.js 的创作灵感来源。既然 AnchorJS 可创建标题的链接,为什么不直接给文章生成一个文章导读(Table of Contents)导航呢? 于是就有了outline.js。
特点(Features)
- 原生 JavaScript 编写,无需任何依赖;
- 支持 UMD 规范;
- 支持 E6 模块,提供功能独立的 ES6 模块;
- Anchors 模块:类似 AnchorJS 基础功能模块,自动分析段落层级;
- Drawer 模块:独立的侧滑窗口模块;
- Navigator 模块:独立的导航菜单模块;
- Toolbar 模块:独立的固定定位的工具栏模块;
- 拥有 AnchorJS 基础功能;
- 支持中文和英文标题文字生成ID;
- 支持生成独立的侧边栏导航菜单;
- 支持直接在文章中生成文章导读导航;
- 自动分析标题关系,生成段落层级索引值;
- 可以作为 jQuery 插件使用;
- 界面简洁大方;
- 配置灵活,丰富,让你随心所欲掌控 outline.js;
安装说明
outline.js 提供多种安装方式的支持: npm 安装、加载 CDN 资源、以及本地资源调用。
npm install
$ npm install -S @yaohaixiao/outline.js
CDN 调用
<script src="https://cdn.jsdelivr.net/gh/yaohaixiao/outline.js/outline.min.js"></script>
调用本地JS文件
<script src="path/to/outline.min.js"></script>
使用说明
outline.js 既支持在 node.js 环境中以 CommonJS 模块调用,也支持 ES6 模块方式加载。
// Node.js 环境中使用
const Outline = require('@yaohaixiao/outline.js')
// 作为 ES6 模块使用
import Outline from '@yaohaixiao/outline.js/src/outline'
// 调用其他独立模块
import Anchors from '@yaohaixiao/outline.js/src/anchors'
import Navigator from '@yaohaixiao/outline.js/src/navigator'
import Drawer from '@yaohaixiao/outline.js/src/drawer'
import Toolbar from '@yaohaixiao/outline.js/src/toolbar'
import Reader form '@yaohaixiao/outline.js/src/reader'
// 创建 Outline 实例
// 2.0.0 调整了配置参数,配置更加简单
const outline = new Outline({
// 文章显示区域的 DOM 元素或者选择器字符串
articleElement: '#article',
// 要收集的标题选择器
selector: 'h2,h3,h4,h5,h6',
// 负责文章区域滚动的元素
// String 类型 - 选择器字符串,默认值:html,body(window窗口)
// HTMLElement 类型 - DOM 元素
scrollElement: 'html,body',
// 文章导读菜单的位置
// relative - (默认值)创建独立的侧滑菜单
// sticky - 导航菜单将以 sticky 模式布局(需要确保菜单插入位置支持 sticky 模式布局)
// fixed - 导航菜单将以 fixed 模式布局,会自动监听滚动位置,模拟 sticky 布局
// sticky 和 fixed 布局时,需要设置 parentElement
// 2.0.0 暂时不支持在文章开始位置插入 chapters 导航菜单
position: 'sticky',
// 设置 position: relative 时,placment 定义侧滑菜单和 toolbar 导航位置:
// rtl - 菜单位置在窗口右侧,滑动动画为:right to left
// ltr - 菜单位置在窗口左侧,滑动动画为:left to right
// ttb - 菜单位置在窗口上方,滑动动画为:top to bottom
// btt - 菜单位置在窗口下方,滑动动画为:bottom to top
placement: '',
// 导航菜单将要插入的位置(DOM 元素)
// String 类型 - 选择器字符串
// HTMLElement 类型 - 插入的 DOM 元素
// 仅在 position 设置为 sticky 和 fixed 布局时有效
parentElement: '#aside',
// 是否显示段落章节编号
showCode: true,
// 标题图标链接的 URL 地址
// (默认)没有设置定制,点击链接页面滚动到标题位置
// 设置了链接地址,则不会滚动定位
anchorURL: '',
// DIYer的福利
// 独立侧滑菜单时,customClass 会追加到 drawer 侧滑窗口组件
// 在文章中显示导航菜单时,customClass 会追加到 chapters 导航菜单
customClass
});
// 可以在创建导航后,重置配置信息,重新生成新的导航
Outline.reload({
// 调整位直接在文章内生成导航
position: 'sticky',
articleElement: '#article'
})
Options
outline.js 有者丰富的配置选项,以便适应不同的展示方式。
articleElement
Description
- Type:
- String|HTMLElement
- Default:
- '#article'
- String:选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement:'DOM 元素;
可选,用来指定页面中显示文章正文的 DOM 节点或者选择器字符串。
// Default Selector
const outline = new Outline(Outline.DEFAULTS)
// Customize Selector
const outline = new Outline({
articleElement: $('#main')
})
selector
Description
- Type:
- String
- Default:
- 'h1,h2,h3,h4,h5,h6'
可选,用来指定 article 节点下,要生成导航的标题标签的选择器。
// Default selector
new Outline(Outline.DEFAULTS)
// Customize selector
new Outline({
selector: 'h2'
})
title
Description
- Type:
- String|Boolean
- Default:
- '目录'
可选,用来指定文章导读导航菜单的标题文字。设置空字符串或者 false,则不显示标题。在插入导航菜单的 DOM 元素已有标题时,可以设置 title: '' 或者 false。
说明:本 API 文档的导航菜单便是使用 outline.js 生成,并且没有设置 title。
(function(){
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = ''
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
outline = new Outline(Outline.DEFAULTS)
})()
scrollElement
Description
- Type:
- String|HTMLElement
- Default:
- 'html,body'
- String: 选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement: DOM 元素;
可选,负责文章区域滚动的元素:
// 默认是当前窗口滚动
new Outline(Outline.DEFAULTS)
// 指定滚动区域是 #main 元素
new Outline({
scrollElement: '#main'
})
position
Description
- Type:
- String
- Default:
- 'relative'
可选,用来指定文章导读导航菜单的显示位置:
- relative: (默认值)创建独立的侧滑菜单;
- sticky: 导航菜单将以 sticky 模式布局(需要确保菜单插入位置(DOM 节点)支持 sticky 模式布局);
- fixed: 导航菜单将模拟 sticky 布局,起初是普通定位,会自动监听滚动位置,但滚动到导航菜单顶部时,以 fixed 模式布局,模拟 sticky 布局效果;
当设置为 sticky 和 fixed 布局时,需要设置 parentElement。
注意:2.0.0 暂时不支持之前版本那种 inside 模式,不会自动在文章开始位置插入 chapters 导航菜单
// 默认生成独立的侧滑弹窗导航菜单
new Outline(Outline.DEFAULTS)
// 在页面内部插入导航菜单
new Outline({
// 在(文章的)侧边栏显示导航菜单
parentElement: '#aside',
// 或者 sticky 定位
position: 'fixed'
})
parentElement
Description
- Type:
- String
- Default:
- '#aside'
- String: 选择器字符串,默认值:html,body(即 window 窗口);
- HTMLElement: DOM 元素;
可选,导航菜单将要插入的位置(DOM 元素)。仅在 position 设置为 sticky 和 fixed 布局时有效。
// 在页面内部插入导航菜单
new Outline({
// 在(文章的)侧边栏显示导航菜单
parentElement: '#aside',
// 或者 sticky 定位
position: 'fixed'
})
placement
Description
- Type:
- String
- Default:
- 'rtl'
可选,设置 position: relative 时,placement 定义侧滑菜单和 toolbar 导航位置:
- rtl - 菜单位置在窗口右侧,滑动动画为:right to left(默认值);
- ltr - 菜单位置在窗口左侧,滑动动画为:left to right;
- ttb - 菜单位置在窗口上方,滑动动画为:top to bottom;
- btt - 菜单位置在窗口下方,滑动动画为:bottom to top;
// 默认是在窗口右侧显示侧滑导航菜单
new Outline(Outline.DEFAULTS)
// 调整为在窗口右侧显示侧滑导航菜单
new Outline({
placement: 'ltr'
})
stickyHeight
Description
- Type:
- Number
- Default:
- 0
可选,用来指定页面中其它 sticky 或者模拟 skicky 的 fiexed 定位的 DOM 元素的高度。
这些 sticky 元素脱离了正常的流布局后,原来 h1~h6 标题标签的 offsetTop 计算会出现偏差。sticky 元素会遮挡标题,因此针对页面中有其它sticky 节点时,需要设置 stickyHeight 高度。以便 outline.js 根据 stickyHeight 和计算出的标题的 offsetTop 值重新计算滚动定位。
说明:outline.js 主要用于文章详情页面,stickyHeight 仅针对 top: 0,且 sticky 定位元素在文章内容区域上方的位置;
const defaults = Outline.DEFAULTS
// 设置 stickyHeight(outline.js 的示例页面的主标题元素的高度)
defaults.stickyHeight = 86
// 默认生成独立的侧滑弹窗导航菜单
new Outline(defaults)
showCode
Description
- Type:
- Boolean
- Default:
- true
可选,是否显示段落章节编号(注意:3.38.2 开始 showCode 默认为 false):
- false - 显示编号;
- false - 不显示编号(默认值);
animationCurrent
Description
- Type:
- Boolean
- Default:
- true
可选,是否采用动画定位高亮当前的章节标题:
- true - 采用动画定位高亮(默认值);
- false - 采用高亮当前章节标题的链接文字并加粗文字;
hasToolbar
Description
- Type:
- Boolean
- Default:
- true
可选,是否显示侧边的按钮工具栏:
- true - 显示按钮工具栏(默认值);
- false - 不显示按钮工具栏;
closeOnClickModal
Description
- Type:
- Boolean
- Default:
- true
可选,点击空白处(非独立导航菜单),收起导航菜单:
- true - 点击空白处,收起菜单(默认值);
- false - 点击空白处,不收起菜单;
showNavModalFirst
Description
- Type:
- Boolean
- Default:
- false
可选,有独立导航菜单时,是否默认显示菜单:
- false - 默认先显示按钮工具栏(默认值);
- true - 默认先显示独立导航菜单弹窗;
anchorURL
Description
- Type:
- String
- Default:
- ''
可选,用来指定文章标题锚点链接图标的链接地址:
// Default URL - 默认链接,点击图标,页面会滚动到当前标题位置
new Outline()
// Customize URL - 直接打开链接了
new Outline({
anchorURL: 'http://www.yaohaixiao.com/'
})
homepage
Description
- Type:
- String
- Default:
- ''
可选,用来指定文章标题锚点链接图标的链接地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 Homepage 图标的按钮
outline.reload({
homepage: 'http://www.yaohaixiao.com/'
})
git
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 git 图标的按钮
outline.reload({
git: 'https://github.com/yaohaixiao/outline.js'
})
tags
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库 tags 页面地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 tags 图标的按钮
outline.reload({
tags: 'https://github.com/yaohaixiao/outline.js/tags'
})
issues
Description
- Type:
- String
- Default:
- ''
可选,针对 API 文档类的文章页面,指定项目 git 仓库 issues 页面地址:
const outline = new Outline(Outline.DEFAULTS)
// 侧边栏的 Toolbar 会多出一个 issues 图标的按钮
outline.reload({
issues: 'https://github.com/yaohaixiao/outline.js/issues'
})
tools
Description
- Type:
- Array
- Default:
- []
可选,自定义的按钮配置项。tools 中的按钮会排列显示在 homepage, git, tags, issues 等按钮之后。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
// 侧边栏的 Toolbar 会多出一个 git 图标的按钮
outline.reload({
git: 'https://github.com/yaohaixiao/outline.js',
tools: [
{
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
}
]
})
reader
Since
3.32.0
说明:3.32.0 以前的版本,此属性的原名为 print,另外,reader.element 属性也调整为了 reader.target。请升级后在初始化配置参数时注意调整。
Description
- Type:
- Object
- Default:
- {target: '', title: '', enterReadingTip: ‘进入阅读模式,按 ESC 键可退出阅读模式’, allowSpeak: false}
可选,自定义的是否自动为文章页面创建打印样式。
- target:
- (必须)要打印的文章区域,DOM 元素或者选择器字符串;
- title:
- (可选)要打印的文章标题。如果 element 区域有 h1 标签则无需设置。可以直接设置标题文本,也可以是文章页的主标题 DOM 元素;
- enterReadingTip:
- (可选)进入阅读模式的提示文本,默认值:‘进入阅读模式,按 ESC 键可退出阅读模式’;
- allowSpeak:
- (可选)针对现代浏览器支持 Web Speech API,是否开启语音阅读功能。默认值:false;
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式',
// 开启语音阅读
allowSpeak: true
}
outline = new Outline(defaults)
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
customClass
Description
- Type:
- String
- Default:
- ''
可选,(DIYer福利)设置自定义样式的 class 名称:
- '' - 采用默认 outline.js 的 UI 界面(默认值);
- 设置自定义样式 - 自己根据需求设置个性化的 UI 界面;
// Default UI
new Outline(Outline.DEFAULTS)
// Customized
new Outline({
// 设置深色配置界面
customClass: 'theme-dark'
})
afterScroll
Description
- Type:
- Function
- Default:
- null
可选,当点击导航菜单、文章中的 anchor 图标(#)或者上下滚动按钮会触发滚动,afterScroll() 回调函数会在滚动结束后触发执行。
Parameters
target
- Type:
- String
afterScroll() 回调函数有一个参数 target,返回的是当前点击的 DOM 元素的名称:
- 'anchor':表示点击的是 anchor 图标,即文章中标题前的 “#” 图标,此时的 this 上下文指向 outline.anchors;
- 'chapter':表示点击的是导航菜单的链接,此时的 this 上下文指向 outline.chapters;
- 'up':表示点击的是工具栏的向上按钮,此时的 this 上下文指向 outline.toolbar;
- 'down':表示点击的是工具栏的向下按钮,此时的 this 上下文指向 outline.toolbar;
注意:因为配置 afterScroll 回调函数会因为 4 个不同的 DOM 触发,所以需要根据 target 返回的值和此时的 this 指向判断处理。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterScroll = function(target) {
// 当然,如果你希望无论是点击什么都执行,就不需要判断了
// 直接些通用的滚动结束的逻辑即可
switch(target){
case 'anchor':
// 针对点击 # 的处理逻辑
break
case 'chapter':
// 针对点击导航菜单的处理逻辑
break
case 'up':
// 针对点击向上滚动按钮的处理逻辑
break
case 'down':
// 针对点击向下滚动按钮的处理逻辑
break
}
}
outline = new Outline(Outline.DEFAULTS)
afterSticky
Description
- Type:
- Function
- Default:
- null
可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。
说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。
Parameters
closed
- Type:
- Boolean
closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态
isSticky
- Type:
- Boolean
isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。
const $header = document.querySelector('#header')
const HEADER_STICKY = 'header_sticky'
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterSticky = function(closed, isStickying) {
const $nav = this.$el
const BORDER_RIGHT = 'utils-border-right'
if (closed) {
return false
}
if (isStickying) {
$nav.classList.add(BORDER_RIGHT)
$header.classList.add(HEADER_STICKY)
} else {
$nav.classList.remove(BORDER_RIGHT)
$header.classList.remove(HEADER_STICKY)
}
}
defaults.afterToggle = function(closed, isStickying) {
if (!isStickying) {
return false
}
if (closed) {
$header.classList.remove(HEADER_STICKY)
} else {
$header.classList.add(HEADER_STICKY)
}
}
outline = new Outline(Outline.DEFAULTS)
afterToggle
Description
- Type:
- Function
- Default:
- null
可选,当导航菜单隐藏或者显示的时候,会触发执行 afterToggle 回调函数。
说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。
Parameters
closed
- Type:
- Boolean
closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态
isSticky
- Type:
- Boolean
isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。
const $header = document.querySelector('#header')
const HEADER_STICKY = 'header_sticky'
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'fixed'
defaults.parentElement = '#aside'
defaults.stickyHeight = 86
defaults.homepage = './index.html'
defaults.afterSticky = function(closed, isStickying) {
const $nav = this.$el
const BORDER_RIGHT = 'utils-border-right'
if (closed) {
return false
}
if (isStickying) {
$nav.classList.add(BORDER_RIGHT)
$header.classList.add(HEADER_STICKY)
} else {
$nav.classList.remove(BORDER_RIGHT)
$header.classList.remove(HEADER_STICKY)
}
}
defaults.afterToggle = function(closed, isStickying) {
if (!isStickying) {
return false
}
if (closed) {
$header.classList.remove(HEADER_STICKY)
} else {
$header.classList.add(HEADER_STICKY)
}
}
outline = new Outline(Outline.DEFAULTS)
chapterTextFilter
Description
- Type:
- Function
- Default:
- null
可选,API 文档中,正文的方法会添加参数等信息,例如:getChapters(headings, showCode, chapterTextFilter)。而在 chapters 导航菜单,我希望显示为 getChapters(),这时我们就可以借助 chapterTextFilter 回调函数。对原始的文本进行过滤,返回我们期望的 getChapters() 文本。
Parameters
text
- Type:
- String
chapterTextFilter() 回调函数有一个参数 text,返回的是当前 hx 标题中的文本。
Returns
- Type:
- String
返回最终希望生成的标题文本内容。
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = false
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
defaults.chapterTextFilter = (text) => {
return text.replace(/\(.*?\)/, '()')
}
outline = new Outline(defaults)
anchorLinkFilter
Description
- Type:
- Function
- Default:
- null
可选,API 文档中,正文标题的锚点链接地址生成函数。
Parameters
tag
- Type:
- String
当前标题的 tagName。小写的:h1~6。
title
- Type:
- String
当前标题的文本内容。
id
- Type:
- Number
outline.js 为当前标题生成 id 号。
Returns
- Type:
- String
返回最终希望生成锚点链接的文本内容。
const defaults = Outline.DEFAULTS
let outline
defaults.selector = 'h2,h3'
defaults.title = false
defaults.showCode = false
defaults.position = 'sticky'
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.articleElement = '#article'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.print = {
element: '#article',
title: 'Outline.js'
}
defaults.chapterTextFilter = (text) => {
return text.replace(/\(.*?\)/, '()')
}
defaults.anchorLinkFilter = (tag, title, id) => {
return `${tag}-${title}-${id}`
}
outline = new Outline(defaults)
Properties
outline.js 重构后,对外放 4 个重要的属性:anchors、drawer、chapters、reader 和 toolbar。它们都是独立的对象实例,提供了 outline.js 所有的能力(属性和方法)。
attrs
Description
- Type:
- Object
存储的是 Outline 对象当前使用中的配置选项:
说明:建议使用 attr(prop) 方法来获取属性,避免直接调用属性。
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 查看全部配置信息
outline.attrs
$article
Since
3.32.0
Description
- Type:
- HTMLElement
存储的是 Outline 对象要分析的文章正文内容显示区域的 DOM 元素:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 获取文章正文内容显示区域的 DOM 元素
outline.$article
$scrollElement
Since
3.34.0
Description
- Type:
- HTMLElement
存储的是 Outline 对象要分析的控制文章内容滚动的 DOM 元素:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 获取文章正文内容显示区域的 DOM 元素
outline.$scrollElement
buttons
Description
- Type:
- Array
存储的是 Outline 对象当前工具栏的完整的按钮配置信息:
// 设置默认配置项
const outline = new Outline(Outline.DEFAULTS)
// 查看全部按钮配置信息
outline.buttons
anchors
Description
- Type:
- Object
Anchors 模块:类似 AnchorJS 基础功能模块,自动分析段落层级。
// 仅展示 API 中对外公开的方法和属性
class Anchors extends Base {
constructor(options) {
super()
this.attrs = Anchors.DEFAULTS
this.$articleElement = null
this.$scrollElement = null
this.$headings = []
this.chapters = []
// 省略其它逻辑...
}
getChapters(isTreeStructured = false) {
const chapters = this.chapters
return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters
}
count() {
return this.chapters.length
}
attr(prop, value) {
const attrs = this.attrs
if (isString(prop)) {
// 只能扩展 attrs 中已有的属性
if (value && hasOwn(attrs, prop)) {
// 更新单个配置信息
attrs[prop] = value
return this
}
// 只传递 prop 参数,则返回对应的属性值
return attrs[prop]
} else if (isObject(prop)) {
// 批量更新配置信息
extend(attrs, prop)
return this
} else if (arguments.length === 0) {
// 不传递参数,直接返回整个
return attrs
}
return this
}
render() {
// 省略其它逻辑...
return this
}
scrollTo(top, after) {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Anchors.DEFAULTS = {
scrollElement: 'html,body',
articleElement: '#article',
selector: 'h1,h2,h3,h4,h5,h6',
anchorURL: '',
hasAnchor: true,
isAtStart: true,
showCode: false,
created: null,
mounted: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Anchors
navigator
Description
- Type:
- Object
Navigator 模块:独立的导航菜单模块;
// 仅展示 API 中对外公开的方法和属性
class Navigator extends Base {
constructor(options) {
super()
this.attrs = Navigator.DEFAULTS
this.$el = null
this.$title = null
this.$main = null
this.$list = null
this.$placeholder = null
this.$parentElement = null
this.$scrollElement = null
this.chapters = []
this.closed = false
this.active = 0
this.offsetTop = 0
this.$active = null
this.timer = null
this.playing = false
// 省略其它逻辑...
}
isClosed() {
return this.closed
}
isSticky() {
const position = this.attr('position')
return position === 'sticky'
}
isFixed() {
const position = this.attr('position')
return position === 'fixed'
}
isInside() {
return this.isFixed() || this.isSticky()
}
isOutside() {
return !this.isInside()
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
highlight(id) {
// 省略其它逻辑...
return this
}
sticky() {
// 省略其它逻辑...
return this
}
scrollTo(top, after) {
// 省略其它逻辑...
return this
}
show() {
// 省略其它逻辑...
return this
}
hide() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Navigator.DEFAULTS = {
parentElement: '',
scrollElement: '',
selector: '',
active: 0,
closed: false,
showCode: true,
position: 'relative',
chapters: [],
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Navigator
drawer
Description
- Type:
- Object
Drawer 模块:独立的侧滑窗口模块。
// 仅展示 API 中对外公开的方法和属性
class Drawer extends Base {
constructor(options) {
super()
this.attrs = Drawer.DEFAULTS
this.title = ''
this.closed = true
this.$el = null
this.$modal = null
this.$header = null
this.$title = null
this.$close = null
this.$main = null
this.$footer = null
this.$overlay = null
this.zIndex = 0
// 省略其它逻辑...
}
isClosed() {
return this.closed
}
setTitle() {
this.attr('title', title)
this.title = title
this.$title.innerHTML = title
return this
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
open() {
// 省略其它逻辑...
return this
}
close() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Drawer.DEFAULTS = {
placement: 'rtl',
title: '标题',
size: 'regular',
hasClose: true,
hasOverlay: true,
hasOffset: false,
hasPadding: true,
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterScroll: null,
beforeDestroy: null,
afterDestroy: null
}
export default Drawer
reader
Description
- Type:
- Object
Reader 模块:独立的阅读视图模块。
// 仅展示 API 中对外公开的方法和属性
class Drawer extends Base {
constructor(options) {
super()
this.attrs = cloneDeep(Reader.DEFAULTS)
this.reading = false
this.$target = null
this.$paper = null
this.$title = null
this.$article = null
this.$icon = null
// 省略其它逻辑...
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
refresh() {
// 省略其它逻辑...
return this
}
enter() {
// 省略其它逻辑...
return this
}
exit() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
print() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Reader.DEFAULTS = {
target: '',
title: '标题',
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
export default Reader
toolbar
Description
- Type:
- Object
Toolbar 模块:独立的固定定位的工具栏模块;
// 仅展示 API 中对外公开的方法和属性
class Toolbar extends Base {
constructor(options) {
super()
this.attrs = Drawer.DEFAULTS
this.title = ''
this.closed = true
this.$el = null
this.$modal = null
this.$header = null
this.$title = null
this.$close = null
this.$main = null
this.$footer = null
this.$overlay = null
// 省略其它逻辑...
}
isDisabled(name) {
const buttons = this.attr('buttons')
let button
if (name) {
button = buttons.find((option) => option.name === name)
return !!(button && button.disabled)
}
return this.disabled
}
isClosed() {
return this.closed
}
highlight() {
// 省略其它逻辑...
return this
}
attr(prop, value) {
// 省略其它逻辑...
return this
}
render() {
// 省略其它逻辑...
return this
}
add(button) {
// 省略其它逻辑...
return this
}
remove(name) {
// 省略其它逻辑...
return this
}
switch(name, enabled) {
// 省略其它逻辑...
return this
}
enable(name) {
// 省略其它逻辑...
return this
}
disable(name) {
// 省略其它逻辑...
return this
}
show() {
// 省略其它逻辑...
return this
}
hide() {
// 省略其它逻辑...
return this
}
toggle() {
// 省略其它逻辑...
return this
}
destroy() {
this.removeListeners()
// 省略其它逻辑...
return this
}
reload(options) {
this.destroy().initialize(this.attr(options))
return this
}
}
Toolbar.DEFAULTS = {
placement: 'ltr',
closed: false,
disabled: false,
buttons: [],
created: null,
mounted: null,
afterClosed: null,
afterOpened: null,
afterDisabled: null,
afterEnabled: null,
beforeDestroy: null,
afterDestroy: null
}
Drawer.zIndex = 2000
export default Toolbar
Outline.DEFAULTS
Description
- Type:
- Object
静态属性,存储的是 Outline 对象默认配置选项:
Outline.DEFAULTS = {
// 文章显示区域的 DOM 元素或者选择器字符串
articleElement: '#article',
// 要收集的标题选择器
selector: 'h2,h3,h4,h5,h6',
// 指定文章导读导航菜单的标题文字。
// 设置空字符串或者 false,则不显示标题
// 在插入导航菜单的 DOM 元素已有标题时,可以设置 title: '' 或者 false
title: '目录',
// 负责文章区域滚动的元素
// String 类型 - 选择器字符串,默认值:html,body(window窗口)
// HTMLElement 类型 - DOM 元素
// 注意:如果您使用的是比较旧的 chrome 浏览器,例如:Chromium 60.x 版本或者以下版本
// 请手动设置 scrollElement = 'body',否则点击导航无法滚动定位
scrollElement: 'html,body',
// 文章导读菜单的位置
// relative - (默认值)创建独立的侧滑菜单
// sticky - 导航菜单将以 sticky 模式布局(需要确保菜单插入位置支持 sticky 模式布局)
// fixed - 导航菜单将以 fixed 模式布局,会自动监听滚动位置,模拟 sticky 布局
// sticky 和 fixed 布局时,需要设置 parentElement
// 2.0.0 暂时不支持之前版本那种 inside 模式,不会自动在文章开始位置插入 chapters 导航菜单
position: 'sticky',
// 导航菜单将要插入的位置(DOM 元素)
// String 类型 - 选择器字符串
// HTMLElement 类型 - 插入的 DOM 元素
// 仅在 position 设置为 sticky 和 fixed 布局时有效
parentElement: '#aside',
// 设置 position: relative 时,placment 定义侧滑菜单和 toolbar 导航位置:
// rtl - 菜单位置在窗口右侧,滑动动画为:right to left
// ltr - 菜单位置在窗口左侧,滑动动画为:left to right
// ttb - 菜单位置在窗口上方,滑动动画为:top to bottom
// btt - 菜单位置在窗口下方,滑动动画为:bottom to top
placement: 'rtl',
// 页面中其它 sticky 或者模拟 skicky 的 fiexed 定位的 DOM 元素的高度。例如 wordpress 系统中,
// 就会有 sticky 定位的导航菜单。这些 sticky 元素脱离了正常的流布局后,原来 h1~h6 标题标签的
// offsetTop 计算会出现偏差。sticky 元素会遮挡标题,因此针对页面中有其它 sticky 元素会遮挡标题,
// 因此针对 sticky 布局时,需要设置 stickyHeight 高度。outline.js 会根据 stickyHeight 和计
// 算出的标题的 offsetTop 值重新计算滚动定位;
// 说明:outline.js 主要用于文章详情页面,
// 因此 stickyHeight 仅针对 top: 0,且 sticky 定位元素在文章内容区域上方的位置;
stickyHeight: 0,
// 是否显示标题编号(注意:3.38.2 开始 showCode 默认为 false)
showCode: false,
// 是否显示侧边的按钮工具栏
hasToolbar: true,
// 指定是否采用动画定位高亮当前的章节标题,默认值:true
// 当值为 false 时,则采用高亮当前章节标题的链接文字并加粗文字
// 如果喜欢更简洁的高亮效果,可以选择设置为 false
animationCurrent: true,
// 标题图标链接的 URL 地址
// (默认)没有设置定制,点击链接页面滚动到标题位置
// 设置了链接地址,则不会滚动定位
anchorURL: '',
// 指定当前站点主页地址
homepage: '',
// 指定git仓库地址
git: '',
// 指定git仓库中的 tags 地址
tags: '',
// 指定git仓库中的 issues 地址
issues: '',
// 自定义按钮配置
tools: [],
// 为文章页添加基础的打印样式
// 如果您的页面已经有打印样式,就无需设置了
reader: {
//(必须)要打印的文章区域,DOM 元素或者选择器字符串。
target: '',
// (可选)要打印的文章标题。如果 element 区域有 h1 标签则无需设置。
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素
title: '',
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
},
// DIYer的福利
// 独立侧滑菜单时,customClass 会追加到 drawer 侧滑窗口组件
// 在文章中显示导航菜单时,customClass 会追加到 chapters 导航菜单
customClass,
// position: fixed,当导航菜单样式进入 fixed 定位后,触发的回调函数
afterSticky: null,
// 当导航菜单隐藏或者显示后,触发的回调函数
afterToggle: null,
// 当点击上下滚动按钮,导航菜单或者文章中的 # 图标,滚动结束后触发的回调函数
afterScroll: null,
// 文档的标题文本过滤回调函数
// API 文档中,正文的方法会添加参数等信息,例如:getChapters(headings, showCode, chapterTextFilter)
// 而在 chapters 导航菜单,我希望显示为 getChapters(),这时我们就可以借助 chapterTextFilter 回调函数
// 对原始的文本进行过滤,返回我们期望的 getChapters() 文本
chapterTextFilter: null,
// 锚点链接的生成回调函数
// anchorLinkFilter(tag, title, id)
// tag - 当前标题的 tagName 小写:h1~6
// title - 当前标题的文本内容
// id - outline 为当前标题生成的 id 号,是个数值
// 如果设置了 anchorURL,则会统一使用 anchorURL 参数的地址
anchorLinkFilter: null
}
Methods
outline.js 的提供的方法如下:
attr([prop, value])
Description
attr() 方法用来设置或者获取初始化时配置的 attrs 信息的。
Parameters
prop
- Type:
- String|HTMLElement
(可选)options 中的属性名称或者要配置的 attrs 信息。
value
- Type:
- Any
(可选)要设置的 prop 属性的值
- 不传递任何参数:返回完整的 attrs 配置信息;
- 仅传递 prop:
- String: 返回 attrs 配型信息中与 prop 对应的值;
- Object: 用来设置 attrs 配置信息;
- 同时传递 prop 和 value 参数:设置 attrs 配置信息中的某个属性值;
Returns
- Type:
- Any
配置信息 attrs 的属性值或者 Outline 对象。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.attr('title') // -> 'Outline v2.0.0'
outline.attr('title', '目录') // -> 设置 title 配置信息的值为 '目录'
outline.attr() // -> 返回完整配置参数 attrs 信息
isExpanded()
Description
isExpanded() 方法来判断导航菜单是否展开(可见)。
Returns
- Type:
- Boolean
返回菜单展开状态。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 展开
outline.toggle()
outline.isExpanded() // -> true
// 收起
outline.toggle()
outline.isExpanded() // -> false
getChapters([isTreeStructured])
Description
getChapters() 方法来获取 outline.js 分析的文章段落层次数据。
Parameters
isTreeStructured
- Type:
- Boolean
- Default:
- false
(可选)是否为树结构的数据。
- false: (默认值)输出打平的一维数组格式数据;
- true: 输出树结构格式的数据;
Returns
- Type:
- Object
outline.js 分析的文章段落层次数据。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// 一维数组格式数据
// -> [{
{
id: 2,
pid: -1,
level: 1,
rel: "heading-2",
text: "安装说明",
index: 3,
code: "3",
},
{
id: 3,
pid: 2,
level: 2,
rel: "heading-3",
text: "npm install",
index: 1,
code: "3.1",
children: []
},
{
id: 4,
pid: 2,
level: 2,
rel: "heading-4",
text: "CDN 调用",
index: 2,
code: "3.2",
children: []
},
{
id: 5,
pid: 2,
level: 2,
rel: "heading-5",
text: "调用本地JS文件",
index: 3,
code: "3.3",
children: []
}
}]
outline.getChapters(true)
// 有 children 属性的树结构对象数组
// -> [{
code: "3",
id: 2,
index:3,
level:1,
pid:-1,
rel: "heading-2"
text:"安装说明",
children: [
{
id: 3,
pid: 2,
level: 2,
rel: "heading-3",
text: "npm install",
index: 1,
code: "3.1",
children: []
},
{
id: 4,
pid: 2,
level: 2,
rel: "heading-4",
text: "CDN 调用",
index: 2,
code: "3.2",
children: []
},
{
id: 5,
pid: 2,
level: 2,
rel: "heading-5",
text: "调用本地JS文件",
index: 3,
code: "3.3",
children: []
}
]
}]
outline.destroy()
outline.getChapters()
// 调用 destroy() 方法后,所有数据都清空了
// -> []
count()
Description
count() 方法来获取 outline.js 分析的文章段落层次数据的数量。
Returns
- Type:
- Number
outline.js 分析的 chapters 数据数量。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// -> [{
code: "1",
id: 0,
index: 1,
level: 1,
pid: -1
rel: "heading-0"
text: "创作灵感"
}]
outline.count()
// -> 1 就是 getChapters() 返回数据的数量
addButton(button)
Description
addButton() 方法添加自定义的工具栏按钮。
Parameters
button
- Type:
- Object|Array
(必须)单个按钮的配置信息或者多个按钮的配置信息。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
outline.addButton({
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
type: 'click',
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
})
removeButton(name)
Description
removeButton() 方法移除工具栏按钮。
Parameters
name
- Type:
- String
(必须)按钮名称。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline(Outline.DEFAULTS)
// 如果需要其它图标,可以到 https://github.com/yaohaixiao/icons.toolkit.vue 项目中选择需要的图标资源
const clean = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 1024 1024">' +
'<path d="M704 32V320h288a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H32a32 32 0 0 1-32-32v-320A32 32 0 0 1 32 320H320V32a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32zM576 128H448v320H128v128h768V448H576V128z"></path>' +
'<path d="M896 576v416a32 32 0 0 1-32 32h-704a32 32 0 0 1-32-32V576h768z m-128 128H256v192h512v-192z"></path>' +
'</svg>'
outline.addButton({
name: 'clean',
// 图标
icon: clean,
size: 20,
color: '#f00'
// link 指定按钮点击后页面的跳转地址
link: 'https://github.com/yaohaixiao',
// link 和 action 只能二选一
// action 指定按钮的处理方式
action: {
type: 'click',
// 指定回调函数的 this 上下文,不设置 this 指向 toolbar 组件
context: outline,
handler: function() {
// 回调函数的处理逻辑
}
}
})
setTimeout(() => {
outline.removeButton('clean')
}, 5000)
toTop([afterScroll])
Description
toTop() 方法会控制页面(scrollElement)滚动到顶部。
Parameters
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toTop() // 页面将滚动到顶部,向上滚动按钮消失
outline.toTop(() => {
console.log('滚动结束‘)
})
toBottom([afterScroll])
Description
toBottom() 方法会控制页面(scrollElement)滚动到顶部。
Parameters
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toBottom() // 页面将滚动到底部,向下滚动按钮消失
outline.toBottom(() => {
console.log('滚动结束‘)
})
scrollTo(top[,afterScroll])
Description
scrollTo() 方法用于将窗口的滚动条滚动到指定 top 值的位置。
Parameters
top
- Type:
- Number
(必选)页面要滚动的 top 数值。
afterScroll
- Type:
- Function
(可选)页面停止滚动后的回调函数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// -> 页面将滚动到距离顶部 200 像素的位置
outline.scrollTo(200)
outline.scrollTo(200, () => {
console.log('滚动结束‘)
})
expand()
Description
expand() 方法来展开导航菜单。
Returns
- Type:
- Number
Outline 对象,便于链式调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 收起菜单
outline.expand()
outline.isExpanded() // -> true
collapses()
Description
collapses() 方法来收起导航菜单。
Returns
- Type:
- Number
Outline 对象,便于链式调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 收起菜单
outline.collapses()
outline.isExpanded() // -> false
toggle()
Description
toggle() 方法用来隐藏或显示侧边栏菜单。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.toggle() // 如果已经隐藏,则显示
outline.toggle() // 如果已显示,则隐藏
print()
Description
print() 方法用于启动打印界面,打印当前文章。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
// 如果浏览器支持 print() 打印,则启动打印界面
outline.print()
enterReading()
Since
3.32.0
Description
enterReading() 方法来切换进入阅读模式。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
outline.enterReading()
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
exitReading()
Since
3.32.0
Description
exitReading() 方法用来从阅读模式切换回普通文章页面模式。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
outline.enterReading()
outline.exitReading()
演示地址:https://yaohaixiao.github.io/examples/outline.js/flex.html
switchReading()
Since
3.32.0
Description
switchReading() 方法用来在阅读模式和回普通文章页面模式相互切换。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const defaults = Outline.DEFAULTS
let outline
defaults.position = 'sticky'
defaults.stickyHeight = 86
defaults.parentElement = '#aside'
defaults.scrollElement = '#main'
defaults.homepage = './index.html'
defaults.git = 'https://github.com/yaohaixiao/outline.js'
defaults.tags = 'https://github.com/yaohaixiao/outline.js/tags'
defaults.issues = 'https://github.com/yaohaixiao/outline.js/issues'
defaults.reader = {
target: '#article',
// 可以直接设置标题文本,也可以是文章页的主标题 DOM 元素。
// 纯静态的页面,设置 DOM 元素,可能更好,确保每个页面的主标题 DOM 元素的选择器不变
// 则 title 会是一个可变的值,这样比直接设置标题文本更加灵活;
title: document.querySelector('.title'),
// 进入阅读模式的提示消息文本
enterReadingTip: '进入阅读模式,按 ESC 键可退出阅读模式'
}
outline = new Outline(defaults)
// 进入阅读模式
outline.switchReading()
// 退出阅读模式
outline.switchReading()
演示地址:https://yaohaixiao.github.io/outline.js/examples/flex.html
destroy()
Description
destroy() 方法用于移除所有绘制的 DOM 节点,并移除绑定的事件处理器,同时重置所有 attrs 配置信息和 data 信息。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
article: '#article',
title: 'Outline v2.0.0'
})
outline.getChapters()
// -> [{
code: "1",
id: 0,
index: 1,
level: 1,
pid: -1
rel: "heading-0"
text: "创作灵感"
}]
outline.destroy()
outline.getChapters()
// 调用 destroy() 方法后,所有数据都清空了
// -> []
refresh()
Description
refresh() 方法是(在文章政委内容改变后)重新绘制导航信息的方法:
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
showCode: true
})
const REFRESH_METHOD = '<h3>添加 refresh() 方法</h3>' +
'<p>refresh() 方法是(在文章政委内容改变后)重新绘制导航信息的方法</p>'
outline.$article.innerHTML += REFRESH_METHOD
// 根据新的内容重新绘制导读信息
outline.refresh()
reload(options)
Description
reload (options) 方法是(根据新的配置信息)重启程序方法:
- 先移除所有绘制的 DOM 元素和绑定的事件处理器;
- 重新初始化程序;
Parameters
options
- Type:
- Object
(可选)初始化的配置参数。
Returns
- Type:
- Outline
Outline 对象,便于链式方法调用。
const outline = new Outline({
showCode: true
})
// 重启后,将不再显示段落层次编号
outline.reload({
showCode: false
})
$emit(topic[, data, async = true])
Description
$emit()方法用来发布订阅主题信息。
outline.js 默认是采用异步方式发布的。以确保在消费者处理主题时,主题的发起者不会被阻止。 当然 $emit() 方法也支持同步主题发布。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
data
- Type:
- Object
(可选)消息传递的数据对象。
async
- Type:
- Boolean
- Default:
- true
(可选) 是否异步发布。默认值:true。
- 当 async 设置为 true(默认) 时,异步发布;
- 当 async 设置为 false 时,同步发布;
Returns
- Type:
- Outline
Outline 对象,以便实现链式调用。
const outline = new Outline(Outline.DEFAULTS)
const handler = (msg) => {
console.log(msg)
}
outline.$on('created', handler)
outline.$on('mounted', handler)
// 异步发布
outline.$emit('mounted') // -> 'ok'
// 同步发布
// 延迟10毫秒:应该看输出 ok 后输出
outline.$emit('created')
$on(topic, handler)
Description
$on() 方法用来订阅主题,并给出处理器函数。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
handler
- Type:
- Function
((必须)主题的处理器函数。
Returns
- Type:
- String。
唯一的 token 字符串,例如:'guid-1'。
const outline = new Outline(Outline.DEFAULTS)
const handler = function(attrs) {
// this 上下文指向 outline 实例
this.attr()
console.log('attrs: ', attrs)
}
outline.$on('created', handler)
// 手动触发 created 事件
outline.$emit('created')
$off(topic[, token])
Description
$off() 用来取消订阅主题。
- Category:
- Core
Parameters
topic
- Type:
- String
(必须)主题名称。
token
- Type:
- Function | String
(可选)订阅主题的处理器函数或者唯一 Id 值。
- 为传递 token 参数:取消指定 topic 的订阅;
- 传递 token 参数:仅删除 topic 订阅信息中与 token 对应的事件处理器
Returns
- Type:
- Outline
Outline 对象,以便实现链式调用。
const outline = new Outline(Outline.DEFAULTS)
const handler = (msg) => {
console.log('handler:', msg)
}
outline.$on('created')
// 取消订阅 author 主题
outline.$off('created')
// 不会有任何反应,因为已经取消订阅了
outline.$emit('created')
Events
outline.js 从 3.21.0 开始提供了 6 事件。通过 outline.js 在 3.21.0 新添加的 $on() 方法监听。
created
事件名称 | 说明 | 回调参数 |
---|---|---|
created | Outline 实例配置信息初始化完成后触发,此时 DOM 元素还没有绘制。 | 返回实例最终的 attrs 配置属性的(对象)值。 |
Usage
const outline = new Outline()
outline.$on('created', function(attrs) {
// this 上下文就是 outline 实例
// attrs === outline.attr()
})
// 当 outline 实例的配置信息初始化完毕,就会触发 created 事件
outline.initialize(Outline.DEFAULTS)
mounted
事件名称 | 说明 | 回调参数 |
---|---|---|
mounted | Outline 实例的所有 DOM 元素绘制完毕后触发。 | -- |
Usage
const outline = new Outline()
outline.$on('mounted', function() {
// do something
})
// 当 outline 实例的所有 DOM 绘制完毕,就会触发 mounted 事件
outline.initialize(Outline.DEFAULTS)
enterReading
事件名称 | 说明 | 回调参数 |
---|---|---|
enterReading | 配置了 print 参数,在进入阅读模式后会触发。 | -- |
Usage
const defaults = Outline.DEFAULTS
// 需要配置 print 参数
defaults.print = {
element: '#article',
title: document.querySelector('.title')
}
const outline = new Outline(Outline.DEFAULTS)
outline.$on('enterReading', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
// 手动触发 enterReading 事件
outline.$emit('enterReading')
exitReading
事件名称 | 说明 | 回调参数 |
---|---|---|
exitReading | 配置了 print 参数,在离开阅读模式后会触发。 | -- |
Usage
const defaults = Outline.DEFAULTS
// 需要配置 print 参数
defaults.print = {
element: '#article',
title: document.querySelector('.title')
}
const outline = new Outline(Outline.DEFAULTS)
outline.$on('exitReading', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
// 手动触发 exitReading 事件
outline.$emit('exitReading')
beforeDestroy
事件名称 | 说明 | 回调参数 |
---|---|---|
beforeDestroy | Outline 实例销毁前事件,在调用 Outline 对象的实例 destroy() 方法后会触发。 | -- |
Usage
const outline = new Outline(Outline.DEFAULTS)
outline.$on('beforeDestroy', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
outline.destroy()
destroyed
事件名称 | 说明 | 回调参数 |
---|---|---|
destroyed | Outline 实例销毁后事件,在调用 Outline 对象的实例 destroy() 方法后会触发。 | -- |
Usage
const outline = new Outline(Outline.DEFAULTS)
outline.$on('beforeDestroy', function() {
// this 上下文就是 outline 实例
console.log('this', this)
})
outline.destroy()
License
JavaScript Code Licensed under MIT License.
API Documentation Licensed under CC BY 3.0