// ==UserScript== // @name 取消超链接 // @name:EN Link2Text // @namespace https://github.com/zxk2099/Link2Text // @version 1.3 // @description 长按元素超链接取消超链接,并提供一个额外的新的按钮以恢复原超链接。 // @description:EN A long press on the element hyperlink cancels the hyperlink, with an additional new button to scroll back. // @author zxk2099 // @icon https://raw.githubusercontent.com/zxk2099/Link2Text/refs/heads/main/icon.png // @supportURL https://github.com/zxk2099/Link2Text/issues // @match *://*/* // @downloadURL https://update.greasyfork.icu/scripts/530665/%E5%8F%96%E6%B6%88%E8%B6%85%E9%93%BE%E6%8E%A5.user.js // @updateURL https://update.greasyfork.icu/scripts/530665/%E5%8F%96%E6%B6%88%E8%B6%85%E9%93%BE%E6%8E%A5.meta.js // ==/UserScript== (function () { // 长按时间(毫秒) const longPressTime = 500; let pressTimer = null; document.addEventListener('mousedown', (e) => { const linkElement = e.target.closest('a'); if (linkElement) { pressTimer = setTimeout(() => { replaceLink(linkElement); }, longPressTime); } }); document.addEventListener('mouseup', () => { if (pressTimer) { clearTimeout(pressTimer); pressTimer = null; } }); document.addEventListener('mouseleave', () => { if (pressTimer) { clearTimeout(pressTimer); pressTimer = null; } }); function isHidden(element) { return element.offsetWidth === 0 && element.offsetHeight === 0; } const replaceLink = (linkElement) => { if(!linkElement.l2t_elementSwitcher){ const container = document.createElement('span'); container.innerHTML = linkElement.innerHTML; [...linkElement.attributes].forEach((a) => { container.setAttribute(a.nodeName,a.nodeValue); }); container.style.cssText = linkElement.style.cssText; container.style.position = 'relative'; container.l2t_elementSwitcher = linkElement; // fix DOMListener in Text To Link 2.8.7 at https://update.greasyfork.org/scripts/342/Text%20To%20link.user.js container.classList.add("textToLink"); const restoreButton = document.createElement('div'); restoreButton.className = 'restore-button'; restoreButton.textContent = '↺'; restoreButton.addEventListener('click', (event) => { const textSpan = event.target.parentElement; event.stopPropagation(); textSpan.l2t_elementSwitcher.style.display = textSpan.style.display; textSpan.style.display = "none"; }); linkElement.l2t_elementSwitcher = container; container.appendChild(restoreButton); linkElement.parentNode.insertBefore(container, linkElement); } linkElement.l2t_elementSwitcher.style.display = linkElement.style.display; linkElement.style.display = "none"; if(isHidden(linkElement.l2t_elementSwitcher)){ linkElement.l2t_elementSwitcher.style.display = "block"; } }; const style = document.createElement('style'); style.textContent = ` .restore-button { position: absolute; left: -8px; top: -12px; width: 16px; height: 16px; background-color: #e31111; color: white; border-radius: 50%; font-size: 12px; text-align: center; line-height: 16px; cursor: pointer; box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5); } `; document.head.appendChild(style); })();