(() => {
// 当代码块内容高度超出多少像素时折叠,默认是300px
const codeMaxHeight = 300;
// 添加样式
addStyle(`
.code-block .code-down {
width: 100%;
text-align: center;
position: absolute;
bottom: 0px;
left: 0;
padding: 70px 0px 10px;
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
}
.code-block .code-down-btn {
padding: 3px 14px 1px;
background: rgba(0, 0, 0, 0.5);
border-radius: 5px;
cursor: pointer;
}
.code-block .code-down-arrow{
width: 13px;
height: 13px;
}
[data-theme-mode="light"] .code-block .code-down {
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1));
}
[data-theme-mode="light"] .code-block .code-down-btn {
background-color: rgba(255, 255, 255, 0.6);
}
[data-theme-mode="dark"] .code-block .code-down {
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5) 70%, rgba(255, 255, 255, 1));
}
[data-theme-mode="dark"] .code-block .code-down-btn {
background-color: rgba(0, 0, 0, 0.5);
}
div:not(#preview) > .protyle-wysiwyg .code-block .hljs {
max-height: ${codeMaxHeight || 300}px;
}
@media (max-width: 768px) {
.code-block .code-down-btn {
padding: 10px 20px;
}
}
`);
function isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
whenElementExist('body').then(async el => {
let protyle;
await whenElementExist(() => {
protyle = el.querySelector('.protyle');
return protyle && protyle?.dataset?.loading === 'finished';
});
addCodeExtends(protyle.querySelectorAll('.code-block'));
let scrollContainer = isMobile() ? window : protyle.querySelector(".protyle-content");
let debounceTimer;
scrollContainer.addEventListener('scroll', () => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
addCodeExtends(protyle.querySelectorAll('.code-block'));
}, 100);
});
observeProtyleAddition(el, protyles => {
protyles.forEach(async protyle => {
if(!protyle.classList.contains('protyle')) {
protyle = protyle.closest('.protyle');
}
addCodeExtends(protyle.querySelectorAll('.code-block'));
let scrollContainer = isMobile() ? window : protyle.querySelector(".protyle-content");
scrollContainer.addEventListener('scroll', () => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
addCodeExtends(protyle.querySelectorAll('.code-block'));
}, 100);
});
});
});
});
let runing = false;
function addCodeExtends(codeBlocks) {
if(codeBlocks.length === 0) return;
if(runing) return;
runing = true;
setTimeout(() => {runing = false;}, 300);
codeBlocks.forEach(async codeBlock => {
if(isCursorInCodeBlock(codeBlock)) {
codeBlock.querySelector('.hljs').style.maxHeight = '100%';
return;
}
if(codeBlock.querySelector('.code-down')) return;
const hljs = await whenElementExist(() => codeBlock.querySelector('.hljs'));
if(hljs && hljs.scrollHeight > codeMaxHeight) {
const expand = document.createElement('div');
expand.className = 'code-down protyle-custom';
expand.innerHTML = `<span class="code-down-btn"><svg class="code-down-arrow"><use xlink:href="#iconDown"></use></svg></span>`;
codeBlock.appendChild(expand);
expand.closest('.code-block').querySelector('.hljs').style.maxHeight = codeMaxHeight+'px';
expand.querySelector('.code-down-btn').onclick = () => {
expand.style.display = 'none';
expand.closest('.code-block').querySelector('.hljs').style.maxHeight = '100%';
};
}
});
}
function addStyle(cssRules) {
const styleElement = document.createElement('style');
styleElement.innerHTML = cssRules;
document.head.appendChild(styleElement);
}
function observeProtyleAddition(el, callback) {
const config = { attributes: false, childList: true, subtree: true };
const observer = new MutationObserver((mutationsList, observer) => {
mutationsList.forEach(mutation => {
if (mutation.type === 'childList') {
const protyles = Array.from(mutation.addedNodes).filter(node =>
node.nodeType === Node.ELEMENT_NODE &&
(node.classList.contains('protyle') || node.classList.contains('protyle-content'))
);
if (protyles.length > 0) {
callback(protyles);
}
}
});
});
observer.observe(el, config);
return () => {
observer.disconnect();
};
}
function isCursorInCodeBlock(codeBlock) {
if(!codeBlock) return false;
let cursorEl = getCursorElement();
if(!cursorEl) return false;
cursorEl = cursorEl.closest('.code-block');
if(!cursorEl) return false;
return cursorEl === codeBlock;
}
function getCursorElement() {
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const startContainer = range.startContainer;
const cursorElement = startContainer.nodeType === Node.TEXT_NODE
? startContainer.parentElement
: startContainer;
return cursorElement;
}
return null;
}
function whenElementExist(selector) {
return new Promise(resolve => {
const checkForElement = () => {
let element = null;
if (typeof selector === 'function') {
element = selector();
} else {
element = document.querySelector(selector);
}
if (element) {
resolve(element);
} else {
requestAnimationFrame(checkForElement);
}
};
checkForElement();
});
}
})();
// see https://ld246.com/article/1727096963532
(async ()=>{
whenElementExist('.sy__outline > .fn__flex-1').then(async el => {
// 监听大纲标题被添加
observeChildAddition(el, node => {
return node.tagName.toLowerCase() === 'ul' &&
node.classList.contains('b3-list') &&
node.querySelector('.b3-list-item')
}, uls => {
// 获取大纲列表
const ul = uls[0];
// 遍历大纲第一级子元素
Array.from(ul.children).forEach(item => {
// 初始时,仅打开第一级
if(item.tagName === 'LI') {
const toggleBtn = item.querySelector('.b3-list-item__toggle');
const svg = toggleBtn?.querySelector('svg.b3-list-item__arrow');
if(!svg.classList.contains('b3-list-item__arrow--open')) {
svg.classList.add('b3-list-item__arrow--open');
}
}
if(item.tagName === 'UL') {
if(item.classList.contains('fn__none')) {
item.remove('fn__none');
}
// 初始时,隐藏第一级下面的后代元素
itemsShow(item, false);
}
// 监听大纲鼠标移入事件
const ul = item.tagName === 'LI' ? item.nextElementSibling : item;
item.addEventListener('mouseenter', (event) => {
if(!ul || ul?.tagName !== 'UL') return;
// 鼠标移入显示第一级后面的后代元素
itemsShow(ul, true);
})
// 监听大纲鼠标移出事件
item.addEventListener('mouseleave', (event) => {
if(!ul || ul?.tagName !== 'UL') return;
// 鼠标移出隐藏第一级后面的后代元素
itemsShow(ul, false);
});
});
});
});
// 动态显示隐藏子标题
function itemsShow(ul, isOpen) {
if(isOpen){
const svgs = ul.querySelectorAll('span.b3-list-item__toggle svg:not(.b3-list-item__arrow--open)');
svgs.forEach(item => {
item.classList.add('b3-list-item__arrow--open');
});
const uls = ul.querySelectorAll('ul.fn__none');
uls.forEach(item => {
item.classList.remove('fn__none');
});
} else {
const svgs = ul.querySelectorAll('span.b3-list-item__toggle svg.b3-list-item__arrow--open');
svgs.forEach(item => {
item.classList.remove('b3-list-item__arrow--open');
});
const uls = ul.querySelectorAll('ul:not(.fn__none)');
uls.forEach(item => {
item.classList.add('fn__none');
});
}
}
function observeChildAddition(el, filter, handler) {
// 配置观察器选项
const config = { attributes: false, childList: true, subtree: false };
// 定义回调函数
const callback = function(mutationsList, observer) {
// 遍历 mutation 列表
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
console.log(mutation, 111);
// 查找新增加的具有类名 'b3-list' 的 ul 元素
const newULs = Array.from(mutation.addedNodes).filter(node => node.nodeType === Node.ELEMENT_NODE && filter(node));
// 如果有新的 ul 元素被添加,则调用处理函数
if(newULs.length > 0) {
handler(newULs);
}
}
}
};
// 创建一个新的 MutationObserver 实例
const observer = new MutationObserver(callback);
// 开始观察目标节点
observer.observe(el, config);
// 返回一个函数来停止观察
return () => {
observer.disconnect();
};
}
// 等待元素渲染完成后执行
function whenElementExist(selector, bySetTimeout = false, delay = 40) {
return new Promise(resolve => {
const checkForElement = () => {
let element = null;
if (typeof selector === 'function') {
element = selector();
} else {
element = document.querySelector(selector);
}
if (element) {
resolve(element);
} else {
if (bySetTimeout) {
setTimeout(checkForElement, delay);
} else {
requestAnimationFrame(checkForElement);
}
}
};
checkForElement();
});
}
})();
// 顶栏倒计时 JS片段 https://ld246.com/article/17211686880/comment/17274133697#comments
// 设置文本内容和目标日期
const countdownMessage = '距离<span style="color: red; font-weight: bold;">国庆结束</span>剩余 ${daysLeft} 天';
const targetDateString = '2025-1-8';
const targetDate = new Date(targetDateString);
function startCountdown(targetDate) {
// 计算剩余天数的函数
function calculateDaysLeft() {
let currentDate = new Date();
let differenceInTime = targetDate.getTime() - currentDate.getTime();
let daysLeft = Math.ceil(differenceInTime / (1000 * 3600 * 24) - 1); // 将时间差转换为天数;不计入当天所以 -1
return daysLeft;
}
// 更新倒计时显示
function updateCountdown() {
let daysLeft = calculateDaysLeft();
let countdownElement = document.getElementById("countdown_days_display");
if (countdownElement) {
countdownElement.innerHTML = countdownMessage.replace('${daysLeft}', daysLeft); // 使用 innerHTML 替代 innerText
} else {
console.warn("找不到 countdown_days_display 元素");
}
}
// 首次插入倒计时显示元素到 #toolbar > #drag 元素旁边
function insertCountdownElement() {
let toolbarDrag = document.querySelector('#toolbar > #drag');
if (toolbarDrag) {
toolbarDrag.insertAdjacentHTML(
"afterend",
`<div id="countdown_days_display" style="font-size: 12px; color: var(--b3-toolbar-color); margin-right: 14px; user-select:none;"></div>`
);
updateCountdown(); // 插入后立即更新显示
} else {
console.error("找不到 #toolbar > #drag 元素");
}
}
// 每隔1分钟检测倒计时元素是否存在
let checkInterval = setInterval(() => {
let countdownElement = document.getElementById("countdown_days_display");
// 如果倒计时元素不存在,则重新插入
if (!countdownElement) {
insertCountdownElement();
console.log("倒计时元素不存在,重新插入");
} else {
console.log("倒计时元素已存在,停止检测");
clearInterval(checkInterval); // 如果找到了元素,停止检测
}
}, 60 * 1000); // 每1分钟检测一次
// 立即插入倒计时显示元素,并在1分钟后开始定时更新
insertCountdownElement(); // 立即插入元素
setInterval(updateCountdown, 60 * 1000); // 每60秒更新一次(1分钟)
}
// 启动倒计时功能
startCountdown(targetDate);
// 顶栏倒计时 JS片段 https://ld246.com/article/17211686880/comment/17274133697#comments
// 设置文本内容和目标日期
const countdownMessage = '距离<span style="color: red; font-weight: bold;">国庆结束</span>剩余 ${daysLeft} 天';
const targetDateString = '2025-1-8';
const targetDate = new Date(targetDateString);
function startCountdown(targetDate) {
// 计算剩余天数的函数
function calculateDaysLeft() {
let currentDate = new Date();
let differenceInTime = targetDate.getTime() - currentDate.getTime();
let daysLeft = Math.ceil(differenceInTime / (1000 * 3600 * 24) - 1); // 将时间差转换为天数;不计入当天所以 -1
return daysLeft;
}
// 更新倒计时显示
function updateCountdown() {
let daysLeft = calculateDaysLeft();
let countdownElement = document.getElementById("countdown_days_display");
if (countdownElement) {
countdownElement.innerHTML = countdownMessage.replace('${daysLeft}', daysLeft); // 使用 innerHTML 替代 innerText
} else {
console.warn("找不到 countdown_days_display 元素");
}
}
// 首次插入倒计时显示元素到 #toolbar > #drag 元素旁边
function insertCountdownElement() {
let toolbarDrag = document.querySelector('#toolbar > #drag');
if (toolbarDrag) {
toolbarDrag.insertAdjacentHTML(
"afterend",
`<div id="countdown_days_display" style="font-size: 12px; color: var(--b3-toolbar-color); margin-right: 14px; user-select:none;"></div>`
);
updateCountdown(); // 插入后立即更新显示
} else {
console.error("找不到 #toolbar > #drag 元素");
}
}
// 每隔1分钟检测倒计时元素是否存在
let checkInterval = setInterval(() => {
let countdownElement = document.getElementById("countdown_days_display");
// 如果倒计时元素不存在,则重新插入
if (!countdownElement) {
insertCountdownElement();
console.log("倒计时元素不存在,重新插入");
} else {
console.log("倒计时元素已存在,停止检测");
clearInterval(checkInterval); // 如果找到了元素,停止检测
}
}, 60 * 1000); // 每1分钟检测一次
// 立即插入倒计时显示元素,并在1分钟后开始定时更新
insertCountdownElement(); // 立即插入元素
setInterval(updateCountdown, 60 * 1000); // 每60秒更新一次(1分钟)
}
// 启动倒计时功能
startCountdown(targetDate);
以下代码片段全是从思源社区白嫖的,参考链接:
在这里❤️感谢❤️以下大佬为我提供的帮助:,,
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- baijiahaobaidu.com 版权所有 湘ICP备2023023988号-9
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务