浏览器插件-霸王硬上复制器

有些网页内容无法复制,比如某乎还有某些网站,虽说直接截图再从图片复制内容也是可以做到!

但是感觉还是脱裤子放屁,多此一举。所以做了个霸王硬上复制器。开启后可以霸王硬上弓。直接强制复制。

content.js

// 复制助手 - 内容脚本
(function() {
    // 状态变量,默认为关闭状态
    let isEnabled = false;
    
    // 从存储中获取当前状态
    chrome.storage.local.get(['copyHelperEnabled'], function(result) {
        isEnabled = result.copyHelperEnabled || false;
        if (isEnabled) {
            enableCopying();
        }
    });
    
    // 监听来自popup的消息
    chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
        if (message.action === 'toggleCopyHelper') {
            isEnabled = message.enabled;
            
            if (isEnabled) {
                enableCopying();
                showNotification('复制助手已开启,现在您可以复制网页内容了');
            } else {
                disableCopying();
                showNotification('复制助手已关闭,网页恢复原始状态');
            }
        }
    });
    
    // 启用复制功能
    function enableCopying() {
        // 移除所有禁止复制的CSS属性
        const style = document.createElement('style');
        style.id = 'copy-helper-style';
        style.innerHTML = `
            * {
                -webkit-user-select: auto !important;
                -moz-user-select: auto !important;
                -ms-user-select: auto !important;
                user-select: auto !important;
            }
            
            *::selection {
                background-color: #b3d4fc !important;
                color: inherit !important;
            }
        `;
        document.head.appendChild(style);
        
        // 移除禁止复制的事件监听器
        document.addEventListener('copy', allowCopy, true);
        document.addEventListener('cut', allowCopy, true);
        document.addEventListener('contextmenu', allowContextMenu, true);
        document.addEventListener('selectstart', allowSelect, true);
        document.addEventListener('mousedown', allowMouseDown, true);
        
        // 禁用所有可能阻止复制的JavaScript函数
        overrideProtectionMethods();
    }
    
    // 禁用复制功能(恢复网页原始状态)
    function disableCopying() {
        // 移除我们添加的样式
        const style = document.getElementById('copy-helper-style');
        if (style) {
            style.remove();
        }
        
        // 移除我们添加的事件监听器
        document.removeEventListener('copy', allowCopy, true);
        document.removeEventListener('cut', allowCopy, true);
        document.removeEventListener('contextmenu', allowContextMenu, true);
        document.removeEventListener('selectstart', allowSelect, true);
        document.removeEventListener('mousedown', allowMouseDown, true);
        
        // 恢复页面刷新以重置所有覆盖的方法
        // 注意:这种方法可能不是最优的,但确保了完全恢复原始状态
        // location.reload();
    }
    
    // 允许复制的事件处理函数
    function allowCopy(e) {
        if (isEnabled) {
            e.stopImmediatePropagation();
            return true;
        }
    }
    
    // 允许右键菜单的事件处理函数
    function allowContextMenu(e) {
        if (isEnabled) {
            e.stopImmediatePropagation();
            return true;
        }
    }
    
    // 允许选择文本的事件处理函数
    function allowSelect(e) {
        if (isEnabled) {
            e.stopImmediatePropagation();
            return true;
        }
    }
    
    // 允许鼠标按下事件(有些网站通过此禁止选择)
    function allowMouseDown(e) {
        if (isEnabled && e.button === 0) { // 左键点击
            const target = e.target;
            const tagName = target.tagName.toLowerCase();
            
            // 如果不是输入框、按钮等交互元素,则允许选择
            if (!['input', 'textarea', 'button', 'select', 'a'].includes(tagName)) {
                // 不阻止默认行为,但阻止其他事件处理程序
                if (window.getComputedStyle(target).userSelect === 'none') {
                    e.stopImmediatePropagation();
                }
            }
        }
    }
    
    // 覆盖常见的保护方法
    function overrideProtectionMethods() {
        // 覆盖document.oncontextmenu
        if (document.oncontextmenu) {
            document.oncontextmenu = null;
        }
        
        // 覆盖document.onselectstart
        if (document.onselectstart) {
            document.onselectstart = null;
        }
        
        // 覆盖document.ondragstart
        if (document.ondragstart) {
            document.ondragstart = null;
        }
        
        // 覆盖document.onmousedown
        if (document.onmousedown) {
            document.onmousedown = null;
        }
        
        // 覆盖window.oncontextmenu
        if (window.oncontextmenu) {
            window.oncontextmenu = null;
        }
        
        // 禁用常见的禁止复制函数
        const disableProtection = function() {
            return true;
        };
        
        // 覆盖常见的禁止复制方法
        document.body.oncopy = disableProtection;
        document.body.oncut = disableProtection;
        document.body.onpaste = disableProtection;
        
        // 移除所有可能阻止复制的事件监听器
        const elements = document.querySelectorAll('*');
        for (let i = 0; i < elements.length; i++) {
            const el = elements[i];
            if (el.oncopy) el.oncopy = disableProtection;
            if (el.oncut) el.oncut = disableProtection;
            if (el.onpaste) el.onpaste = disableProtection;
            if (el.oncontextmenu) el.oncontextmenu = disableProtection;
            if (el.onselectstart) el.onselectstart = disableProtection;
            if (el.ondragstart) el.ondragstart = disableProtection;
        }
    }
    
    // 显示通知
    function showNotification(message) {
        const notification = document.createElement('div');
        notification.textContent = message;
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 10px 15px;
            background-color: #333;
            color: white;
            border-radius: 4px;
            font-size: 14px;
            z-index: 10000;
            opacity: 0;
            transition: opacity 0.3s ease;
        `;
        document.body.appendChild(notification);
        
        // 显示通知
        setTimeout(() => {
            notification.style.opacity = '1';
        }, 10);
        
        // 3秒后隐藏通知
        setTimeout(() => {
            notification.style.opacity = '0';
            setTimeout(() => {
                notification.remove();
            }, 300);
        }, 3000);
    }
})();

manifest.json

{
    "manifest_version": 3,
    "name": "霸王硬上复制器",
    "version": "1.0",
    "description": "一键开启/关闭网页内容复制功能,解除网站复制限制",
    "icons": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    },
    "action": {
      "default_popup": "popup.html",
      "default_icon": {
        "16": "icons/icon16.png",
        "48": "icons/icon48.png",
        "128": "icons/icon128.png"
      }
    },
    "content_scripts": [
      {
        "matches": ["<all_urls>"],
        "js": ["content.js"],
        "run_at": "document_end"
      }
    ],
    "permissions": ["activeTab", "storage"],
    "host_permissions": ["<all_urls>"]
  }

popup.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    body {
      width: 250px;
      padding: 15px;
      font-family: Arial, sans-serif;
    }
    h1 {
      font-size: 16px;
      margin-top: 0;
      color: #333;
      text-align: center;
    }
    .description {
      font-size: 14px;
      color: #666;
      margin-bottom: 15px;
    }
    
    /* 开关按钮样式 */
    .toggle-container {
      display: flex;
      justify-content: center;
      margin: 20px 0;
    }
    .toggle-switch {
      position: relative;
      display: inline-block;
      width: 60px;
      height: 34px;
    }
    .toggle-switch input {
      opacity: 0;
      width: 0;
      height: 0;
    }
    .slider {
      position: absolute;
      cursor: pointer;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: #ccc;
      transition: .4s;
      border-radius: 34px;
    }
    .slider:before {
      position: absolute;
      content: "";
      height: 26px;
      width: 26px;
      left: 4px;
      bottom: 4px;
      background-color: white;
      transition: .4s;
      border-radius: 50%;
    }
    input:checked + .slider {
      background-color: #4CAF50;
    }
    input:checked + .slider:before {
      transform: translateX(26px);
    }
    .toggle-label {
      margin-left: 10px;
      line-height: 34px;
    }
    
    .instructions {
      font-size: 13px;
      background-color: #f5f5f5;
      padding: 10px;
      border-radius: 4px;
      margin-top: 15px;
    }
    .instructions p {
      margin: 5px 0;
    }
    .footer {
      font-size: 12px;
      color: #999;
      text-align: center;
      margin-top: 15px;
    }
  </style>
</head>
<body>
  <h1>网页内容复制助手</h1>
  <div class="description">
    帮助您在禁止复制的网页上启用复制功能
  </div>
  
  <!-- 添加开关按钮 -->
  <div class="toggle-container">
    <label class="toggle-switch">
      <input type="checkbox" id="copyToggle">
      <span class="slider"></span>
    </label>
    <span class="toggle-label" id="toggleStatus">已关闭</span>
  </div>
  
  <div class="instructions">
    <p><strong>使用方法:</strong></p>
    <p>1. 点击上方开关按钮开启复制功能</p>
    <p>2. 开启后,您可以在任何网页上自由复制内容</p>
    <p>3. 再次点击开关按钮可关闭复制功能</p>
  </div>
  
  <div class="footer">
    版本 1.0 - 享受自由复制的乐趣
  </div>

  <script src="popup.js"></script>
</body>
</html>

popup.js

document.addEventListener('DOMContentLoaded', function() {
    const toggleSwitch = document.getElementById('copyToggle');
    const toggleStatus = document.getElementById('toggleStatus');
    
    // 从存储中获取当前状态
    chrome.storage.local.get(['copyHelperEnabled'], function(result) {
      toggleSwitch.checked = result.copyHelperEnabled || false;
      toggleStatus.textContent = toggleSwitch.checked ? '已开启' : '已关闭';
    });
    
    // 监听开关变化
    toggleSwitch.addEventListener('change', function() {
      const isEnabled = toggleSwitch.checked;
      toggleStatus.textContent = isEnabled ? '已开启' : '已关闭';
      
      // 保存状态到存储
      chrome.storage.local.set({copyHelperEnabled: isEnabled});
      
      // 向当前标签页发送消息
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        if (tabs[0]) {
          chrome.tabs.sendMessage(tabs[0].id, {
            action: 'toggleCopyHelper',
            enabled: isEnabled
          });
        }
      });
    });
  });

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值