Warning: fopen(/www/sites/update.greasyfork.icu/index/store/temp/45fb28deaa7152fe0e049cf19a874dc7.js): failed to open stream: No space left on device in /www/sites/update.greasyfork.icu/index/scriptControl.php on line 65
// ==UserScript==
// @name 最简洁的划线翻译
// @namespace http://tampermonkey.net/
// @version 2025-4-8
// @description 网页不认识的单词,划线点击按钮,立马得到结果
// @author aipinky
// @include *
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// @run-at document-end
// @license MIT
// @downloadURL https://update.greasyfork.icu/scripts/530103/%E6%9C%80%E7%AE%80%E6%B4%81%E7%9A%84%E5%88%92%E7%BA%BF%E7%BF%BB%E8%AF%91.user.js
// @updateURL https://update.greasyfork.icu/scripts/530103/%E6%9C%80%E7%AE%80%E6%B4%81%E7%9A%84%E5%88%92%E7%BA%BF%E7%BF%BB%E8%AF%91.meta.js
// ==/UserScript==
(function() {
'use strict';
// 插入 CSS 样式
const style = document.createElement('style');
style.textContent = `
.ptext {
position: fixed;
width: 250px;
background-color: hwb(0 97% 2%);
border-radius: 10px;
display: none;
padding-left: 10px;
border: 2px solid #cecbcb;
}
#lp .pfixed,
#lp .pdel {
position: absolute;
width: 15px;
height: 15px;
border-radius: 50%;
border: 0;
}
#lp a {
float: left;
}
#lp {
height:20px;
width:100%;
display: flex;
align-items: center;
margin-top:5px;
}
#lp .pdel {
font-size: 13px;
color: #fff;
margin-right: 10px;
display: flex;
justify-content: center;
align-items: center;
background-color: red;
right:40px
}
#lp .pfixed {
margin-right: 40px;
background-color: greenyellow;
right:-10px;
}
.pdata {
margin-top: 5px;
margin-bottom: 10px;
width: 90%;
padding: 10px;
line-height: 1.5;
font-size: 15px;
overflow: hidden;
background-color: #fff;
}
.pimg {
width: 25px;
height: 25px;
border-radius: 50%;
background-color: red;
background: url(https://i.postimg.cc/3xcgdvXs/lovetranslate-resized.png) no-repeat center/cover;
border: 0;
display: none;
position: fixed;
}
* {
user-select: auto !important;
}
`;
document.head.appendChild(style);
// 动态加载 axios
const script = document.createElement('script');
script.src = 'https://unpkg.com/axios/dist/axios.min.js';
script.onload = function() {
initScript(); // axios 加载完成后初始化脚本
};
document.head.appendChild(script);
function initScript() {
// 创建 HTML 结构
const html = `
`;
document.body.insertAdjacentHTML('beforeend', html);
// 获取元素
const text = document.querySelector('.ptext');
const dataText = document.querySelector('.pdata');
const delBtn = document.querySelector('#lp .pdel');
const fixed = document.querySelector('#lp .pfixed');
const imgBtn = document.querySelector('.pimg');
// 关闭按钮,关闭窗口
delBtn.addEventListener('click', () => {
['click', 'mousedown', 'mouseup', 'mousemove', 'contextmenu'].forEach(eventType => {
text.addEventListener(eventType,preEvent)});
dataText.innerHTML = '';
text.style.display = 'none';
flag = false;
fixed.style.backgroundColor = 'greenyellow';
text.style.cursor = '';
});
// 点击固定按钮,任意拖拽位置
let isDragging = false; // 是否正在拖拽
let offsetX, offsetY; // 鼠标相对于盒子左上角的偏移量
let flag = false;
function preEvent(event) {
event.preventDefault();
event.stopPropagation();
}
fixed.addEventListener('click', () => {
// 定义事件处理函数
// 禁用所有鼠标事件
['click', 'mousedown', 'mouseup', 'mousemove', 'contextmenu'].forEach(eventType => {
text.addEventListener(eventType,preEvent)});
if (flag === false) {
flag = true;
fixed.style.backgroundColor = 'pink';
text.style.cursor = 'move';
} else {
flag = false;
fixed.style.backgroundColor = 'greenyellow';
text.style.cursor = '';
}
});
// 鼠标按下时开始拖拽
text.addEventListener('mousedown', function(event) {
isDragging = true;
// 计算鼠标相对于盒子左上角的偏移量
offsetX = event.clientX - text.offsetLeft;
offsetY = event.clientY - text.offsetTop;
// 改变鼠标样式
if(fixed.style.backgroundColor === 'pink'){
['click', 'mousedown', 'mouseup', 'mousemove', 'contextmenu'].forEach(eventType => {
text.removeEventListener(eventType, preEvent);
});
text.style.cursor = 'grabbing';
}
});
// 鼠标移动时更新盒子位置
document.addEventListener('mousemove', function(event) {
if (isDragging && fixed.style.backgroundColor === 'pink') {
// 计算盒子的新位置
const newLeft = event.clientX - offsetX;
const newTop = event.clientY - offsetY;
// 更新盒子的位置
text.style.left = `${newLeft}px`;
text.style.top = `${newTop}px`;
}
});
let selection;
let mouseX, mouseY;
// 鼠标松开时停止拖拽
document.addEventListener('mouseup', function(event) {
isDragging = false;
// 恢复鼠标样式
if(fixed.style.backgroundColor === 'pink'){
text.style.cursor = 'move';
}else{
text.style.cursor = '';
}
// 检查是否有选中的文本
if (selection && !text.contains(event.target) && text.style.display === 'none') {
const mous1 = event.clientY;
const mous2 = event.clientX;
imgBtn.style.top = `${mous1}px`;
imgBtn.style.left = `${mous2}px`;
imgBtn.style.display = 'block';
} else {
console.log('没有选中文本');
}
});
// 监听 selectionchange 事件
document.addEventListener('selectionchange', function() {
// 获取当前选中的文本
if(!text.contains(event.target)){
selection = window.getSelection().toString();
}
});
// 点击图片按钮,显示文本框
imgBtn.addEventListener('click', () => {
getWhere();
text.style.display = 'block';
getText(selection)
.then(data => {
dataText.innerHTML = data;
})
.catch(error => {
dataText.innerHTML = error;
});
imgBtn.style.display = 'none';
});
function getWhere() {
document.addEventListener('mouseup', function() {
const selection = window.getSelection();
// 检查是否有选中的文本
if (selection.toString().length > 0 && !text.contains(event.target) && text.style.display === 'none') {
// 获取选中的范围
const range = selection.getRangeAt(0);
// 获取选中文本的长度
const textLength = selection.toString().length;
// 计算中间位置的索引
const middleIndex = Math.floor(textLength / 2);
// 创建一个新的 Range,用于定位中间位置
const middleRange = document.createRange();
middleRange.setStart(range.startContainer, range.startOffset + middleIndex);
middleRange.setEnd(range.startContainer, range.startOffset + middleIndex + 1);
// 获取中间位置的边界框
const middleRect = middleRange.getBoundingClientRect();
// 计算中间位置的坐标
const middleX = middleRect.left + middleRect.width / 2;
//const middleY = middleRect.top + middleRect.height / 2;
//const mouseY = event.clientY;
const mouseY = middleRect.top + middleRect.height / 2;
// 获取窗口的高度和宽度
const windowHeight = window.innerHeight;
const windowWidth = window.innerWidth;
// 计算鼠标距离窗口底部的距离
let fromBottom = windowHeight - mouseY;
let formLeft = windowWidth - middleX;
if (middleX > 150 && middleX < windowWidth - 150) {
text.style.left = `${middleX - 150}px`;
if (fromBottom > 100) {
text.style.top = `${mouseY + 18}px`;
} else {
text.style.bottom = `${fromBottom + 18}px`;
}
} else if (middleX >= windowWidth - 150) {
text.style.left = `${windowWidth - 350}px`;
if (fromBottom > 100) {
text.style.top = `${mouseY + 18}px`;
} else {
text.style.bottom = `${fromBottom + 18}px`;
}
} else {
if (fromBottom > 100) {
let newMiddleX = 150 - middleX;
text.style.top = `${mouseY + 18}px`;
text.style.left = `${middleX - 140 + newMiddleX}px`;
} else {
let newMiddleX = 150 - middleX;
text.style.bottom = `${fromBottom + 18}px`;
text.style.left = `${middleX - 140 + newMiddleX}px`;
}
}
}
});
}
//!text.contains(event.target) || getWhere();
getWhere()
// 监听 document 上的 mousedown 事件
document.addEventListener('mousedown', function(event) {
if (!imgBtn.contains(event.target)) {
imgBtn.style.display = 'none';
}
// 检查点击的目标是否是盒子或其子元素
if (!text.contains(event.target)) {
text.style.display = 'none';
flag = false;
fixed.style.backgroundColor = 'greenyellow';
text.style.cursor = '';
}
});
// 请求函数
function getText(param) {
return axios({
url: 'https://v.api.aa1.cn/api/api-fanyi-yd/index.php',
method: 'get',
params: {
msg: param,
type: 3
}
})
.then(re => {
// 使用正则表达式匹配 {} 里面的内容
const matches = re.data.match(/\{([^}]+)\}/g);
if (matches) {
// 提取内容并去掉 {}
const results = matches.map(match => match.replace(/[{}]/g, ''));
// 原始字符串
const str = results[1];
// 修复字符串格式
const fixedStr = `{${str.replace(/)/g, ')')}}`; // 将中文括号替换为英文括号,并添加外层 {}
// 转换为对象
const obj = JSON.parse(fixedStr);
return obj.text;
} else {
return '没有找到 {} 里面的内容';
}
})
.catch(err => {
console.log(err.data);
throw err.data;
});
}
}
document.body.style.userSelect = 'text';
document.body.style.webkitUserSelect = 'text';
document.body.style.mozUserSelect = 'text';
document.body.style.msUserSelect = 'text';
})();