1 Star 0 Fork 34

sky/outline.js

forked from Yaohaixiao/outline.js 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
chapters.min.js.map 90.76 KB
一键复制 编辑 原始数据 按行查看 历史
{"version":3,"file":"chapters.min.js","sources":["utils/types/isString.js","utils/lang/hasOwn.js","utils/lang/toString.js","utils/types/isFunction.js","utils/types/isObject.js","utils/observer/_subscribers.js","utils/observer/_hasDirectSubscribersFor.js","utils/observer/has.js","utils/observer/_hasSubscribers.js","utils/observer/emit.js","utils/types/isTypedArray.js","utils/lang/guid.js","utils/observer/_removeSubscriber.js","utils/observer/off.js","utils/observer/_removeSubscriberByToken.js","base.js","utils/lang/extend.js","utils/observer/on.js","utils/types/isElement.js","utils/lang/later.js","utils/event/enum.js","utils/event/_off.js","utils/event/_delete.js","utils/event/purgeElement.js","utils/event/getListeners.js","utils/event/off.js","utils/event/at.js","utils/dom/matches.js","utils/dom/getParentOrHost.js","utils/event/on.js","utils/event/getTarget.js","utils/dom/resolveTextNode.js","utils/dom/closest.js","utils/types/isArray.js","utils/types/isDOM.js","utils/types/isHTMLCollection.js","utils/types/isFragment.js","utils/types/isTextNode.js","utils/dom/createElement.js","utils/dom/setAttributes.js","utils/dom/setAttribute.js","utils/lang/easeInQuad.js","utils/dom/_getScrollElement.js","utils/dom/scrollTo.js","utils/dom/hasClass.js","utils/dom/addClass.js","utils/dom/removeClass.js","utils/lang/trim.js","utils/dom/offsetTop.js","utils/dom/getStyle.js","utils/dom/setProperty.js","utils/lang/cloneDeep.js","utils/lang/timeSlice.js","chapters.js","_paintChapters.js","utils/dom/inBounding.js","utils/dom/intersection.js","utils/event/stop.js"],"sourcesContent":["/**\r\n * 检测数据是否为 String 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} str\r\n * @returns {boolean}\r\n */\r\nconst isString = (str) => {\r\n return typeof str === 'string'\r\n}\r\n\r\nexport default isString\r\n","/**\r\n * 检测对象自身属性中是否具有指定的属性。\r\n * ========================================================================\r\n * @method hasOwn\r\n * @param {Object} obj - (必须)检测的目标对象\r\n * @param {String} prop - (必须)属性名\r\n * @returns {Boolean}\r\n */\r\nconst hasOwn = (obj, prop) => {\r\n const hasOwnProperty = Object.prototype.hasOwnProperty\r\n return obj && hasOwnProperty.call(obj, prop)\r\n}\r\n\r\nexport default hasOwn\r\n","/**\r\n * Object 对象原型上的 toString 方法\r\n * ========================================================================\r\n * @method toString\r\n * @param {*} val\r\n * @returns {string}\r\n */\r\nconst toString = (val) => {\r\n return Object.prototype.toString.apply(val)\r\n}\r\n\r\nexport default toString\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测测试数据是否为 Function 类型\r\n * ========================================================================\r\n * @method isFunction\r\n * @param {*} val - (必须)待检测的数据\r\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\r\n */\r\nconst isFunction = (val) => {\r\n return typeof val === 'function' || toString(val) === '[object Function]'\r\n}\r\n\r\nexport default isFunction\r\n","import toString from '../lang/toString'\r\nimport isFunction from './isFunction'\r\n\r\n/**\r\n * 检测数据是否为 Object 类型\r\n * ========================================================================\r\n * @method isObject\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isObject = (o) => {\r\n return (\r\n (toString(o) === '[object Object]' ||\r\n typeof o === 'object' ||\r\n isFunction(o)) &&\r\n o !== null\r\n )\r\n}\r\n\r\nexport default isObject\r\n","/**\r\n * 存储订阅者(主题和处理器的)私有对象\r\n * ========================================================================\r\n * @type {{}}\r\n * @private\r\n */\r\nconst _subscribers = {}\r\n\r\nexport default _subscribers\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\r\n * ========================================================================\r\n * @method _hasDirectSubscribersFor\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasDirectSubscribersFor = (topic) => {\r\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\r\n}\r\n\r\nexport default _hasDirectSubscribersFor\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\nimport _hasSubscribers from './_hasSubscribers'\r\n\r\n/**\r\n * 判断是否存在包含 topic 指定的订阅者信息\r\n * ========================================================================\r\n * @method has\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\r\n * @returns {Boolean}\r\n */\r\nconst has = (topic, isDirect = true) => {\r\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\r\n}\r\n\r\nexport default has\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * 判断是否存在包含给定 topic 相关的订阅者信息\r\n * ========================================================================\r\n * @method _hasSubscribers\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasSubscribers = (topic) => {\r\n let found = _hasDirectSubscribersFor(topic)\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (!found && position !== -1) {\r\n topic = topic.substring(0, position)\r\n position = topic.lastIndexOf('.')\r\n found = _hasDirectSubscribersFor(topic)\r\n }\r\n\r\n return found\r\n}\r\n\r\nexport default _hasSubscribers\r\n","import isTypedArray from '../types/isTypedArray'\r\nimport _subscribers from './_subscribers'\r\nimport has from './has'\r\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * (异步)发布订阅主题信息\r\n * ========================================================================\r\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\r\n * ========================================================================\r\n * @method emit\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Object} [data] - (可选)数据对象\r\n * @param {Boolean} [async] - (可选) 是否异步发布\r\n */\r\nconst emit = (topic, data, async = true) => {\r\n const execute = (topic) => {\r\n if (!_hasDirectSubscribersFor(topic)) {\r\n return false\r\n }\r\n\r\n _subscribers[topic].forEach((subscriber) => {\r\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\r\n // 采用 toString() 方法转化为普通(JSON)字符串\r\n const message = isTypedArray(data) ? data.toString() : data\r\n\r\n subscriber.callback.call(subscriber.context || subscriber, message)\r\n })\r\n }\r\n const deliver = () => {\r\n let subscriber = topic\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (position !== -1) {\r\n subscriber = subscriber.substring(0, position)\r\n position = subscriber.lastIndexOf('.')\r\n\r\n execute(subscriber)\r\n }\r\n\r\n // 执行 topic 对应的处理器\r\n execute(topic)\r\n // 执行特殊 topic:'*'(监听全部消息的发布)\r\n execute('*')\r\n }\r\n\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (async) {\r\n setTimeout(deliver, 10)\r\n } else {\r\n deliver()\r\n }\r\n}\r\n\r\nexport default emit\r\n","import toString from '../lang/toString'\r\n/**\r\n * 判断检测数据是否为 Typed Arrays 类型的数据\r\n * ========================================================================\r\n * @param {*} val\r\n * @returns {boolean}\r\n */\r\nconst isTypedArray = (val) => {\r\n const TYPES = [\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ]\r\n\r\n return TYPES.indexOf(toString(val)) > -1\r\n}\r\n\r\nexport default isTypedArray\r\n","/**\r\n * 生成唯一 id 字符串的函数\r\n * ========================================================================\r\n * @method guid\r\n * @param {String} [prefix] - 生成 id 的前缀字符串\r\n * @return {String} 返回一个表示唯一 id 的字符串\r\n */\r\nconst guid = (() => {\r\n let uuid = 0\r\n\r\n return (prefix) => {\r\n uuid += 1\r\n\r\n return prefix ? prefix + '-' + uuid : 'guid-' + uuid\r\n }\r\n})()\r\n\r\nexport default guid\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 删除与给定 topic 相同的订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriber\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _removeSubscriber = (topic) => {\r\n if (!hasOwn(_subscribers, topic)) {\r\n return false\r\n }\r\n\r\n delete _subscribers[topic]\r\n}\r\n\r\nexport default _removeSubscriber\r\n","import has from './has'\r\nimport _removeSubscriber from './_removeSubscriber'\r\nimport _removeSubscriberByToken from './_removeSubscriberByToken'\r\n\r\n/**\r\n * 取消订阅主题\r\n * ========================================================================\r\n * @method off\r\n * @param {String} topic - (必须)订阅的主题\r\n * @param {Function|String} [token] - (可选)订阅主题的处理器函数或者唯一 Id 值\r\n */\r\nconst off = (topic, token) => {\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (token) {\r\n _removeSubscriberByToken(token)\r\n } else {\r\n _removeSubscriber(topic)\r\n }\r\n}\r\n\r\nexport default off\r\n","import _subscribers from './_subscribers'\r\nimport _removeSubscriber from './_removeSubscriber'\r\n\r\n/**\r\n * 通过订阅者 token 值删除订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriberByToken\r\n * @param {String} token - 订阅者 token 字符串\r\n * @returns {boolean}\r\n * @private\r\n */\r\nconst _removeSubscriberByToken = (token) => {\r\n const keys = Object.keys(_subscribers)\r\n let index = -1\r\n\r\n if (!token || keys.length < 1) {\r\n return false\r\n }\r\n\r\n keys.forEach((subject) => {\r\n const subscriber = _subscribers[subject]\r\n let topic\r\n\r\n subscriber.forEach((execution, j) => {\r\n if (execution.callback === token || execution.token === token) {\r\n topic = execution.topic\r\n subscriber.splice(index, j)\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (subscriber.length < 1) {\r\n _removeSubscriber(topic)\r\n }\r\n })\r\n}\r\n\r\nexport default _removeSubscriberByToken\r\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\nimport publish from './utils/observer/emit'\r\nimport subscribe from './utils/observer/on'\r\nimport unsubscribe from './utils/observer/off'\r\n\r\nclass Base {\r\n constructor(options) {\r\n this.attrs = {}\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n attr(prop, value) {\r\n const attrs = this.attrs\r\n\r\n if (isString(prop)) {\r\n // 只能扩展 attrs 中已有的属性\r\n if (value && hasOwn(attrs, prop)) {\r\n // 更新单个配置信息\r\n attrs[prop] = value\r\n return this\r\n }\r\n\r\n // 只传递 prop 参数,则返回对应的属性值\r\n return attrs[prop]\r\n } else if (isObject(prop)) {\r\n // 批量更新配置信息\r\n extend(attrs, prop)\r\n\r\n return this\r\n } else if (arguments.length === 0) {\r\n // 不传递参数,直接返回整个\r\n return attrs\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n return this\r\n }\r\n\r\n refresh() {\r\n return this\r\n }\r\n\r\n destroy() {\r\n this.removeListeners()\r\n return this\r\n }\r\n\r\n reload(options) {\r\n this.destroy().initialize(options)\r\n return this\r\n }\r\n\r\n $emit(event, data) {\r\n publish(event, data)\r\n return this\r\n }\r\n\r\n $on(event, callback) {\r\n subscribe(event, callback, this)\r\n return this\r\n }\r\n\r\n $off(event, callback) {\r\n unsubscribe(event, callback)\r\n return this\r\n }\r\n\r\n addListeners() {\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n return this\r\n }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\r\n\r\n/**\r\n * 扩展对象\r\n * ========================================================================\r\n * @method extend\r\n * @param {Object} origin\r\n * @param {Object} source\r\n */\r\nconst extend = (origin, source) => {\r\n const keys = Object.keys(source)\r\n\r\n keys.forEach((prop) => {\r\n if (hasOwn(source, prop)) {\r\n origin[prop] = source[prop]\r\n }\r\n })\r\n}\r\n\r\nexport default extend\r\n","import _subscribers from './_subscribers'\r\nimport isFunction from '../types/isFunction'\r\nimport guid from '../lang/guid'\r\n\r\n/**\r\n * 订阅主题,并给出处理器函数\r\n * ========================================================================\r\n * @method on\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Function} handler - (必须)主题的处理器函数\r\n * @param {Object} [context] - (可选)指定 this 执行上下文\r\n * @return {String} - 唯一的 token 字符串,例如:'guid-1'。\r\n */\r\nconst on = (topic, handler, context = null) => {\r\n const token = guid()\r\n let subject = typeof topic === 'symbol' ? topic.toString() : topic\r\n\r\n if (!isFunction(handler)) {\r\n return ''\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (!_subscribers[subject]) {\r\n _subscribers[subject] = []\r\n }\r\n\r\n _subscribers[subject].push({\r\n topic: subject,\r\n callback: handler,\r\n context,\r\n token\r\n })\r\n\r\n return token\r\n}\r\n\r\nexport default on\r\n","import isObject from './isObject'\r\n\r\n/**\r\n * 检测数据是否为 HTMLElement DOM 节点\r\n * ========================================================================\r\n * @method isElement\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isElement = (o) => {\r\n return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\r\n}\r\n\r\nexport default isElement\r\n","import isFunction from '../types/isFunction'\r\n\r\n/**\r\n * later - 延迟执行方法\r\n * ========================================================================\r\n * @method later\r\n * @param {Function} fn\r\n * @param {Number} [delay]\r\n * @returns {number|boolean}\r\n */\r\nconst later = (fn, delay = 300) => {\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n return setTimeout(() => {\r\n fn()\r\n }, delay)\r\n}\r\n\r\nexport default later\r\n","export const CAPTURE_EVENTS = [\r\n 'focusout',\r\n 'blur',\r\n 'focusin',\r\n 'focus',\r\n 'load',\r\n 'unload',\r\n 'mouseenter',\r\n 'mouseleave'\r\n]\r\n","import { CAPTURE_EVENTS } from './enum'\r\nimport _delete from './_delete'\r\n\r\n/**\r\n * (私有方法)取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method _off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} fn - (必须)事件处理器回调函数\r\n * @private\r\n */\r\nconst _off = (el, type, fn) => {\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n /* istanbul ignore else */\r\n if (fn._delegateListener) {\r\n fn = fn._delegateListener\r\n delete fn._delegateListener\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n _delete(el, type, fn)\r\n\r\n el.removeEventListener(type, fn, capture)\r\n}\r\n\r\nexport default _off\r\n","/**\r\n * 删除 DOM 元素缓存的 _listeners 数据\r\n * ========================================================================\r\n * @method _delete\r\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\r\n * @param {String} type - 事件类型(名称)\r\n * @param {Function} [fn] - 事件处理器回调函数\r\n */\r\nconst _delete = function (el, type, fn) {\r\n const listeners = el._listeners\r\n let index = -1\r\n\r\n if (listeners.length < 1) {\r\n return false\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n listeners.forEach((listener, i) => {\r\n const handler = listener.fn\r\n\r\n if (type === listener.type) {\r\n index = i\r\n\r\n if (handler === fn) {\r\n index = i\r\n }\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (index > -1) {\r\n listeners.splice(index, 1)\r\n }\r\n}\r\n\r\nexport default _delete\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\nimport getListeners from './getListeners'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 销毁(type 类型的)代理事件绑定\r\n * ========================================================================\r\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\r\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\r\n * ========================================================================\r\n * @method purgeElement\r\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\r\n * @param {String|Boolean} type - (必须)事件类型\r\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\r\n */\r\nconst purgeElement = function (el, type, recurse = false) {\r\n const $element = isString(el) ? document.querySelector(el) : el\r\n const $children = $element.childNodes\r\n const listeners = getListeners($element, type)\r\n\r\n listeners.forEach((listener) => {\r\n _off($element, listener.type, listener.fn)\r\n })\r\n\r\n if (\r\n (recurse || type === true || arguments.length === 1) &&\r\n $element &&\r\n $children\r\n ) {\r\n $children.forEach(($child) => {\r\n if (isElement($child)) {\r\n purgeElement($child, type, recurse)\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default purgeElement\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 获取 DOM 元素(type 事件类型)事件绑定信息\r\n * ========================================================================\r\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\r\n * ========================================================================\r\n * @methods getListeners\r\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\r\n * @param {String} [type] - (可选)事件类型\r\n * @returns {Array} - 已绑定的事件信息\r\n */\r\nconst getListeners = (el, type) => {\r\n let listeners = el._listeners || []\r\n\r\n if (isString(type) && type) {\r\n listeners = listeners.filter((listener) => {\r\n return listener.type === type\r\n })\r\n }\r\n\r\n return listeners\r\n}\r\n\r\nexport default getListeners\r\n","import purgeElement from './purgeElement'\r\nimport isFunction from '../types/isFunction'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method off\r\n * @param {HTMLElement|Object} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} [fn] - (可选)事件处理器回调函数\r\n */\r\nconst off = (el, type, fn) => {\r\n // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\r\n if (!isFunction(fn)) {\r\n purgeElement(el, type)\r\n return false\r\n }\r\n\r\n _off(el, type, fn)\r\n}\r\n\r\nexport default off\r\n","import isFunction from '../types/isFunction'\r\nimport off from './off'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定事件\r\n * ========================================================================\r\n * @method at\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (必须) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst at = (el, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n const listener = function (evt) {\r\n let overrideContext = context || el\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default at\r\n","/**\r\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\r\n * ========================================================================\r\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\r\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\r\n * 标 DOM 元素是否为事件代理所期望触发的目标。\r\n * ========================================================================\r\n * @method matches\r\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\r\n * @returns {Boolean}\r\n */\r\nconst matches = (el, selector = '') => {\r\n const sel = selector.replace(/^>/i, '')\r\n\r\n if (!selector || !sel || !el) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el.matches) {\r\n return el.matches(sel)\r\n } else if (el.msMatchesSelector) {\r\n return el.msMatchesSelector(sel)\r\n } else {\r\n return false\r\n }\r\n}\r\n\r\nexport default matches\r\n","/**\r\n * 获取 DOM 元素的父节点\r\n * ========================================================================\r\n * @method getParentOrHost\r\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\r\n * @returns {*|HTMLElement}\r\n */\r\nconst getParentOrHost = (el) => {\r\n return el.host && el !== document && el.host.nodeType\r\n ? el.host\r\n : el.parentNode\r\n}\r\n\r\nexport default getParentOrHost\r\n","import closest from '../dom/closest'\r\nimport off from './off'\r\nimport getTarget from './getTarget'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定代理事件\r\n * ========================================================================\r\n * @method on\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst on = (el, selector, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n const listener = function (evt) {\r\n const target = getTarget(evt)\r\n // 通过 Element.matches 方法获得点击的目标元素\r\n const delegateTarget = closest(target, selector, el)\r\n let overrideContext = context || el\r\n\r\n evt.delegateTarget = delegateTarget\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (delegateTarget) {\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n }\r\n\r\n if (!el) {\r\n return false\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n selector,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default on\r\n","import resolveTextNode from '../dom/resolveTextNode'\r\n\r\n/**\r\n * 返回触发事件的 target DOM 元素\r\n * ========================================================================\r\n * @method getTarget\r\n * @param {Event} evt - Event 对象\r\n * @return {HTMLElement} - Event 对象的 target DOM 元素\r\n */\r\nconst getTarget = function (evt) {\r\n const target = evt.target\r\n\r\n return resolveTextNode(target)\r\n}\r\n\r\nexport default getTarget\r\n","/**\r\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\r\n * resolveTextNode() 方法则会返回实际的目标节点。\r\n * ========================================================================\r\n * @method resolveTextNode\r\n * @param {HTMLElement|Text} el - 要解析的节点\r\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\r\n */\r\nconst resolveTextNode = function (el) {\r\n if (el && el.nodeType === 3) {\r\n return el.parentNode\r\n }\r\n\r\n return el\r\n}\r\n\r\nexport default resolveTextNode\r\n","import matches from './matches'\r\nimport getParentOrHost from './getParentOrHost'\r\n\r\n/**\r\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\r\n * ========================================================================\r\n * @method closest\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)DOM 元素的选择其\r\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\r\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\r\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\r\n */\r\nconst closest = (el, selector, ctx, includeCTX) => {\r\n const context = ctx || document\r\n\r\n if (!el) {\r\n return null\r\n }\r\n\r\n do {\r\n /* istanbul ignore else */\r\n if (\r\n (selector != null &&\r\n (selector.startsWith('>')\r\n ? el.parentNode === context && matches(el, selector)\r\n : matches(el, selector))) ||\r\n (includeCTX && el === context)\r\n ) {\r\n return el\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el === context) {\r\n break\r\n }\r\n\r\n /* jshint boss:true */\r\n } while ((el = getParentOrHost(el)))\r\n}\r\n\r\nexport default closest\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测数据是否为 Array 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isArray = (o) => {\r\n if (Array.isArray) {\r\n return Array.isArray(o)\r\n } else {\r\n return toString(o) === '[object Array]'\r\n }\r\n}\r\n\r\nexport default isArray\r\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isFragment = (fragment) => {\r\n return !!(\r\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\r\n )\r\n}\r\n\r\nexport default isFragment\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","import isObject from '../types/isObject'\r\nimport isString from '../types/isString'\r\nimport isArray from '../types/isArray'\r\nimport isDOM from '../types/isDOM'\r\nimport setAttributes from './setAttributes'\r\n\r\n/**\r\n * 创建 DOM 节点,并添加属性和子节点\r\n * ========================================================================\r\n * @method createElement\r\n * @param {String} tagName - 标签名称\r\n * @param {Object|Array|HTMLElement|DocumentFragment|String} attrs - 属性对象或者子节点\r\n * @param {Array|HTMLElement|DocumentFragment|String} [children] - 子节点数组\r\n * @returns {HTMLElement}\r\n */\r\nconst createElement = (tagName, attrs, children) => {\r\n const $fragment = document.createDocumentFragment()\r\n const $el = document.createElement(tagName)\r\n const isValidChild = (child) => {\r\n return isDOM(child) || isString(child)\r\n }\r\n const append = (child) => {\r\n let $child\r\n\r\n if (!isValidChild(child)) {\r\n return false\r\n }\r\n\r\n if (isDOM(child)) {\r\n $child = child\r\n } else if (isString(child)) {\r\n $child = document.createTextNode(child)\r\n }\r\n\r\n $fragment.appendChild($child)\r\n }\r\n\r\n if (isObject(attrs)) {\r\n setAttributes($el, attrs)\r\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\r\n attrs.forEach((child) => {\r\n append(child)\r\n })\r\n } else if (isDOM(attrs)) {\r\n append(attrs)\r\n } else if (isString(attrs)) {\r\n append(document.createTextNode(attrs))\r\n }\r\n\r\n if (isArray(children)) {\r\n children.forEach((child) => {\r\n append(child)\r\n })\r\n } else {\r\n append(children)\r\n }\r\n\r\n $el.appendChild($fragment)\r\n\r\n return $el\r\n}\r\n\r\nexport default createElement\r\n","import isObject from '../types/isObject'\r\nimport hasOwn from '../lang/hasOwn'\r\nimport setAttribute from './setAttribute'\r\n\r\nconst setAttributes = (el, attrs) => {\r\n if (!el || !isObject(attrs)) {\r\n return false\r\n }\r\n\r\n Object.keys(attrs).forEach((attr) => {\r\n const value = attrs[attr]\r\n if (hasOwn(attrs, attr)) {\r\n setAttribute(el, attr, value)\r\n }\r\n })\r\n}\r\n\r\nexport default setAttributes\r\n","/**\r\n * 给 DOM 节点设置属性/值\r\n * ========================================================================\r\n * @method setAttribute\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} attr - 属性名称\r\n * @param {String|Number|Boolean} value - 属性值\r\n */\r\nconst setAttribute = (el, attr, value) => {\r\n let tagName = el.tagName.toLowerCase()\r\n\r\n switch (attr) {\r\n case 'style':\r\n el.style.cssText = value\r\n break\r\n case 'value':\r\n if (tagName === 'input' || tagName === 'textarea') {\r\n el.value = value\r\n } else {\r\n el.setAttribute(attr, value)\r\n }\r\n break\r\n case 'htmlFor':\r\n el.setAttribute('for', value)\r\n break\r\n case 'className':\r\n el.className = value\r\n break\r\n case 'innerHTML':\r\n el.innerHTML = value\r\n break\r\n case 'innerText':\r\n el.innerText = value\r\n break\r\n default:\r\n el.setAttribute(attr, value)\r\n break\r\n }\r\n}\r\n\r\nexport default setAttribute\r\n","/**\r\n * 返回给定值的平方值\r\n * ========================================================================\r\n * @method easeInQuad\r\n * @param {Number} x\r\n * @returns {number}\r\n */\r\nconst easeInQuad = (x) => {\r\n return x * x\r\n}\r\n\r\nexport default easeInQuad\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\r\n * ========================================================================\r\n * @method _getScrollElement\r\n * @param {String|HTMLElement} scrollElement\r\n * @returns {Element}\r\n * @private\r\n */\r\nconst _getScrollElement = (scrollElement = null) => {\r\n let $rootElements\r\n let $scrollElement\r\n\r\n if (!scrollElement) {\r\n $rootElements = document.querySelectorAll('html,body')\r\n $scrollElement =\r\n $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\r\n ? $rootElements[0]\r\n : $rootElements[1]\r\n } else {\r\n if (isString(scrollElement)) {\r\n $scrollElement = document.querySelector(scrollElement)\r\n } else if (isElement(scrollElement)) {\r\n $scrollElement = scrollElement\r\n }\r\n }\r\n\r\n return $scrollElement\r\n}\r\n\r\nexport default _getScrollElement\r\n","import easeInQuad from '../lang/easeInQuad'\r\nimport isFunction from '../types/isFunction'\r\nimport _getScrollElement from './_getScrollElement'\r\n\r\n/**\r\n * 指定 rootElement DOM 节点滚动到指定 top 位置\r\n * ========================================================================\r\n * @method scrollTo\r\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\r\n * @param {Number} top - (必须)滚动的 scrollTop 数值\r\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\r\n */\r\nconst scrollTo = (scrollElement, top, afterStop) => {\r\n const $scrollElement = _getScrollElement(scrollElement)\r\n let scrollTop = $scrollElement.scrollTop\r\n let step = 0\r\n const distance = top - scrollTop\r\n const MAX_HEIGHT = $scrollElement.scrollHeight\r\n const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\r\n const stop = (top) => {\r\n if (isFunction(afterStop)) {\r\n afterStop(top)\r\n }\r\n\r\n return false\r\n }\r\n const play = () => {\r\n step += 1\r\n\r\n // 向上滚动\r\n if (distance < 0) {\r\n scrollTop -= easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop <= top) {\r\n $scrollElement.scrollTop = top\r\n return stop(top)\r\n }\r\n } else {\r\n scrollTop += easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop >= MAX_TOP) {\r\n $scrollElement.scrollTop = MAX_TOP\r\n return stop(MAX_TOP)\r\n }\r\n }\r\n\r\n // eslint-disable-next-line compat/compat\r\n requestAnimationFrame(play)\r\n }\r\n\r\n // eslint-disable-next-line compat/compat\r\n requestAnimationFrame(play)\r\n}\r\n\r\nexport default scrollTo\r\n","import isElement from '../types/isElement'\r\n/**\r\n * 检测 DOM 节点是否包含名为 className 的样式\r\n * ========================================================================\r\n * @method hasClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst hasClass = (el, className) => {\r\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\r\n let allClass\r\n let classList\r\n\r\n if (!isElement(el)) {\r\n return false\r\n }\r\n\r\n allClass = el.className\r\n\r\n if (!allClass) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList && classList.contains) {\r\n return el.classList.contains(className)\r\n }\r\n\r\n return !!pattern.exec(allClass)\r\n}\r\n\r\nexport default hasClass\r\n","import hasClass from './hasClass'\r\n\r\n/**\r\n * 给 DOM 节点添加名为 className 的样式\r\n * ========================================================================\r\n * @method addClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst addClass = (el, className) => {\r\n let classList\r\n let allClass\r\n\r\n if (hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.add) {\r\n classList.add(className)\r\n } else {\r\n allClass = el.className\r\n allClass += allClass.length > 0 ? ' ' + className : className\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default addClass\r\n","import trim from '../lang/trim'\r\nimport hasClass from './hasClass'\r\n\r\n/**\r\n * 移除 DOM 节点的 className 样式\r\n * ========================================================================\r\n * @method removeClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst removeClass = (el, className) => {\r\n let allClass = el.className\r\n let classList\r\n\r\n if (!allClass || !hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.remove) {\r\n classList.remove(className)\r\n } else {\r\n allClass = trim(allClass.replace(className, ''))\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default removeClass\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 清楚字符串起始位置所有的空格\r\n * ========================================================================\r\n * @method trim\r\n * @param {string} str\r\n * @returns {string|Boolean}\r\n */\r\nconst trim = (str) => {\r\n if (!isString(str)) {\r\n return false\r\n }\r\n return str.replace(/(^\\s+)|(\\s+$)/g, '')\r\n}\r\n\r\nexport default trim\r\n","/**\r\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\r\n * ========================================================================\r\n * @method offsetTop\r\n * @param {HTMLElement} el - DOM 节点\r\n * @returns {Number}\r\n */\r\nconst offsetTop = (el) => {\r\n let top = el.offsetTop\r\n\r\n if (el.offsetParent !== null) {\r\n top += offsetTop(el.offsetParent)\r\n }\r\n\r\n return top\r\n}\r\n\r\nexport default offsetTop\r\n","/**\r\n * 获取HTML元素的某个CSS样式值\r\n * ====================================================\r\n * @param el\r\n * @param ruleName\r\n * @returns {*}\r\n */\r\nconst getStyle = (el, ruleName) => {\r\n return getComputedStyle(el)[ruleName]\r\n}\r\n\r\nexport default getStyle\r\n","const setProperty = (prop, value) => {\r\n const documentElement = document.documentElement\r\n documentElement.style.setProperty(prop, value)\r\n}\r\n\r\nexport default setProperty\r\n","import isObject from '../types/isObject'\r\nimport isArray from '../types/isArray'\r\n\r\n/**\r\n * 深拷贝对象函数\r\n * ========================================================================\r\n * @methods cloneDeep\r\n * @param {Object} obj - 深拷贝的对象\r\n * @returns {Array|Object|*}\r\n *\r\n * @example\r\n * const arr = cloneDeep([2,3,4,6])\r\n * => [2,3,4,6]\r\n */\r\nconst cloneDeep = (obj) => {\r\n let clone = {}\r\n\r\n if (obj === null) {\r\n return null\r\n }\r\n\r\n if (isArray(obj)) {\r\n clone = Array.from(obj)\r\n } else {\r\n clone = Object.assign({}, obj)\r\n Object.keys(clone).forEach((key) => {\r\n return (clone[key] = isObject(obj[key]) ? cloneDeep(obj[key]) : obj[key])\r\n })\r\n }\r\n\r\n return clone\r\n}\r\n\r\nexport default cloneDeep\r\n","/**\r\n * timeSlice.js 时间切片功能函数\r\n * ====================================================\r\n * Created By: Yaohaixiao\r\n * Update: 2023.09.04\r\n */\r\nimport isFunction from '../types/isFunction'\r\nimport later from './later'\r\n\r\nconst queue = []\r\nlet isHandling\r\nlet done\r\n\r\n// Shim from https://developers.google.com/web/updates/2015/08/using-requestidlecallback\r\nif (typeof window.requestIdleCallback === 'undefined') {\r\n window.requestIdleCallback = function (cb) {\r\n const start = Date.now()\r\n return later(function () {\r\n cb({\r\n didTimeout: false,\r\n timeRemaining: function () {\r\n return Math.max(0, 50 - (Date.now() - start))\r\n }\r\n })\r\n }, 10)\r\n }\r\n\r\n window.cancelIdleCallback = function (id) {\r\n clearTimeout(id)\r\n }\r\n}\r\n\r\nfunction runIdle(idleDeadline) {\r\n while (idleDeadline.timeRemaining() > 0 && queue.length) {\r\n const fn = queue.shift()\r\n\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n fn()\r\n }\r\n\r\n if (queue.length) {\r\n isHandling = requestIdleCallback(runIdle)\r\n } else {\r\n isHandling = 0\r\n\r\n if (isFunction(done)) {\r\n done()\r\n done = null\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 时间切片功能函数:主要用于优化长时任务的性能,将长时任务分解成\r\n * 多个短时间任务\r\n * ====================================================\r\n * @param {Function} fn - 需要在空闲时执行的回调函数\r\n * @param {Function} afterComplete - queen 的\r\n * @return {(function(): (boolean|undefined))|*|boolean}\r\n */\r\nconst timeSlice = (fn, afterComplete = null) => {\r\n queue.push(fn)\r\n\r\n if (isFunction(afterComplete)) {\r\n done = afterComplete\r\n }\r\n\r\n if (!isHandling) {\r\n requestIdleCallback(runIdle)\r\n }\r\n}\r\n\r\nexport default timeSlice\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport later from './utils/lang/later'\r\nimport at from './utils/event/at'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport createElement from './utils/dom/createElement'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport addClass from './utils/dom/addClass'\r\nimport intersection from './utils/dom/intersection'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport getStyle from './utils/dom/getStyle'\r\nimport setProperty from './utils/dom/setProperty'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport cloneDeep from './utils/lang/cloneDeep'\r\n\r\nimport _paintChapters from './_paintChapters'\r\nimport inBounding from './utils/dom/inBounding'\r\n\r\nclass Chapters extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this._default()\r\n\r\n this.scrollTimer = null\r\n this.resizeTimer = null\r\n this.observerTimer = null\r\n this.Observer = null\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n _default() {\r\n this.attrs = cloneDeep(Chapters.DEFAULTS)\r\n\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.$active = null\r\n\r\n this.chapters = []\r\n this.active = 0\r\n this.offsetWidth = 0\r\n this.offsetTop = 0\r\n this.playing = false\r\n this.closed = false\r\n\r\n return this\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let parentElement\r\n let scrollElement\r\n let $parent\r\n\r\n this.attr(options)\r\n\r\n created = this.attr('created')\r\n parentElement = this.attr('parentElement')\r\n scrollElement = this.attr('scrollElement')\r\n\r\n if (isString(parentElement)) {\r\n $parent = document.querySelector(parentElement)\r\n } else if (isElement(parentElement)) {\r\n $parent = parentElement\r\n }\r\n this.$parentElement = $parent\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n\r\n this.chapters = this.attr('chapters')\r\n this.closed = this.attr('closed')\r\n this.active = this.attr('active')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n if (this.chapters.length < 1) {\r\n return this\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n this.$active = document.querySelector(`#chapter-${this.active}`)\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n isSticky() {\r\n const position = this.attr('position')\r\n return position === 'sticky'\r\n }\r\n\r\n isFixed() {\r\n const position = this.attr('position')\r\n return position === 'fixed'\r\n }\r\n\r\n isInside() {\r\n return this.isFixed() || this.isSticky()\r\n }\r\n\r\n isOutside() {\r\n return !this.isInside()\r\n }\r\n\r\n count() {\r\n return this.chapters.length\r\n }\r\n\r\n _paintEdge() {\r\n const $fragment = document.createDocumentFragment()\r\n const STICKY = 'outline-chapters_sticky'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const title = this.attr('title')\r\n const animationCurrent = this.attr('animationCurrent')\r\n const customClass = this.attr('customClass')\r\n const $parentElement = this.$parentElement\r\n const children = []\r\n const contents = []\r\n let $title = null\r\n let $el\r\n let $main\r\n let $list\r\n let $placeholder\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n if (this.isInside() && title) {\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-chapters__title'\r\n },\r\n title\r\n )\r\n this.$title = $title\r\n contents.push($title)\r\n }\r\n\r\n $list = createElement('ul', {\r\n // 为优化性能,添加了 _fixed 和 _hidden\r\n // fixed 为了让 $list 脱离流布局\r\n // hidden 让 $list 不可见\r\n className: `outline-chapters__list`\r\n })\r\n this.$list = $list\r\n children.push($list)\r\n\r\n if (animationCurrent) {\r\n $placeholder = createElement('div', {\r\n className: 'outline-chapters__placeholder'\r\n })\r\n this.$placeholder = $placeholder\r\n children.push($placeholder)\r\n }\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__main'\r\n },\r\n children\r\n )\r\n this.$main = $main\r\n contents.push($main)\r\n\r\n $el = createElement(\r\n 'nav',\r\n {\r\n id: 'outline-chapters',\r\n className: `outline-chapters ${HIDDEN}`\r\n },\r\n contents\r\n )\r\n this.$el = $el\r\n\r\n if (this.isSticky()) {\r\n this.calculateStickyHeight()\r\n addClass($el, STICKY)\r\n }\r\n\r\n if (customClass) {\r\n addClass($el, customClass)\r\n }\r\n $fragment.appendChild($el)\r\n $parentElement.appendChild($fragment)\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const $parentElement = this.$parentElement\r\n const chapters = this.chapters\r\n const count = this.count()\r\n let $el\r\n\r\n if (!$parentElement || chapters.length < 1) {\r\n return this\r\n }\r\n\r\n if (this.isInside()) {\r\n addClass($parentElement, 'outline-chapters-parent')\r\n }\r\n\r\n this._paintEdge()\r\n $el = this.$el\r\n\r\n this._paint(chapters)\r\n\r\n later(() => {\r\n this.highlight(this.active)\r\n }, 60)\r\n\r\n this.offsetTop = offsetTop($el)\r\n this.offsetWidth = $el.offsetWidth\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n setProperty('--outline-chapters-width', `${this.offsetWidth}px`)\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n if (count < 400) {\r\n this.onObserver()\r\n }\r\n\r\n return this\r\n }\r\n\r\n erase() {\r\n this.$list.innerHTML = ''\r\n\r\n return this\r\n }\r\n\r\n _paint(chapters) {\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const showCode = this.attr('showCode')\r\n const $el = this.$el\r\n const $list = this.$list\r\n\r\n _paintChapters($list, chapters, showCode)\r\n removeClass($el, HIDDEN)\r\n\r\n return this\r\n }\r\n\r\n _remove() {\r\n this.$parentElement.removeChild(this.$el)\r\n return this\r\n }\r\n\r\n refresh(chapters) {\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const $el = this.$el\r\n\r\n removeClass($el, HIDDEN)\r\n this.erase()._paint(chapters)\r\n\r\n return this\r\n }\r\n\r\n _getPlaceholderOffset(index) {\r\n const $main = this.$main\r\n const $list = this.$list\r\n const $anchor = $list.querySelector('.outline-chapters__anchor')\r\n const animationCurrent = this.attr('animationCurrent')\r\n const mainPaddingTop = parseInt(getStyle($main, 'padding-top'), 10)\r\n const mainBorderTop = parseInt(getStyle($main, 'border-top-width'), 10)\r\n const placeholderPaddingTop = parseInt(getStyle($list, 'padding-top'), 10)\r\n const placeholderMarginTop = parseInt(getStyle($list, 'margin-top'), 10)\r\n const placeholderBorderTop = parseInt(\r\n getStyle($list, 'border-top-width'),\r\n 10\r\n )\r\n let height = $anchor.offsetHeight\r\n let offsetTop = 0\r\n let top\r\n\r\n if (!animationCurrent) {\r\n return this\r\n }\r\n\r\n if (mainPaddingTop) {\r\n offsetTop += mainPaddingTop\r\n }\r\n\r\n if (placeholderPaddingTop) {\r\n offsetTop += placeholderPaddingTop\r\n }\r\n\r\n if (placeholderMarginTop) {\r\n offsetTop += placeholderMarginTop\r\n }\r\n\r\n if (mainBorderTop) {\r\n offsetTop += mainBorderTop\r\n }\r\n\r\n if (placeholderBorderTop) {\r\n offsetTop += placeholderBorderTop\r\n }\r\n\r\n top = height * index\r\n\r\n return offsetTop + top\r\n }\r\n\r\n positionPlaceholder(index) {\r\n const $list = this.$list\r\n const $placeholder = this.$placeholder\r\n const $anchor = $list.querySelector('.outline-chapters__anchor')\r\n const animationCurrent = this.attr('animationCurrent')\r\n const height = $anchor.offsetHeight\r\n let offsetTop = 0\r\n\r\n if (!animationCurrent) {\r\n return this\r\n }\r\n\r\n offsetTop = this._getPlaceholderOffset(index)\r\n\r\n $placeholder.style.cssText = `transform: translateY(${offsetTop}px);height:${height}px;`\r\n\r\n return this\r\n }\r\n\r\n highlight(id) {\r\n const $el = this.$el\r\n const animationCurrent = this.attr('animationCurrent')\r\n const ACTIVE = 'outline-chapters_active'\r\n const HIGHLIGHT = 'outline-chapters_highlight'\r\n let $anchor = null\r\n let placeholderOffsetTop = 0\r\n\r\n if (!$el) {\r\n return this\r\n }\r\n\r\n $anchor = $el.querySelector(`#chapter__anchor-${id}`)\r\n\r\n if (!$anchor) {\r\n return this\r\n }\r\n\r\n this.active = parseInt($anchor.getAttribute('data-id'), 10)\r\n\r\n if (this.$active) {\r\n removeClass(this.$active, HIGHLIGHT)\r\n removeClass(this.$active, ACTIVE)\r\n }\r\n\r\n this.$active = $anchor\r\n addClass(this.$active, ACTIVE)\r\n\r\n if (animationCurrent) {\r\n this.positionPlaceholder(this.active)\r\n\r\n later(() => {\r\n if (!inBounding(this.$active, this.$parentElement)) {\r\n placeholderOffsetTop = this._getPlaceholderOffset(this.active)\r\n scrollTo(this.$main, placeholderOffsetTop)\r\n }\r\n })\r\n } else {\r\n addClass(this.$active, HIGHLIGHT)\r\n }\r\n\r\n return this\r\n }\r\n\r\n sticky() {\r\n const afterSticky = this.attr('afterSticky')\r\n const FIXED = 'outline-chapters_fixed'\r\n const $el = this.$el\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (!this.isFixed()) {\r\n return this\r\n }\r\n\r\n isStickying = scrollTop >= top\r\n\r\n if (isStickying) {\r\n addClass($el, FIXED)\r\n } else {\r\n removeClass($el, FIXED)\r\n }\r\n\r\n if (isFunction(afterSticky)) {\r\n afterSticky.call(this, this.isClosed(), isStickying)\r\n }\r\n\r\n return this\r\n }\r\n\r\n calculateStickyHeight() {\r\n const documentElement = document.documentElement\r\n const height = Math.max(\r\n documentElement.clientHeight || 0,\r\n window.innerHeight || 0\r\n )\r\n setProperty('--outline-sticky-height', `${height}px`)\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n show() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const opened = this.attr('afterOpened')\r\n const count = this.count()\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n if (count > 800) {\r\n removeClass($parent, HIDDEN)\r\n } else {\r\n removeClass($parent, HIDDEN)\r\n later(() => {\r\n removeClass($parent, FOLDED)\r\n }, 30)\r\n }\r\n } else {\r\n removeClass($el, HIDDEN)\r\n }\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const closed = this.attr('afterClosed')\r\n const count = this.count()\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n if (count > 800) {\r\n addClass($parent, HIDDEN)\r\n } else {\r\n addClass($parent, FOLDED)\r\n later(() => {\r\n addClass($parent, HIDDEN)\r\n })\r\n }\r\n } else {\r\n addClass($el, HIDDEN)\r\n }\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n isStickying = scrollTop >= top\r\n afterToggle.call(this, this.isClosed(), isStickying)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()._remove()._default()\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n this.scrollTimer = null\r\n }\r\n\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n this.resizeTimer = null\r\n }\r\n\r\n if (this.observerTimer) {\r\n clearTimeout(this.observerTimer)\r\n this.observerTimer = null\r\n }\r\n\r\n if (this.Observer) {\r\n this.Observer = null\r\n }\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onObserver() {\r\n const selector = this.attr('selector')\r\n\r\n this.Observer = intersection(\r\n ($heading) => {\r\n const id = $heading.getAttribute('data-id')\r\n\r\n if (this.playing) {\r\n return false\r\n }\r\n\r\n if (this.observerTimer) {\r\n clearTimeout(this.observerTimer)\r\n }\r\n\r\n this.observerTimer = later(() => {\r\n this.highlight(id)\r\n }, 100)\r\n },\r\n {\r\n selector,\r\n context: this\r\n }\r\n )\r\n\r\n return this\r\n }\r\n\r\n onSelect(evt) {\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const id = $anchor.getAttribute('data-id')\r\n const headingId = $anchor.href.split('#')[1]\r\n const $heading = document.querySelector(`#${headingId}`)\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const min = 0\r\n const max = this.$scrollElement.scrollHeight\r\n const afterScroll = this.attr('afterScroll')\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this, 'chapter')\r\n }\r\n\r\n later(() => {\r\n this.playing = false\r\n this.$emit('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.playing = true\r\n if (this.isFixed()) {\r\n this.sticky()\r\n later(() => {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }, 10)\r\n } else {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }\r\n\r\n stop(evt)\r\n\r\n return this\r\n }\r\n\r\n onScroll() {\r\n const $scrollElement = this.$scrollElement\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n }\r\n\r\n this.scrollTimer = later(() => {\r\n const top = $scrollElement.scrollTop\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n }\r\n\r\n this.$emit('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n }, 100)\r\n\r\n return this\r\n }\r\n\r\n onResize() {\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n }\r\n\r\n this.resizeTimer = later(() => {\r\n this.calculateStickyHeight()\r\n })\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (this.count() < 1) {\r\n return this\r\n }\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n on($el, '.outline-chapters__anchor', 'click', this.onSelect, this, true)\r\n at($element, 'scroll', this.onScroll, this, true)\r\n if (this.isSticky()) {\r\n at(window, 'resize', this.onResize, this, true)\r\n }\r\n this.$on('anchors:all:paint', this.onObserver, this)\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const selector = this.attr('selector')\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (this.count() < 1) {\r\n return this\r\n }\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n off($el, 'click', this.onSelect)\r\n off($element, 'scroll', this.onScroll)\r\n if (this.isSticky()) {\r\n off(window, 'resize', this.onResize)\r\n }\r\n this.$off('anchors:all:paint')\r\n\r\n if (this.Observer) {\r\n document.querySelectorAll(selector).forEach((section) => {\r\n this.Observer.unobserve(section)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n}\r\n\r\nChapters.DEFAULTS = {\r\n parentElement: '',\r\n scrollElement: '',\r\n selector: '.outline-heading',\r\n active: 0,\r\n closed: false,\r\n showCode: true,\r\n animationCurrent: true,\r\n position: 'relative',\r\n stickyHeight: 0,\r\n chapters: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterSticky: null\r\n}\r\n\r\nexport default Chapters\r\n","import createElement from './utils/dom/createElement'\r\nimport timeSlice from './utils/lang/timeSlice'\r\n\r\nconst _paintChapters = ($list, chapters, showCode = false) => {\r\n const LIMIT = 400\r\n const count = chapters.length\r\n const clones = [...chapters]\r\n const paint = (parts) => {\r\n const byId = (id) => $list.querySelector(`#${id}`)\r\n parts.forEach((chapter) => {\r\n const pid = chapter.pid\r\n const id = chapter.id\r\n const rel = chapter.rel\r\n const children = []\r\n const $text = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__text'\r\n },\r\n chapter.text\r\n )\r\n let $link\r\n let $code\r\n let $li\r\n let $subject\r\n let $chapter\r\n\r\n if (showCode) {\r\n $code = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__code',\r\n 'data-id': id\r\n },\r\n chapter.code\r\n )\r\n\r\n children.push($code)\r\n }\r\n\r\n children.push($text)\r\n\r\n $link = createElement(\r\n 'a',\r\n {\r\n id: `chapter__anchor-${id}`,\r\n className: 'outline-chapters__anchor',\r\n href: '#' + rel,\r\n rel: rel,\r\n 'data-id': id\r\n },\r\n children\r\n )\r\n\r\n $li = createElement(\r\n 'li',\r\n {\r\n id: `chapter-${id}`,\r\n className: 'outline-chapters__item',\r\n 'data-id': id\r\n },\r\n $link\r\n )\r\n\r\n if (pid === -1) {\r\n $list.appendChild($li)\r\n } else {\r\n $chapter = byId(`chapter-${pid}`)\r\n $subject = byId(`subject-${pid}`)\r\n\r\n if (!$subject) {\r\n $subject = createElement(\r\n 'ul',\r\n {\r\n id: 'subject-' + pid,\r\n className: 'outline-chapters__subject'\r\n },\r\n $li\r\n )\r\n\r\n $chapter.appendChild($subject)\r\n } else {\r\n $subject.appendChild($li)\r\n }\r\n }\r\n })\r\n }\r\n\r\n if (count > LIMIT) {\r\n // 同步绘制\r\n paint(clones.splice(0, LIMIT))\r\n // 剩余的采用 timeSlice 机制绘制\r\n while (clones.length > 0) {\r\n const once = clones.splice(0, LIMIT)\r\n timeSlice(() => {\r\n paint(once)\r\n })\r\n }\r\n } else {\r\n paint(clones)\r\n }\r\n}\r\n\r\nexport default _paintChapters\r\n","import isElement from '../types/isElement'\r\n\r\n/**\r\n * 检测某个 DOM 节点的位置是否在另个一个 DOM 节点范围内\r\n * ========================================================================\r\n * @method inBounding\r\n * @param {HTMLElement} child\r\n * @param {HTMLElement} parent\r\n * @return {Boolean}\r\n */\r\nconst inBounding = (child, parent) => {\r\n let parentRect\r\n let childRect\r\n\r\n if (!isElement(child) || !isElement(parent)) {\r\n return false\r\n }\r\n\r\n parentRect = parent.getBoundingClientRect()\r\n childRect = child.getBoundingClientRect()\r\n\r\n return (\r\n childRect.top >= parentRect.top &&\r\n childRect.right <= parentRect.right &&\r\n childRect.bottom <= parentRect.bottom &&\r\n childRect.left >= parentRect.left\r\n )\r\n}\r\n\r\nexport default inBounding\r\n","import isFunction from '../types/isFunction'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通用的 IntersectionObserver 观察者处理器\r\n * ========================================================================\r\n * @method intersection\r\n * @param {Function} fn\r\n * @param {Object} [props]\r\n * @param {Object|HTMLElement} [props.root]\r\n * @param {String} [props.selector]\r\n * @param {Object} [props.context]\r\n * @param {String} [props.attr]\r\n * @param {String} [props.rootMargin]\r\n */\r\nconst intersection = (fn, props = {}) => {\r\n const root = props.root || null\r\n const selector = props.selector || '.outline-heading'\r\n const context = props.context || null\r\n const rootMargin = props.rootMargin || '0px 0px -90% 0px'\r\n const options = {\r\n rootMargin: rootMargin\r\n }\r\n // eslint-disable-next-line compat/compat\r\n const Observer = new IntersectionObserver((entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.intersectionRatio > 0) {\r\n if (isFunction(fn)) {\r\n fn.call(context || entry.target, entry.target)\r\n }\r\n }\r\n })\r\n }, options)\r\n const $root = isElement(root) ? root : document\r\n\r\n if (root) {\r\n options.root = root\r\n }\r\n\r\n $root.querySelectorAll(selector).forEach((section) => {\r\n Observer.observe(section)\r\n })\r\n\r\n return Observer\r\n}\r\n\r\nexport default intersection\r\n","/**\r\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\r\n * ========================================================================\r\n * @method stop\r\n * @param {Event} evt - 事件对象\r\n *\r\n * @example\r\n * <div id=\"nav\" class=\"nav\">\r\n * <a id=\"service\" class=\"anchor\" href=\"https://www.yaohaixiao.com/serivce\">Service</a>\r\n * <a id=\"help\" class=\"anchor\" href=\"https://www.yaohaixiao.com/help\">Help</a>\r\n * </div>\r\n *\r\n * const $nav = document.querySelector('#nav')\r\n * const $service = document.querySelector('.anchor')\r\n *\r\n * on($nav, 'click', function(evt) {\r\n * console.log('你点击了导航栏')\r\n * })\r\n *\r\n * on($anchor, 'click', function(evt) {\r\n * console.log('tagName', this.tagName)\r\n *\r\n * // 工作台输出:'a'\r\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\r\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\r\n * stopEvent(evt)\r\n * })\r\n */\r\nconst stop = function (evt) {\r\n evt.stopPropagation()\r\n evt.preventDefault()\r\n}\r\n\r\nexport default stop\r\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","_subscribers","_hasDirectSubscribersFor","topic","length","has","arguments","undefined","found","position","lastIndexOf","substring","_hasSubscribers","emit","data","async","execute","forEach","subscriber","message","indexOf","callback","context","deliver","setTimeout","guid","uuid","prefix","_removeSubscriber","off","token","keys","subject","execution","j","splice","_removeSubscriberByToken","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","extend","refresh","destroy","removeListeners","reload","$emit","event","publish","$on","handler","push","subscribe","$off","unsubscribe","isElement","nodeName","tagName","nodeType","later","fn","delay","CAPTURE_EVENTS","_off","el","type","capture","_delegateListener","listeners","_listeners","index","listener","i","_delete","removeEventListener","purgeElement","recurse","$element","document","querySelector","$children","childNodes","getListeners","filter","$child","at","once","evt","overrideContext","addEventListener","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","on","target","getTarget","delegateTarget","closest","ctx","includeCTX","startsWith","isArray","Array","isDOM","isHTMLCollection","fragment","isTextNode","createElement","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","setAttributes","setAttribute","toLowerCase","style","cssText","className","innerHTML","innerText","every","easeInQuad","x","_getScrollElement","$rootElements","$scrollElement","scrollElement","querySelectorAll","scrollTop","scrollTo","top","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","hasClass","pattern","RegExp","allClass","classList","contains","exec","addClass","_classList","add","removeClass","remove","offsetTop","offsetParent","getStyle","ruleName","getComputedStyle","setProperty","documentElement","cloneDeep","clone","from","assign","key","queue","isHandling","done","runIdle","idleDeadline","timeRemaining","shift","requestIdleCallback","window","cb","start","Date","now","didTimeout","Math","max","cancelIdleCallback","id","clearTimeout","timeSlice","afterComplete","Chapters","super","_default","scrollTimer","resizeTimer","observerTimer","Observer","DEFAULTS","$title","$main","$list","$placeholder","$parentElement","$active","chapters","active","offsetWidth","playing","closed","created","parentElement","$parent","isClosed","isSticky","isFixed","isInside","isOutside","count","_paintEdge","title","animationCurrent","customClass","contents","calculateStickyHeight","mounted","_paint","highlight","sticky","onObserver","erase","showCode","clones","paint","parts","byId","chapter","pid","rel","$text","text","$link","$code","$li","$subject","$chapter","code","href","_paintChapters","_remove","removeChild","_getPlaceholderOffset","$anchor","mainPaddingTop","parseInt","mainBorderTop","placeholderPaddingTop","placeholderMarginTop","placeholderBorderTop","height","offsetHeight","positionPlaceholder","ACTIVE","HIGHLIGHT","placeholderOffsetTop","getAttribute","inBounding","parent","parentRect","childRect","getBoundingClientRect","right","bottom","left","afterSticky","FIXED","isStickying","clientHeight","innerHeight","after","show","HIDDEN","opened","hide","toggle","afterToggle","beforeDestroy","afterDestroy","props","root","rootMargin","IntersectionObserver","entries","entry","intersectionRatio","$root","section","observe","intersection","$heading","onSelect","stickyHeight","headingId","split","afterScroll","min","stopPropagation","preventDefault","onScroll","onResize","unobserve","afterClosed","afterOpened"],"mappings":"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"}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/scrsxx/outline.js.git
git@gitee.com:scrsxx/outline.js.git
scrsxx
outline.js
outline.js
master

搜索帮助