简易拖拽
// ==UserScript==
// @name 简易拖拽
// @namespace f+drag
// @version 2024.03.26
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEVElEQVR4nO2bTagOURjHf68UYqkoZSmKRErdnVLqlq+SYmNjr1iIlVKUbESxtfCVciUbX90UCtlIlOjKR/mK6+u63Pu+Y3Fm3Ge+zjkzc87MyP3X033fuec8z3N+c+bMmXPm7QRBwH+tIAj+mkH9wEhoa7wnptc5YAx4XbSibG8QBHRkwzudjq5uD5AFtIVzNA8FbyEwBJwBhgv6OAVsFd9HgJm2lVMn2rIH9IAgYc9sgwJzgc8ZPgIUgPkFfGXl8tO2crIHmADMz0k6AF5Yxjym8SHtmG0bcuyXVeUCABYbEp5lEW9Hok4PeAUMoAAmfR6x8HlJk9O4qbItAFPjp1okCvHu+jmnzDvigGx0QpObFoINgH6N8yjJMfE5auQvYI+IdVbUGTU0aESUPS+Obwd+JGL3wli6HHMhmAAcMji2sb4w1rA4tt8A4KAoOxweM/VCk2VCNwEwkbWxi2GscXFslQEAGYnfd5CLEcCUxP8LTywy9NSBD4A7FetnAkiXSo8BTyhP/I1wXbUHVM1FjkeZ7Q2CIHM0XxQGXpiTaBd1F+gHlqMGxFHUre2lRUOLaBFqLrIeddudBuwDVgPXNPX2osYVszTzgAfk031v4dpFD8hT1mwwsh3aIAVngjc0gW4bkvQF4Lcmpy3GIAUBAFzPCWYaMH0ByDv7my1ilAIA6gksGXCFIZYvAE8zcunT1pBBSgIANar+Dm2nRSyfY8CtMI9PmE9EPEgFAEXlE0BpmSZC/50mATSdQNOaBNB0Ak1rEkDTCWRoGhMrP2UsCP92gbeopfhctREAqD2HshbVnwLMQU3ZD+cFahOAaCGl7PN/0qR2kTd7bdFM0Ic+ihx6UG0muALVnbrEp61n3ebsVLOZ2DDpAEdTJSx7wBD67tYj/Szehh4A6vqP8vha5mFIrstHNka8J0R2StRrCwBEHuNFAdwk3sDLGWWSS+mnw+NtAhDdHrtFAciG6TY3PiXKbia+2/NPAtjNRAN+WATJWqlpPQDdXWCt+HzPIsgC4FGVLJuQ64nQEuChY59epQMwKD4vK+BzKXA3caxboH69KjAIbijoOtpT+FIpQTcqfRdI7s1pn6xarNIAQE13JYRN9eTsVJUAQBqC1S5Mi1QZAKhX0SQE4z5ci+QEAMB34hB2+8vZqZwBADWqSwgH/OTsVE4BQBqC3csIzck5AFCvw0gIg/rijcoLAFArRBLCLXc5O5U3AJCGYHpzpAl5BQDqAUhCeFw9Z6fyDgDgKnEIz6s6dKhaAABcIQ5hyIVTB6oNAKifs0gIb/TFa1GtAACOE4dg816hT9UOANQmhITwwXWAAmoEAKj9OAnBZnHVhxoDALCN5iE0CgDSEEZ8BstQLgDb3/5U1UnUA9RA+H0GakdpI2rTdbqnuN9Qy3r5v3GsqQdE6iN/86QOa+wSkFpZU2OzbKypS0DqLnABWBd+r4N8dAmcTv2jxjPfSrXpHaFG9AfMF2OPkJ/rhQAAAABJRU5ErkJggg==
// @description 拖动文字、图片、链接时新窗口打开(拖拽距离超过15px,时间在1.2秒内)
// @author f+
// @match *://*/*
// @grant none
// ==/UserScript==
(function () {
"use strict";
const requiredDistance = 15;
let startY;
let startX;
const upperTimeLimit = 1200;
let startTime;
let link;
let image;
let text;
// 重置状态
function reset() {
startY = void 0;
startX = void 0;
startTime = void 0;
link = void 0;
image = void 0;
text = void 0;
}
// 记录拖拽起始
function setStart(event) {
startY = event.clientY;
startX = event.clientX;
startTime = new Date();
}
// 判断是否是图片链接
function isImageLink(link) {
if (!link || !link.href) {
return false;
}
const imageExtensions = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp"];
const lowerHref = link.href.toLowerCase();
return imageExtensions.some((ext) => lowerHref.endsWith(ext));
}
// 监听拖放开始事件
document.addEventListener("dragstart", function (event) {
// 获取拖动的链接元素
if ("closest" in event.target) {
link = event.target.closest("a");
image = event.target.closest("img");
if (link || image) {
// 记录初始位置
setStart(event);
}
} else {
const selection = window.getSelection();
if (selection) {
// 判断选中的文本anchorNode跟拖动srcElement的关系
if (selection.anchorNode === event.target) {
text = selection.toString().trim();
setStart(event);
}
}
}
});
// 监听拖放结束事件
document.addEventListener("dragend", function (event) {
function isGoodDrag() {
const distanceY = Math.abs(event.clientY - startY);
const distanceX = Math.abs(event.clientX - startX);
const isDragged = distanceY > requiredDistance && distanceX * 4 < distanceY;
const isIntime = new Date() - startTime < upperTimeLimit;
return isDragged && isIntime;
}
if (isGoodDrag()) {
if (link || image || text) {
// 获取链接的 URL
let url;
if (text) {
// 文本拥有最高优先级
if (text.startsWith("http://") || text.startsWith("https://")) {
url = text;
} else {
url = `https://cn.bing.com/search?q=${encodeURIComponent(text)}&FORM=PORE`;
}
} else if (isImageLink(link)) {
// 其次是如果link是图片则为该link
url = link.href;
} else if (image && image.src) {
// 再次是image
url = image.src;
} else if (link && link.href) {
// 最后是其他link
url = link.href;
}
if (url) {
console.log("超级拖拽");
// 阻止默认的拖放行为
if (event.cancelable) event.preventDefault();
event.stopImmediatePropagation();
// 在后台打开链接
window.open(url, "_blank");
}
}
}
// 重置状态
reset();
});
})();