// ==UserScript== // @name 乐享增强 // @namespace http://tampermonkey.net/ // @version 0.6 // @description 编辑界面悬浮大纲/阅读界面返回顶部按钮嘎~ // @author 阿裕Addyu // @match https://lexiangla.com/* // @grant none // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/512223/%E4%B9%90%E4%BA%AB%E5%A2%9E%E5%BC%BA.user.js // @updateURL https://update.greasyfork.icu/scripts/512223/%E4%B9%90%E4%BA%AB%E5%A2%9E%E5%BC%BA.meta.js // ==/UserScript== (function () { "use strict"; const isEditPage = window.location.href.includes("/edit"); // 编辑页面功能:悬浮大纲 if (isEditPage) { const createTocContainer = () => { const tocContainer = document.createElement("div"); tocContainer.id = "tocContainer"; tocContainer.style.cssText = ` position: fixed; top: 100px; right: 8px; width: 200px; max-height: 500px; overflow-y: auto; background: white; border: 1px solid #ccc; padding: 10px; z-index: 9999; box-shadow: 0 0 10px rgba(0,0,0,0.1); cursor: grab; `; document.body.appendChild(tocContainer); return tocContainer; }; const populateToc = (tocContainer, iframeDocument) => { const headings = iframeDocument.querySelectorAll("h1, h2, h3"); if (headings.length === 0) { console.log("未找到标题,稍候重试嘎..."); setTimeout(findIframeAndInjectToc, 3000); return; } tocContainer.innerHTML = `

文档大纲

`; const tocList = document.createElement("ul"); tocList.style.cssText = "list-style: none; padding: 0;"; tocContainer.appendChild(tocList); headings.forEach((heading, index) => { const tocItem = document.createElement("li"); const headingTag = heading.tagName.toLowerCase(); tocItem.innerHTML = ` ${heading.innerText} `; tocItem.style.margin = "5px 0"; tocList.appendChild(tocItem); tocItem.addEventListener("click", (e) => { e.preventDefault(); heading.scrollIntoView({ behavior: "smooth" }); }); }); }; const enableDraggable = (element) => { let isDragging = false; let offsetX = 0; let offsetY = 0; element.addEventListener("mousedown", (e) => { isDragging = true; element.style.cursor = "grabbing"; offsetX = e.clientX - element.getBoundingClientRect().left; offsetY = e.clientY - element.getBoundingClientRect().top; }); document.addEventListener("mousemove", (e) => { if (isDragging) { const newLeft = e.clientX - offsetX; const newTop = e.clientY - offsetY; element.style.left = `${newLeft}px`; element.style.top = `${newTop}px`; element.style.right = "auto"; } }); document.addEventListener("mouseup", () => { if (isDragging) { isDragging = false; element.style.cursor = "grab"; } }); element.ondragstart = () => false; }; const findIframeAndInjectToc = () => { const iframe = document.querySelector(".tox-edit-area__iframe"); if (!iframe) { console.log("iframe未找到,重试中嘎..."); setTimeout(findIframeAndInjectToc, 1000); return; } console.log("iframe已找到,创建悬浮窗口嘎~"); const iframeDocument = iframe.contentDocument || iframe.contentWindow.document; const tocContainer = createTocContainer(); populateToc(tocContainer, iframeDocument); enableDraggable(tocContainer); }; setTimeout(findIframeAndInjectToc, 3000); } // 阅读页面功能:返回顶部按钮 if (!isEditPage) { const createBackToTopButton = () => { const button = document.createElement("div"); button.innerHTML = "⬆️"; button.style.cssText = ` position: fixed; right: 20px; bottom: 20px; width: 50px; height: 50px; background-color: transparent; color: #007bff; font-size: 24px; text-align: center; line-height: 50px; border-radius: 50%; cursor: pointer; z-index: 1000; user-select: none; box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.2); `; document.body.appendChild(button); return button; }; const createTooltip = () => { const tooltip = document.createElement("div"); tooltip.innerHTML = "返回顶部(双击删除)"; tooltip.style.cssText = ` position: fixed; padding: 5px 10px; background-color: rgba(0, 0, 0, 0.7); color: #fff; border-radius: 5px; font-size: 12px; visibility: hidden; white-space: nowrap; z-index: 9999; `; document.body.appendChild(tooltip); return tooltip; }; const button = createBackToTopButton(); const tooltip = createTooltip(); let clickTimeout; let isDoubleClick = false; button.addEventListener("click", () => { if (isDoubleClick) return; clickTimeout = setTimeout(() => { if (!isDoubleClick) window.scrollTo({ top: 0, behavior: "smooth" }); }, 150); }); button.addEventListener("dblclick", () => { clearTimeout(clickTimeout); isDoubleClick = true; button.remove(); tooltip.remove(); setTimeout(() => (isDoubleClick = false), 150); }); let isDragging = false; let offsetX, offsetY; button.addEventListener("mousedown", (e) => { isDragging = true; offsetX = e.clientX - button.getBoundingClientRect().left; offsetY = e.clientY - button.getBoundingClientRect().top; button.style.transition = "none"; }); document.addEventListener("mousemove", (e) => { if (isDragging) { button.style.left = e.clientX - offsetX + "px"; button.style.top = e.clientY - offsetY + "px"; button.style.right = "auto"; button.style.bottom = "auto"; } }); document.addEventListener("mouseup", () => { isDragging = false; button.style.transition = ""; }); button.addEventListener("mouseenter", (e) => { tooltip.style.visibility = "visible"; tooltip.style.left = e.clientX - tooltip.offsetWidth - 10 + "px"; tooltip.style.top = e.clientY - tooltip.offsetHeight - 10 + "px"; }); button.addEventListener("mouseleave", () => { tooltip.style.visibility = "hidden"; }); button.addEventListener("mousemove", (e) => { tooltip.style.left = e.clientX - tooltip.offsetWidth - 10 + "px"; tooltip.style.top = e.clientY - tooltip.offsetHeight - 10 + "px"; }); } })();