chore: 重写初始提交(清空历史,整理后全量提交)
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
/**
|
||||
* YwxApp 文档中心前台脚本
|
||||
*
|
||||
* 提供:目录折叠、移动端抽屉、代码复制、右侧锚点滚动高亮、版本切换。
|
||||
* 纯原生实现,不依赖任何库。
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
initTreeToggle();
|
||||
initMobileDrawer();
|
||||
initCodeCopy();
|
||||
initTocScrollSpy();
|
||||
initVersionSwitch();
|
||||
scrollActiveIntoView();
|
||||
});
|
||||
|
||||
/**
|
||||
* 侧边目录展开与折叠
|
||||
*/
|
||||
function initTreeToggle() {
|
||||
var tree = document.querySelector('.dc-tree');
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
tree.addEventListener('click', function (e) {
|
||||
var toggle = e.target.closest('.dc-tree-toggle');
|
||||
var dirLink = e.target.closest('.dc-tree-link.is-dir');
|
||||
var trigger = toggle || dirLink;
|
||||
|
||||
if (!trigger) {
|
||||
return;
|
||||
}
|
||||
|
||||
var li = trigger.closest('li');
|
||||
if (li) {
|
||||
li.classList.toggle('is-open');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动端侧边栏抽屉
|
||||
*/
|
||||
function initMobileDrawer() {
|
||||
var btn = document.getElementById('dcMenuToggle');
|
||||
var sidebar = document.getElementById('dcSidebar');
|
||||
var mask = document.getElementById('dcMask');
|
||||
|
||||
if (!btn || !sidebar) {
|
||||
return;
|
||||
}
|
||||
|
||||
function close() {
|
||||
sidebar.classList.remove('is-open');
|
||||
if (mask) {
|
||||
mask.classList.remove('is-show');
|
||||
}
|
||||
}
|
||||
|
||||
btn.addEventListener('click', function () {
|
||||
sidebar.classList.toggle('is-open');
|
||||
if (mask) {
|
||||
mask.classList.toggle('is-show', sidebar.classList.contains('is-open'));
|
||||
}
|
||||
});
|
||||
|
||||
if (mask) {
|
||||
mask.addEventListener('click', close);
|
||||
}
|
||||
|
||||
// 点击目录项后自动收起抽屉
|
||||
sidebar.addEventListener('click', function (e) {
|
||||
if (e.target.closest('a.dc-tree-link') && window.innerWidth <= 860) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('resize', function () {
|
||||
if (window.innerWidth > 860) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 代码块复制按钮
|
||||
*/
|
||||
function initCodeCopy() {
|
||||
var blocks = document.querySelectorAll('.dc-content pre');
|
||||
|
||||
Array.prototype.forEach.call(blocks, function (pre) {
|
||||
var btn = document.createElement('button');
|
||||
btn.className = 'dc-copy-btn';
|
||||
btn.type = 'button';
|
||||
btn.textContent = '复制';
|
||||
|
||||
btn.addEventListener('click', function () {
|
||||
var code = pre.querySelector('code');
|
||||
var text = code ? code.innerText : pre.innerText;
|
||||
|
||||
copyText(text, function (ok) {
|
||||
btn.textContent = ok ? '已复制' : '复制失败';
|
||||
btn.classList.toggle('is-done', ok);
|
||||
setTimeout(function () {
|
||||
btn.textContent = '复制';
|
||||
btn.classList.remove('is-done');
|
||||
}, 1600);
|
||||
});
|
||||
});
|
||||
|
||||
pre.appendChild(btn);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制文本到剪贴板,兼容不支持 Clipboard API 的环境
|
||||
*
|
||||
* @param {string} text 待复制文本
|
||||
* @param {Function} cb 回调,参数为是否成功
|
||||
*/
|
||||
function copyText(text, cb) {
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
navigator.clipboard.writeText(text).then(function () {
|
||||
cb(true);
|
||||
}).catch(function () {
|
||||
cb(fallbackCopy(text));
|
||||
});
|
||||
return;
|
||||
}
|
||||
cb(fallbackCopy(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* 兜底复制方案
|
||||
*
|
||||
* @param {string} text 待复制文本
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function fallbackCopy(text) {
|
||||
var ta = document.createElement('textarea');
|
||||
ta.value = text;
|
||||
ta.style.position = 'fixed';
|
||||
ta.style.opacity = '0';
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
|
||||
var ok = false;
|
||||
try {
|
||||
ok = document.execCommand('copy');
|
||||
} catch (err) {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
document.body.removeChild(ta);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* 右侧锚点滚动高亮
|
||||
*/
|
||||
function initTocScrollSpy() {
|
||||
var toc = document.getElementById('dcToc');
|
||||
var content = document.getElementById('dcContent');
|
||||
|
||||
if (!toc || !content) {
|
||||
return;
|
||||
}
|
||||
|
||||
var links = Array.prototype.slice.call(toc.querySelectorAll('a[data-anchor]'));
|
||||
if (!links.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var headings = links.map(function (link) {
|
||||
return document.getElementById(link.getAttribute('data-anchor'));
|
||||
}).filter(Boolean);
|
||||
|
||||
if (!headings.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var offset = 90;
|
||||
var ticking = false;
|
||||
|
||||
function update() {
|
||||
var current = 0;
|
||||
|
||||
for (var i = 0; i < headings.length; i++) {
|
||||
if (headings[i].getBoundingClientRect().top <= offset) {
|
||||
current = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
links.forEach(function (link, index) {
|
||||
link.classList.toggle('is-active', index === current);
|
||||
});
|
||||
|
||||
ticking = false;
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', function () {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(update);
|
||||
ticking = true;
|
||||
}
|
||||
}, { passive: true });
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 版本切换:保持当前文档路径,仅替换版本段
|
||||
*/
|
||||
function initVersionSwitch() {
|
||||
var select = document.getElementById('dcVersionSelect');
|
||||
if (!select) {
|
||||
return;
|
||||
}
|
||||
|
||||
select.addEventListener('change', function () {
|
||||
var opt = select.options[select.selectedIndex];
|
||||
var isDefault = opt.getAttribute('data-default') === '1';
|
||||
|
||||
// 地址形如 /docs/<项目>[/<版本>]/<文档>
|
||||
var parts = window.location.pathname.split('/').filter(Boolean);
|
||||
if (parts.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
var project = parts[1];
|
||||
var docName = parts[parts.length - 1];
|
||||
|
||||
// 只有项目段时说明还未进入具体文档
|
||||
if (parts.length === 2) {
|
||||
window.location.href = '/docs/' + project;
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = isDefault
|
||||
? '/docs/' + project + '/' + docName
|
||||
: '/docs/' + project + '/' + select.value + '/' + docName;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 让当前选中的目录项进入可视区域
|
||||
*/
|
||||
function scrollActiveIntoView() {
|
||||
var active = document.querySelector('.dc-tree-item.is-active');
|
||||
var sidebar = document.getElementById('dcSidebar');
|
||||
|
||||
if (!active || !sidebar) {
|
||||
return;
|
||||
}
|
||||
|
||||
var top = active.offsetTop - sidebar.clientHeight / 2;
|
||||
if (top > 0) {
|
||||
sidebar.scrollTop = top;
|
||||
}
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user