🛡? 禁用瀏覽器復制功能完整指南
網頁中禁用用戶的復制功能,包括 CSS 方法、JavaScript 方法、綜合解決方案以及實際應用場景。適用于需要保護內容版權、防止惡意爬取或提升用戶體驗的場景。
📋 目錄
- 🚀 快速開始
- 🎨 CSS 方法
- ? JavaScript 方法
- 🔧 綜合解決方案
- 🎯 高級技巧
- 💡 實際應用示例
- ? 常見問題解答
🚀 快速開始
如果您想快速實現基本的復制保護,可以直接使用以下代碼:
<!DOCTYPE html>
<html><head><style>/* 基礎保護樣式 */.protected {-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;-webkit-touch-callout: none;}</style></head><body class="protected"><script>// 基礎保護腳本document.addEventListener("contextmenu", (e) => e.preventDefault());document.addEventListener("keydown", (e) => {if (e.ctrlKey && (e.keyCode === 67 || e.keyCode === 65)) {e.preventDefault();}});</script><h1>受保護的內容</h1><p>這里的內容無法被輕易復制</p></body>
</html>
🎨 CSS 方法
CSS 方法是最基礎且高效的保護方式,通過樣式屬性來禁用用戶的選擇和交互行為。
1. 禁用文本選擇
基礎語法
/* 禁用所有文本選擇 - 基礎版本 */
.no-select {-webkit-user-select: none; /* Safari */-moz-user-select: none; /* Firefox */-ms-user-select: none; /* Internet Explorer/Edge */user-select: none; /* 標準語法 */
}/* 應用到整個頁面 */
body {-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;
}
高級配置
/* 完整的文本選擇保護 */
.protected-content {-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;/* 移動端優化 */-webkit-touch-callout: none; /* 禁用iOS Safari的長按菜單 */-webkit-tap-highlight-color: transparent; /* 禁用點擊高亮 */-webkit-appearance: none; /* 移除默認樣式 *//* 禁用文本選擇手柄 */-webkit-text-size-adjust: none;
}/* 選擇性允許文本選擇 */
.selectable {-webkit-user-select: text;-moz-user-select: text;-ms-user-select: text;user-select: text;
}/* 只允許選擇文本內容,不允許選擇元素 */
.text-only {-webkit-user-select: text;-moz-user-select: text;-ms-user-select: text;user-select: text;
}/* 允許全部選擇 */
.select-all {-webkit-user-select: all;-moz-user-select: all;-ms-user-select: all;user-select: all;
}
實際使用示例
<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8" /><style>/* 保護主要內容 */.article-content {-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;padding: 20px;border: 1px solid #ddd;background: #f9f9f9;}/* 允許輸入框正常使用 */.user-input {-webkit-user-select: text;-moz-user-select: text;-ms-user-select: text;user-select: text;padding: 10px;border: 1px solid #ccc;width: 100%;margin: 10px 0;}/* 代碼塊可以選擇 */.code-block {-webkit-user-select: all;-moz-user-select: all;-ms-user-select: all;user-select: all;background: #f4f4f4;padding: 10px;font-family: monospace;}</style></head><body><div class="article-content"><h2>受保護的文章標題</h2><p>這段內容無法被選擇和復制</p><img src="protected-image.jpg" alt="受保護的圖片" /></div><inputtype="text"class="user-input"placeholder="這里可以正常輸入和選擇文本"/><div class="code-block">console.log('這段代碼可以被選擇復制');</div></body>
</html>
2. 禁用拖拽功能
/* 禁用圖片和媒體元素的拖拽 */
img,
video,
audio,
canvas,
svg {-webkit-user-drag: none;-khtml-user-drag: none;-moz-user-drag: none;-o-user-drag: none;user-drag: none;pointer-events: none; /* 完全禁用鼠標事件 */
}/* 禁用所有元素的拖拽 */
* {-webkit-user-drag: none;-khtml-user-drag: none;-moz-user-drag: none;-o-user-drag: none;user-drag: none;
}/* 恢復必要的交互元素 */
.interactive,
button,
input,
textarea,
select,
a {pointer-events: auto;-webkit-user-drag: auto;-khtml-user-drag: auto;-moz-user-drag: auto;-o-user-drag: auto;user-drag: auto;
}/* 特殊處理:可拖拽的元素 */
.draggable {-webkit-user-drag: element;-khtml-user-drag: element;-moz-user-drag: element;-o-user-drag: element;user-drag: element;
}
3. 移動端特殊優化
/* 移動端復制保護 */
.mobile-protected {-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;/* iOS Safari 特殊處理 */-webkit-touch-callout: none; /* 禁用長按菜單 */-webkit-tap-highlight-color: transparent; /* 禁用點擊高亮 *//* Android 特殊處理 */-webkit-text-size-adjust: none; /* 禁用文本大小調整 *//* 禁用雙擊縮放 */touch-action: manipulation;/* 禁用選擇手柄 */-webkit-appearance: none;
}/* 禁用文本選擇高亮 */
.mobile-protected::selection {background: transparent;
}.mobile-protected::-moz-selection {background: transparent;
}/* 禁用iOS Safari的選擇工具欄 */
.mobile-protected::-webkit-selection {background: transparent;
}
? JavaScript 方法
JavaScript 方法提供了更靈活和強大的保護功能,可以動態控制用戶行為并提供反饋。
1. 禁用右鍵菜單
基礎實現
// 方法1: 全局禁用右鍵菜單
document.addEventListener("contextmenu", function (e) {e.preventDefault();return false;
});// 方法2: 針對特定元素
document.getElementById("protected-content").addEventListener("contextmenu", function (e) {e.preventDefault();alert("右鍵功能已被禁用");return false;});// 方法3: 使用事件委托
document.addEventListener("contextmenu", function (e) {if (e.target.classList.contains("protected")) {e.preventDefault();console.log("嘗試右鍵點擊受保護內容");return false;}
});
高級實現
// 智能右鍵菜單禁用
class ContextMenuProtection {constructor(options = {}) {this.options = {showWarning: true,warningMessage: "此內容受到保護,無法使用右鍵菜單",allowedElements: ["input", "textarea"],...options,};this.init();}init() {document.addEventListener("contextmenu", (e) => this.handleContextMenu(e));}handleContextMenu(e) {const tagName = e.target.tagName.toLowerCase();// 允許特定元素使用右鍵菜單if (this.options.allowedElements.includes(tagName)) {return true;}// 檢查是否有特殊標記if (e.target.dataset.allowContextMenu === "true") {return true;}e.preventDefault();if (this.options.showWarning) {this.showWarning(this.options.warningMessage);}return false;}showWarning(message) {// 創建自定義提示const warning = document.createElement("div");warning.textContent = message;warning.style.cssText = `position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background: #ff4444;color: white;padding: 10px 20px;border-radius: 5px;z-index: 10000;font-size: 14px;`;document.body.appendChild(warning);setTimeout(() => {document.body.removeChild(warning);}, 2000);}
}// 使用示例
const contextProtection = new ContextMenuProtection({showWarning: true,warningMessage: "內容受保護,禁止右鍵操作",allowedElements: ["input", "textarea", "select"],
});
2. 禁用鍵盤快捷鍵
基礎實現
// 禁用常見的復制快捷鍵
document.addEventListener("keydown", function (e) {// 禁用 Ctrl+C (復制)if (e.ctrlKey && e.keyCode === 67) {e.preventDefault();return false;}// 禁用 Ctrl+A (全選)if (e.ctrlKey && e.keyCode === 65) {e.preventDefault();return false;}// 禁用 Ctrl+V (粘貼)if (e.ctrlKey && e.keyCode === 86) {e.preventDefault();return false;}// 禁用 Ctrl+X (剪切)if (e.ctrlKey && e.keyCode === 88) {e.preventDefault();return false;}// 禁用 Ctrl+S (保存)if (e.ctrlKey && e.keyCode === 83) {e.preventDefault();return false;}// 禁用 F12 (開發者工具)if (e.keyCode === 123) {e.preventDefault();return false;}// 禁用 Ctrl+Shift+I (開發者工具)if (e.ctrlKey && e.shiftKey && e.keyCode === 73) {e.preventDefault();return false;}// 禁用 Ctrl+U (查看源代碼)if (e.ctrlKey && e.keyCode === 85) {e.preventDefault();return false;}
});
高級鍵盤保護
class KeyboardProtection {constructor(options = {}) {this.options = {disableCopy: true,disablePaste: true,disableSelectAll: true,disableSave: true,disableDevTools: true,disablePrint: true,allowedInputs: ["input", "textarea"],showWarnings: true,...options,};this.forbiddenKeys = this.buildForbiddenKeys();this.init();}buildForbiddenKeys() {const keys = [];if (this.options.disableCopy) {keys.push({ ctrl: true, key: 67, name: "Ctrl+C (復制)" });}if (this.options.disablePaste) {keys.push({ ctrl: true, key: 86, name: "Ctrl+V (粘貼)" });}if (this.options.disableSelectAll) {keys.push({ ctrl: true, key: 65, name: "Ctrl+A (全選)" });}if (this.options.disableSave) {keys.push({ ctrl: true, key: 83, name: "Ctrl+S (保存)" });}if (this.options.disableDevTools) {keys.push({ key: 123, name: "F12 (開發者工具)" },{ ctrl: true, shift: true, key: 73, name: "Ctrl+Shift+I (開發者工具)" },{ ctrl: true, shift: true, key: 74, name: "Ctrl+Shift+J (控制臺)" },{ ctrl: true, key: 85, name: "Ctrl+U (查看源代碼)" });}if (this.options.disablePrint) {keys.push({ ctrl: true, key: 80, name: "Ctrl+P (打印)" });}return keys;}init() {document.addEventListener("keydown", (e) => this.handleKeyDown(e));}handleKeyDown(e) {const target = e.target;const tagName = target.tagName.toLowerCase();// 允許在輸入框中使用某些快捷鍵if (this.options.allowedInputs.includes(tagName)) {// 在輸入框中只禁用開發者工具相關快捷鍵if (this.options.disableDevTools) {const devToolsKeys = this.forbiddenKeys.filter((key) =>key.name.includes("開發者工具") ||key.name.includes("控制臺") ||key.name.includes("查看源代碼"));for (let forbidden of devToolsKeys) {if (this.matchesKeyCombo(e, forbidden)) {e.preventDefault();this.showWarning(`${forbidden.name} 已被禁用`);return false;}}}return true;}// 檢查所有禁用的快捷鍵for (let forbidden of this.forbiddenKeys) {if (this.matchesKeyCombo(e, forbidden)) {e.preventDefault();if (this.options.showWarnings) {this.showWarning(`${forbidden.name} 已被禁用`);}return false;}}}matchesKeyCombo(event, combo) {return ((!combo.ctrl || event.ctrlKey) &&(!combo.shift || event.shiftKey) &&(!combo.alt || event.altKey) &&event.keyCode === combo.key);}showWarning(message) {if (this.options.showWarnings) {console.warn(message);// 可以在這里添加自定義的警告顯示邏輯}}
}// 使用示例
const keyboardProtection = new KeyboardProtection({disableCopy: true,disablePaste: true,disableSelectAll: true,disableSave: true,disableDevTools: true,disablePrint: true,allowedInputs: ["input", "textarea"],showWarnings: true,
});
3. 禁用文本選擇
// 方法1: 禁用選擇事件
document.addEventListener("selectstart", function (e) {e.preventDefault();return false;
});// 方法2: 清除已選擇的文本
document.addEventListener("mouseup", function () {if (window.getSelection) {window.getSelection().removeAllRanges();} else if (document.selection) {document.selection.empty();}
});// 方法3: 禁用拖拽選擇
document.addEventListener("dragstart", function (e) {e.preventDefault();return false;
});// 方法4: 高級文本選擇保護
class TextSelectionProtection {constructor(options = {}) {this.options = {clearSelectionInterval: 100, // 清除選擇的間隔時間(ms)allowedElements: ["input", "textarea"],...options,};this.init();}init() {// 禁用選擇開始事件document.addEventListener("selectstart", (e) => this.handleSelectStart(e));// 禁用拖拽事件document.addEventListener("dragstart", (e) => this.handleDragStart(e));// 定期清除選擇if (this.options.clearSelectionInterval > 0) {setInterval(() => this.clearSelection(),this.options.clearSelectionInterval);}// 監聽鼠標事件document.addEventListener("mouseup", () => this.clearSelection());document.addEventListener("keyup", () => this.clearSelection());}handleSelectStart(e) {const tagName = e.target.tagName.toLowerCase();if (this.options.allowedElements.includes(tagName)) {return true;}e.preventDefault();return false;}handleDragStart(e) {const tagName = e.target.tagName.toLowerCase();if (this.options.allowedElements.includes(tagName)) {return true;}e.preventDefault();return false;}clearSelection() {try {if (window.getSelection) {const selection = window.getSelection();if (selection.rangeCount > 0) {// 檢查選擇是否在允許的元素中const range = selection.getRangeAt(0);const container = range.commonAncestorContainer;const element =container.nodeType === Node.TEXT_NODE? container.parentElement: container;const tagName = element.tagName ? element.tagName.toLowerCase() : "";if (!this.options.allowedElements.includes(tagName)) {selection.removeAllRanges();}}} else if (document.selection) {document.selection.empty();}} catch (e) {// 忽略錯誤}}
}// 使用示例
const textProtection = new TextSelectionProtection({clearSelectionInterval: 50,allowedElements: ["input", "textarea", "select"],
});
4. 監控開發者工具
// 基礎開發者工具檢測
let devtools = {open: false,orientation: null,
};const threshold = 160;function detectDevTools() {if (window.outerHeight - window.innerHeight > threshold ||window.outerWidth - window.innerWidth > threshold) {if (!devtools.open) {devtools.open = true;console.log("開發者工具已打開");// 可以在這里添加警告或重定向// window.location.href = 'about:blank';}} else {devtools.open = false;}
}setInterval(detectDevTools, 500);// 高級開發者工具檢測
class DevToolsDetection {constructor(options = {}) {this.options = {checkInterval: 1000,onDetected: () => console.warn("檢測到開發者工具"),onClosed: () => console.log("開發者工具已關閉"),threshold: 160,redirectUrl: null,showWarning: true,...options,};this.isOpen = false;this.init();}init() {setInterval(() => this.check(), this.options.checkInterval);// 檢測控制臺輸出this.detectConsoleOutput();// 檢測調試器this.detectDebugger();}check() {const widthThreshold =window.outerWidth - window.innerWidth > this.options.threshold;const heightThreshold =window.outerHeight - window.innerHeight > this.options.threshold;if (widthThreshold || heightThreshold) {if (!this.isOpen) {this.isOpen = true;this.handleDetected();}} else {if (this.isOpen) {this.isOpen = false;this.handleClosed();}}}detectConsoleOutput() {// 重寫console方法來檢測控制臺使用const originalLog = console.log;console.log = (...args) => {this.handleDetected();return originalLog.apply(console, args);};}detectDebugger() {// 定期檢查調試器setInterval(() => {const start = performance.now();debugger;const end = performance.now();if (end - start > 100) {this.handleDetected();}}, 3000);}handleDetected() {this.options.onDetected();if (this.options.showWarning) {alert("檢測到開發者工具,頁面功能可能受限");}if (this.options.redirectUrl) {window.location.href = this.options.redirectUrl;}}handleClosed() {this.options.onClosed();}
}// 使用示例
const devToolsDetection = new DevToolsDetection({checkInterval: 1000,onDetected: () => {console.warn("開發者工具被檢測到");document.body.style.display = "none";},onClosed: () => {document.body.style.display = "block";},threshold: 160,showWarning: true,
});
🔧 綜合解決方案
將 CSS 和 JavaScript 方法結合起來,創建一個完整的復制保護系統。
完整的保護類
class CopyProtection {constructor(options = {}) {this.options = {// 基礎保護選項disableRightClick: true,disableSelection: true,disableKeyboardShortcuts: true,disableDeveloperTools: true,disableDragDrop: true,disablePrint: true,// 用戶體驗選項showWarnings: true,allowedElements: ["input", "textarea", "select"],warningDuration: 2000,// 高級選項clearSelectionInterval: 100,devToolsCheckInterval: 1000,redirectOnDevTools: false,redirectUrl: "about:blank",// 自定義消息messages: {rightClick: "右鍵功能已被禁用",keyboard: "該快捷鍵已被禁用",devTools: "檢測到開發者工具",selection: "文本選擇已被禁用",},...options,};this.isDevToolsOpen = false;this.init();}init() {// 添加CSS樣式this.addProtectionStyles();// 初始化各種保護功能if (this.options.disableRightClick) {this.initRightClickProtection();}if (this.options.disableSelection) {this.initSelectionProtection();}if (this.options.disableKeyboardShortcuts) {this.initKeyboardProtection();}if (this.options.disableDeveloperTools) {this.initDevToolsDetection();}if (this.options.disableDragDrop) {this.initDragDropProtection();}if (this.options.disablePrint) {this.initPrintProtection();}console.log("🛡? 復制保護系統已啟動");}addProtectionStyles() {const style = document.createElement("style");style.id = "copy-protection-styles";style.textContent = `/* 基礎保護樣式 */.copy-protected {-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;-webkit-touch-callout: none;-webkit-tap-highlight-color: transparent;-webkit-user-drag: none;-khtml-user-drag: none;-moz-user-drag: none;-o-user-drag: none;user-drag: none;}/* 媒體元素保護 */.copy-protected img,.copy-protected video,.copy-protected audio,.copy-protected canvas {pointer-events: none;-webkit-user-drag: none;-khtml-user-drag: none;-moz-user-drag: none;-o-user-drag: none;user-drag: none;}/* 選擇高亮禁用 */.copy-protected::selection {background: transparent;}.copy-protected::-moz-selection {background: transparent;}/* 警告提示樣式 */.copy-protection-warning {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background: linear-gradient(135deg, #ff6b6b, #ee5a24);color: white;padding: 15px 25px;border-radius: 8px;box-shadow: 0 4px 20px rgba(0,0,0,0.3);z-index: 999999;font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;font-size: 14px;font-weight: 500;text-align: center;animation: copyProtectionFadeIn 0.3s ease-out;}@keyframes copyProtectionFadeIn {from {opacity: 0;transform: translate(-50%, -50%) scale(0.8);}to {opacity: 1;transform: translate(-50%, -50%) scale(1);}}/* 允許的元素恢復正常功能 */.copy-protected input,.copy-protected textarea,.copy-protected select {-webkit-user-select: text;-moz-user-select: text;-ms-user-select: text;user-select: text;pointer-events: auto;}`;document.head.appendChild(style);// 應用保護樣式到bodydocument.body.classList.add("copy-protected");}initRightClickProtection() {document.addEventListener("contextmenu", (e) => {const tagName = e.target.tagName.toLowerCase();if (this.options.allowedElements.includes(tagName)) {return true;}if (e.target.dataset.allowContextMenu === "true") {return true;}e.preventDefault();if (this.options.showWarnings) {this.showWarning(this.options.messages.rightClick);}return false;});}initSelectionProtection() {// 禁用選擇開始document.addEventListener("selectstart", (e) => {const tagName = e.target.tagName.toLowerCase();if (this.options.allowedElements.includes(tagName)) {return true;}e.preventDefault();return false;});// 定期清除選擇if (this.options.clearSelectionInterval > 0) {setInterval(() => {this.clearSelection();}, this.options.clearSelectionInterval);}// 監聽鼠標和鍵盤事件document.addEventListener("mouseup", () => this.clearSelection());document.addEventListener("keyup", () => this.clearSelection());}clearSelection() {try {if (window.getSelection) {const selection = window.getSelection();if (selection.rangeCount > 0) {const range = selection.getRangeAt(0);const container = range.commonAncestorContainer;const element =container.nodeType === Node.TEXT_NODE? container.parentElement: container;const tagName = element.tagName ? element.tagName.toLowerCase() : "";if (!this.options.allowedElements.includes(tagName)) {selection.removeAllRanges();}}} else if (document.selection) {document.selection.empty();}} catch (e) {// 忽略錯誤}}initKeyboardProtection() {const forbiddenKeys = [{ ctrl: true, key: 67, name: "Ctrl+C (復制)" },{ ctrl: true, key: 86, name: "Ctrl+V (粘貼)" },{ ctrl: true, key: 65, name: "Ctrl+A (全選)" },{ ctrl: true, key: 88, name: "Ctrl+X (剪切)" },{ ctrl: true, key: 83, name: "Ctrl+S (保存)" },{ ctrl: true, key: 80, name: "Ctrl+P (打印)" },{ key: 123, name: "F12 (開發者工具)" },{ ctrl: true, shift: true, key: 73, name: "Ctrl+Shift+I (開發者工具)" },{ ctrl: true, shift: true, key: 74, name: "Ctrl+Shift+J (控制臺)" },{ ctrl: true, key: 85, name: "Ctrl+U (查看源代碼)" },];document.addEventListener("keydown", (e) => {const target = e.target;const tagName = target.tagName.toLowerCase();// 允許在輸入框中使用某些快捷鍵if (this.options.allowedElements.includes(tagName)) {// 在輸入框中只禁用開發者工具相關快捷鍵const devToolsKeys = forbiddenKeys.filter((key) =>key.name.includes("開發者工具") ||key.name.includes("控制臺") ||key.name.includes("查看源代碼"));for (let forbidden of devToolsKeys) {if (this.matchesKeyCombo(e, forbidden)) {e.preventDefault();if (this.options.showWarnings) {this.showWarning(this.options.messages.keyboard);}return false;}}return true;}// 檢查所有禁用的快捷鍵for (let forbidden of forbiddenKeys) {if (this.matchesKeyCombo(e, forbidden)) {e.preventDefault();if (this.options.showWarnings) {this.showWarning(this.options.messages.keyboard);}return false;}}});}matchesKeyCombo(event, combo) {return ((!combo.ctrl || event.ctrlKey) &&(!combo.shift || event.shiftKey) &&(!combo.alt || event.altKey) &&event.keyCode === combo.key);}initDragDropProtection() {document.addEventListener("dragstart", (e) => {const tagName = e.target.tagName.toLowerCase();if (this.options.allowedElements.includes(tagName)) {return true;}e.preventDefault();return false;});}initPrintProtection() {// 禁用打印快捷鍵已在鍵盤保護中處理// 這里可以添加額外的打印保護邏輯window.addEventListener("beforeprint", (e) => {if (this.options.showWarnings) {this.showWarning("打印功能已被禁用");}e.preventDefault();return false;});}initDevToolsDetection() {setInterval(() => {const widthThreshold = window.outerWidth - window.innerWidth > 160;const heightThreshold = window.outerHeight - window.innerHeight > 160;if (widthThreshold || heightThreshold) {if (!this.isDevToolsOpen) {this.isDevToolsOpen = true;this.handleDevToolsDetected();}} else {this.isDevToolsOpen = false;}}, this.options.devToolsCheckInterval);}handleDevToolsDetected() {if (this.options.showWarnings) {this.showWarning(this.options.messages.devTools);}if (this.options.redirectOnDevTools) {setTimeout(() => {window.location.href = this.options.redirectUrl;}, 1000);}}showWarning(message) {// 移除已存在的警告const existingWarning = document.querySelector(".copy-protection-warning");if (existingWarning) {existingWarning.remove();}// 創建新的警告const warning = document.createElement("div");warning.className = "copy-protection-warning";warning.textContent = message;document.body.appendChild(warning);// 自動移除警告setTimeout(() => {if (warning.parentNode) {warning.parentNode.removeChild(warning);}}, this.options.warningDuration);}// 公共方法:啟用保護enable() {document.body.classList.add("copy-protected");console.log("🛡? 復制保護已啟用");}// 公共方法:禁用保護disable() {document.body.classList.remove("copy-protected");console.log("🔓 復制保護已禁用");}// 公共方法:銷毀保護destroy() {// 移除樣式const style = document.getElementById("copy-protection-styles");if (style) {style.remove();}// 移除類名document.body.classList.remove("copy-protected");// 移除警告const warnings = document.querySelectorAll(".copy-protection-warning");warnings.forEach((warning) => warning.remove());console.log("🗑? 復制保護已銷毀");}
}// 使用示例
const protection = new CopyProtection({// 基礎保護選項disableRightClick: true,disableSelection: true,disableKeyboardShortcuts: true,disableDeveloperTools: true,disableDragDrop: true,disablePrint: false,// 用戶體驗選項showWarnings: true,allowedElements: ["input", "textarea", "select"],warningDuration: 3000,// 高級選項clearSelectionInterval: 50,devToolsCheckInterval: 1000,redirectOnDevTools: false,// 自定義消息messages: {rightClick: "🚫 右鍵功能已被禁用",keyboard: "?? 該快捷鍵已被禁用",devTools: "🔧 檢測到開發者工具",selection: "📝 文本選擇已被禁用",},
});
🎯 高級技巧
1. 動態內容保護
// 動態添加保護到新內容
function protectNewContent() {const observer = new MutationObserver((mutations) => {mutations.forEach((mutation) => {mutation.addedNodes.forEach((node) => {if (node.nodeType === Node.ELEMENT_NODE) {node.classList.add("copy-protected");}});});});observer.observe(document.body, {childList: true,subtree: true,});
}
2. 圖片水印保護
// 為圖片添加水印
function addWatermarkToImages() {document.querySelectorAll("img").forEach((img) => {img.addEventListener("load", function () {const canvas = document.createElement("canvas");const ctx = canvas.getContext("2d");canvas.width = this.naturalWidth;canvas.height = this.naturalHeight;// 繪制原圖ctx.drawImage(this, 0, 0);// 添加水印ctx.font = "20px Arial";ctx.fillStyle = "rgba(255, 255, 255, 0.5)";ctx.fillText("? 版權所有", 10, 30);// 替換原圖this.src = canvas.toDataURL();});});
}
3. 內容加密顯示
// 簡單的內容混淆
function obfuscateContent() {const textNodes = document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT,null,false);const nodes = [];let node;while ((node = textNodes.nextNode())) {if (node.textContent.trim()) {nodes.push(node);}}nodes.forEach((node) => {const original = node.textContent;const obfuscated = btoa(original); // Base64編碼node.textContent = obfuscated;// 鼠標懸停時顯示原文node.parentElement.addEventListener("mouseenter", () => {node.textContent = original;});node.parentElement.addEventListener("mouseleave", () => {node.textContent = obfuscated;});});
}
🌐 瀏覽器兼容性
功能 | Chrome | Firefox | Safari | Edge | IE11 |
---|---|---|---|---|---|
user-select | ? | ? | ? | ? | ? |
contextmenu 事件 | ? | ? | ? | ? | ? |
selectstart 事件 | ? | ? | ? | ? | ? |
dragstart 事件 | ? | ? | ? | ? | ? |
keydown 事件 | ? | ? | ? | ? | ? |
touch-callout | ? | ? | ? | ? | ? |
tap-highlight-color | ? | ? | ? | ? | ? |
? 常見問題解答
Q1: 這些方法能 100%防止復制嗎?
A: 不能。這些方法只能防止普通用戶的意外復制,技術熟練的用戶仍然可以通過多種方式繞過這些限制。
Q2: 會影響 SEO 嗎?
A: 適當使用不會影響 SEO。搜索引擎爬蟲通常不會執行 JavaScript,所以 CSS 的user-select: none
不會影響內容索引。
Q3: 如何在保護內容的同時保持可訪問性?
A:
- 確保輸入框和表單元素可以正常使用
- 為屏幕閱讀器用戶提供替代的內容訪問方式
- 不要完全禁用鍵盤導航
Q4: 移動端效果如何?
A: 移動端的保護效果相對較好,特別是 iOS Safari 的-webkit-touch-callout: none
可以有效禁用長按菜單。
?CSS+JavaScript 禁用瀏覽器復制功能的幾種方法 - 高質量源碼分享平臺-免費下載各類網站源碼與模板及前沿技術分享