自由选择网页区域并复制为 Markdown 格式
当前为
// ==UserScript==
// @name Universal-Markdown-Copy
// @namespace http://tampermonkey.net/
// @version 1.8.0
// @description 自由选择网页区域并复制为 Markdown 格式
// @author shenfangda
// @match https://*.shenfangda.cn/*
// @grant GM_setClipboard
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 日志函数
const log = (msg) => console.log(`[Markdown-Copy] ${msg}`);
// 检查 DOM 是否就绪
function waitForDOM(callback) {
if (document.readyState === 'complete' || document.readyState === 'interactive') {
callback();
} else {
document.addEventListener('DOMContentLoaded', callback);
setTimeout(callback, 2000); // 2秒后强制执行
}
}
// 主逻辑
function initScript() {
log(`脚本开始初始化于 ${window.location.href}`);
// 样式定义
const STYLES = `
.markdown-copy-btn {
position: fixed;
top: 10px;
right: 10px;
z-index: 9999;
padding: 8px 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s;
}
.markdown-copy-btn:hover {
background-color: #45a049;
transform: scale(1.05);
}
.selection-box {
position: absolute;
border: 2px dashed #4CAF50;
background-color: rgba(76, 175, 80, 0.1);
z-index: 9998;
pointer-events: none;
}
.div-highlight {
border: 2px solid #4CAF50;
background-color: rgba(76, 175, 80, 0.1);
transition: all 0.2s;
}
`;
// 添加样式
if (!document.head) {
log('错误:document.head 未找到');
return;
}
const styleSheet = document.createElement('style');
styleSheet.textContent = STYLES;
document.head.appendChild(styleSheet);
log('样式已加载');
// 创建按钮
if (!document.body) {
log('错误:document.body 未找到');
return;
}
const copyBtn = document.createElement('button');
copyBtn.className = 'markdown-copy-btn';
copyBtn.textContent = '选择区域复制 Markdown';
document.body.appendChild(copyBtn);
log('按钮已添加');
let isSelecting = false;
let isDivMode = false; // 新增:是否为 div 选择模式
let startX, startY;
let selectionBox = null;
// HTML 转 Markdown
function htmlToMarkdown(element) {
let markdown = '';
function processNode(node) {
if (node.nodeType === Node.TEXT_NODE) return node.textContent.trim();
if (node.nodeType !== Node.ELEMENT_NODE) return '';
let result = '';
const tag = node.tagName.toLowerCase();
if (/h[1-6]/.test(tag)) {
const level = parseInt(tag[1]);
result += '#'.repeat(level) + ' ' + node.textContent.trim() + '\n\n';
} else if (tag === 'p') {
result += node.textContent.trim() + '\n\n';
} else if (tag === 'ul' || tag === 'ol') {
const items = Array.from(node.children).filter(child => child.tagName.toLowerCase() === 'li');
items.forEach(item => {
result += (tag === 'ul' ? '- ' : '1. ') + item.textContent.trim() + '\n';
});
result += '\n';
} else if (tag === 'pre' || tag === 'code') {
result += '```\n' + node.textContent.trim() + '\n```\n\n';
} else {
node.childNodes.forEach(child => result += processNode(child));
}
return result;
}
if (element) markdown = processNode(element);
return markdown.trim();
}
// 获取自由选择区域内容
function getSelectedContent(x1, y1, x2, y2) {
const elements = document.elementsFromPoint((x1 + x2) / 2, (y1 + y2) / 2);
for (let el of elements) {
if (el.tagName.toLowerCase() !== 'body' && el.tagName.toLowerCase() !== 'html') {
const content = htmlToMarkdown(el);
log(`自由选择内容:${content.substring(0, 50)}...`);
return content;
}
}
return '';
}
// 按钮点击切换模式
copyBtn.addEventListener('click', () => {
if (!isSelecting) {
isSelecting = true;
isDivMode = !isDivMode; // 切换模式
copyBtn.textContent = isDivMode ? '按 Div 选择 (再次切换)' : '正在选择... (再次切换)';
document.body.style.cursor = isDivMode ? 'pointer' : 'crosshair';
log(`进入${isDivMode ? 'Div 选择' : '自由选择'}模式`);
} else {
resetSelection();
log('取消选择模式');
}
});
// 自由选择模式:鼠标事件
document.addEventListener('mousedown', (e) => {
if (!isSelecting || isDivMode || e.target === copyBtn) return;
startX = e.clientX;
startY = e.clientY;
if (selectionBox) selectionBox.remove();
selectionBox = document.createElement('div');
selectionBox.className = 'selection-box';
document.body.appendChild(selectionBox);
log(`自由选择开始:(${startX}, ${startY})`);
});
document.addEventListener('mousemove', (e) => {
if (!isSelecting || isDivMode || !selectionBox) return;
const currentX = e.clientX;
const currentY = e.clientY;
const left = Math.min(startX, currentX);
const top = Math.min(startY, currentY);
const width = Math.abs(currentX - startX);
const height = Math.abs(currentY - startY);
selectionBox.style.left = `${left}px`;
selectionBox.style.top = `${top}px`;
selectionBox.style.width = `${width}px`;
selectionBox.style.height = `${height}px`;
});
document.addEventListener('mouseup', (e) => {
if (!isSelecting || isDivMode || !selectionBox) return;
const endX = e.clientX;
const endY = e.clientY;
const markdownContent = getSelectedContent(startX, startY, endX, endY);
if (markdownContent) {
try {
GM_setClipboard(markdownContent);
alert('Markdown 已复制到剪贴板!');
log('自由选择复制成功');
} catch (err) {
alert('复制失败,请检查控制台');
log(`复制失败:${err.message}`);
}
} else {
alert('未检测到有效内容,请重新选择');
log('自由选择未找到有效内容');
}
resetSelection();
});
// Div 选择模式:鼠标悬停高亮和点击复制
let highlightedDiv = null;
document.addEventListener('mouseover', (e) => {
if (!isSelecting || !isDivMode) return;
const target = e.target.closest('div');
if (target && target !== highlightedDiv) {
if (highlightedDiv) highlightedDiv.classList.remove('div-highlight');
highlightedDiv = target;
highlightedDiv.classList.add('div-highlight');
log(`高亮 Div: ${target.outerHTML.substring(0, 50)}...`);
}
});
document.addEventListener('click', (e) => {
if (!isSelecting || !isDivMode || e.target === copyBtn) return;
e.preventDefault(); // 防止点击触发其他事件
const target = e.target.closest('div');
if (target) {
const markdownContent = htmlToMarkdown(target);
if (markdownContent) {
try {
GM_setClipboard(markdownContent);
alert('Markdown 已复制到剪贴板!');
log('Div 选择复制成功');
} catch (err) {
alert('复制失败,请检查控制台');
log(`复制失败:${err.message}`);
}
} else {
alert('未检测到有效内容');
log('Div 选择未找到有效内容');
}
resetSelection();
}
});
// 离开页面时清理高亮
document.addEventListener('mouseout', (e) => {
if (!isSelecting || !isDivMode || !highlightedDiv) return;
if (!e.relatedTarget || !highlightedDiv.contains(e.relatedTarget)) {
highlightedDiv.classList.remove('div-highlight');
highlightedDiv = null;
}
});
// 重置选择
function resetSelection() {
isSelecting = false;
copyBtn.textContent = '选择区域复制 Markdown';
document.body.style.cursor = 'default';
if (selectionBox) {
selectionBox.remove();
selectionBox = null;
}
if (highlightedDiv) {
highlightedDiv.classList.remove('div-highlight');
highlightedDiv = null;
}
}
// Esc 键取消
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && isSelecting) {
resetSelection();
log('通过 Esc 键取消选择');
}
});
}
// 等待 DOM 就绪后执行
waitForDOM(() => {
try {
initScript();
} catch (err) {
log(`初始化失败:${err.message}`);
}
});
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址