// ==UserScript== // @name 在新标签页中打开链接 // @namespace http://tampermonkey.net/ // @version 1.33 // @description 在页面上显示一个功能开关,改变网页跳转方式改为打开新标签页进行跳转,请自行配置脚本作用域 // @author 晚风知我意 // @match https://yesicon.app/* // @match https://bbs.binmt.cc/* // @grant none // @license GNU AGPLv3 // @downloadURL https://update.greasyfork.icu/scripts/517963/%E5%9C%A8%E6%96%B0%E6%A0%87%E7%AD%BE%E9%A1%B5%E4%B8%AD%E6%89%93%E5%BC%80%E9%93%BE%E6%8E%A5.user.js // @updateURL https://update.greasyfork.icu/scripts/517963/%E5%9C%A8%E6%96%B0%E6%A0%87%E7%AD%BE%E9%A1%B5%E4%B8%AD%E6%89%93%E5%BC%80%E9%93%BE%E6%8E%A5.meta.js // ==/UserScript== (function() { 'use strict'; const domain = location.hostname; const toggleKey = `linkToggleEnabled_${domain}`; const ignoredElementsKey = `ignoredElements_${domain}`; if (localStorage.getItem(toggleKey) === null) { localStorage.setItem(toggleKey, 'true'); } let isEnabled = localStorage.getItem(toggleKey) === 'true'; const ignoredElements = new Set(JSON.parse(localStorage.getItem(ignoredElementsKey)) || []); const button = document.createElement("div"); button.style.position = "fixed"; button.style.right = "10px"; button.style.top = "50%"; button.style.transform = "translateY(-50%)"; button.style.cursor = "pointer"; button.style.zIndex = "9999"; button.style.width = "50px"; button.style.height = "50px"; button.style.borderRadius = "50%"; button.style.display = "flex"; button.style.alignItems = "center"; button.style.justifyContent = "center"; button.innerHTML = ``; document.body.appendChild(button); let longPressTimeout; let isDragging = false; button.addEventListener("mousedown", (e) => { e.preventDefault(); longPressTimeout = setTimeout(() => { isDragging = true; document.addEventListener('mousemove', mouseMoveHandler); }, 500); }); button.addEventListener("click", (e) => { if (!isDragging) { toggleFunctionality(); } }); document.addEventListener("mouseup", () => { clearTimeout(longPressTimeout); isDragging = false; document.removeEventListener('mousemove', mouseMoveHandler); }); function mouseMoveHandler(e) { if (isDragging) { e.preventDefault(); button.style.left = (e.clientX - button.offsetWidth / 2) + 'px'; button.style.top = (e.clientY - button.offsetHeight / 2) + 'px'; } } button.addEventListener('touchstart', (e) => { e.preventDefault(); longPressTimeout = setTimeout(() => { isDragging = true; document.addEventListener('touchmove', touchMoveHandler); }, 500); }); button.addEventListener("touchend", () => { clearTimeout(longPressTimeout); if (!isDragging) { toggleFunctionality(); } isDragging = false; document.removeEventListener('touchmove', touchMoveHandler); }); function touchMoveHandler(e) { if (isDragging) { e.preventDefault(); button.style.left = (e.touches[0].clientX - button.offsetWidth / 2) + 'px'; button.style.top = (e.touches[0].clientY - button.offsetHeight / 2) + 'px'; } } function toggleFunctionality() { isEnabled = !isEnabled; localStorage.setItem(toggleKey, isEnabled); updateButtonState(isEnabled); if (isEnabled) { enableLinkOpening(); } else { disableLinkOpening(); } } function updateButtonState(newState) { const paths = button.querySelectorAll('.icon-path'); paths.forEach(path => { path.setAttribute('fill', newState ? "#FDB122" : "#cccccc"); }); } function enableLinkOpening() { document.addEventListener('click', handleLinkClick, true); const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { const newLinks = node.querySelectorAll('a'); newLinks.forEach(newLink => { newLink.addEventListener('click', handleLinkClick, true); }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); } function disableLinkOpening() { document.removeEventListener('click', handleLinkClick, true); } function isExcludedElement(element) { return element.closest('input, textarea, button, .modal, .dialog, [data-popup], [data-modal], .sidebar, .sidebar *, .dropdown, .dropdown *, [role="button"], [onclick], [data-ignore-link], .fixed-container *'); } function handleLinkClick(event) { const isLinkElement = event.target.closest('a'); if (!isLinkElement) return; if (isExcludedElement(event.target)) { return; } const url = new URL(event.currentTarget.href); const clickedElementInfo = { tag: event.target.tagName, classes: event.target.className, id: event.target.id, href: url.href }; let newTab; try { newTab = window.open(url.href, '_blank'); if (!newTab || newTab.closed || typeof newTab.closed === 'undefined') { throw new Error('Failed to open new tab'); } } catch (e) { ignoredElements.add(JSON.stringify(clickedElementInfo)); localStorage.setItem(ignoredElementsKey, JSON.stringify(Array.from(ignoredElements))); console.log(`Added to ignored elements: ${JSON.stringify(clickedElementInfo)}`); return; } event.preventDefault(); event.stopImmediatePropagation(); } updateButtonState(isEnabled); if (isEnabled) { enableLinkOpening(); } })();