Warning: fopen(/www/sites/update.greasyfork.icu/index/store/temp/9960d6d2a790f8209b67240da7ae09a1.js): failed to open stream: No space left on device in /www/sites/update.greasyfork.icu/index/scriptControl.php on line 65
// ==UserScript==
// @name 链接选中
// @version 0.4
// @namespace https://greasyfork.org/users/1171320
// @description 在链接上禁用拖拽行为,左键滑动时选择文本而不是打开链接。
// @author yzcjd
// @author2 ChatGPT4 辅助
// @match *://*/*
// @run-at document-start
// @grant none
// @license MIT
// @downloadURL https://update.greasyfork.icu/scripts/532160/%E9%93%BE%E6%8E%A5%E9%80%89%E4%B8%AD.user.js
// @updateURL https://update.greasyfork.icu/scripts/532160/%E9%93%BE%E6%8E%A5%E9%80%89%E4%B8%AD.meta.js
// ==/UserScript==
(function () {
'use strict';
let startX = 0;
let startY = 0;
let isDraggingLink = false;
let linkBeingDragged = null;
const DRAG_THRESHOLD = 5; // 像素
// 设置 user-select 样式
const style = document.createElement('style');
style.textContent = `
a {
user-select: text !important;
-webkit-user-select: text !important;
}
`;
document.head.appendChild(style);
// 禁用所有链接的拖拽属性
const disableDrag = (el) => {
if (el.tagName === 'A') {
el.setAttribute('draggable', 'false');
}
};
const observer = new MutationObserver(() => {
document.querySelectorAll('a').forEach(disableDrag);
});
observer.observe(document.body, { childList: true, subtree: true });
document.querySelectorAll('a').forEach(disableDrag);
// 鼠标按下
document.addEventListener('mousedown', (e) => {
if (e.button !== 0) return; // 仅处理左键
const link = findLink(e.target);
if (!link) return;
startX = e.clientX;
startY = e.clientY;
isDraggingLink = true;
linkBeingDragged = link;
});
// 鼠标抬起时,根据是否滑动来决定是否拦截 click
document.addEventListener('mouseup', (e) => {
if (!isDraggingLink || !linkBeingDragged) return;
const dx = Math.abs(e.clientX - startX);
const dy = Math.abs(e.clientY - startY);
if (dx > DRAG_THRESHOLD || dy > DRAG_THRESHOLD) {
// 明确是滑动选择了文字,而不是点击
linkBeingDragged.setAttribute('data-ignore-click', 'true');
}
// 重置状态
isDraggingLink = false;
linkBeingDragged = null;
});
// 捕获阶段处理点击,阻止滑动后引起的“伪点击”
document.addEventListener('click', (e) => {
const link = findLink(e.target);
if (link && link.getAttribute('data-ignore-click') === 'true') {
e.stopImmediatePropagation();
e.preventDefault();
link.removeAttribute('data-ignore-click');
}
}, true); // ← 必须使用捕获阶段!!!
// 工具函数:查找最接近的链接
function findLink(el) {
while (el && el !== document.body) {
if (el.tagName === 'A') return el;
el = el.parentElement;
}
return null;
}
})();