您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
支持PC 用于统计购物车域名列表,方便统计计算
// ==UserScript== // @name Namecheap 购物车域名列表 // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgODUgNDYuNTciPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0iYSIgeDE9IjU5Ljk5IiB5MT0iNDQuMTYiIHgyPSI4MC4wMSIgeTI9IjEuMjMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNkNDIwMmMiLz48c3RvcCBvZmZzZXQ9IjAuMSIgc3RvcC1jb2xvcj0iI2RjM2QyOSIgc3RvcC1vcGFjaXR5PSIwLjc5Ii8+PHN0b3Agb2Zmc2V0PSIwLjIiIHN0b3AtY29sb3I9IiNlNDU5MjYiIHN0b3Atb3BhY2l0eT0iMC41OCIvPjxzdG9wIG9mZnNldD0iMC4zMiIgc3RvcC1jb2xvcj0iI2VhNzEyMyIgc3RvcC1vcGFjaXR5PSIwLjQiLz48c3RvcCBvZmZzZXQ9IjAuNDMiIHN0b3AtY29sb3I9IiNmMDg1MjEiIHN0b3Atb3BhY2l0eT0iMC4yNSIvPjxzdG9wIG9mZnNldD0iMC41NSIgc3RvcC1jb2xvcj0iI2Y0OTQxZiIgc3RvcC1vcGFjaXR5PSIwLjE0Ii8+PHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjZjc5ZjFlIiBzdG9wLW9wYWNpdHk9IjAuMDYiLz48c3RvcCBvZmZzZXQ9IjAuODIiIHN0b3AtY29sb3I9IiNmOGE1MWQiIHN0b3Atb3BhY2l0eT0iMC4wMiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2Y5YTcxZCIgc3RvcC1vcGFjaXR5PSIwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIHgxPSIxNzc3LjQ4IiB5MT0iMTA0OC43NiIgeDI9IjE3OTcuNSIgeTI9IjEwMDUuODMiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTgwMy41IDEwNTIuNikgcm90YXRlKDE4MCkiIHhsaW5rOmhyZWY9IiNhIi8+PC9kZWZzPjx0aXRsZT5jbi1sb2dvPC90aXRsZT48cGF0aCBkPSJNNzcuMTcuNzFhNy44Nyw3Ljg3LDAsMCwwLTYuODgsNC4wNWwtLjE2LjMzTDY0LDE3LjI1bC03LjgsMTUuMzcsNS4xMSwxMC4wNy4yOC41NUE4LDgsMCwwLDAsNjUsNDYuNDdhOC4wNSw4LjA1LDAsMCwwLDMuNDEtMy4yM2wuMjgtLjU1TDg0LDEyLjQ4bC4zNy0uNzNhNy44Niw3Ljg2LDAsMCwwLTcuMTktMTFaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMSAtMC43MSkiIGZpbGw9IiNmZjUxMDAiLz48cGF0aCBkPSJNMjkuODUsMTUuMzRsLTUuMS0xMC0uMjgtLjU1YTcuODksNy44OSwwLDAsMC0zLjQtMy4yMiw3LjkyLDcuOTIsMCwwLDAtMy40LDMuMjFsLS4yOS41NkwyLjA1LDM1LjUybC0uMzcuNzJhNy44Niw3Ljg2LDAsMCwwLDE0LjA2LDdsLjE3LS4zMiw2LjE3LTEyLjE2TDI5Ljg3LDE1LjRaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMSAtMC43MSkiIGZpbGw9IiNmZjUxMDAiLz48cGF0aCBkPSJNNzcuMTUuNzFhNy44Niw3Ljg2LDAsMCwwLTYuODcsNC4wNWwtLjE3LjMzTDYzLjk0LDE3LjI1LDU2LjEzLDMyLjYybDUuMTIsMTAuMDcuMjguNTVhNy45NCw3Ljk0LDAsMCwwLDMuNDEsMy4yMyw3Ljk0LDcuOTQsMCwwLDAsMy40MS0zLjIzbC4yOS0uNTVMODQsMTIuNDhsLjM2LS43M2E3Ljg2LDcuODYsMCwwLDAtNy4xOS0xMVoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xIC0wLjcxKSIgZmlsbD0idXJsKCNhKSIvPjxwYXRoIGQ9Ik04Ljg2LDQ3LjI5YTcuODYsNy44NiwwLDAsMCw2Ljg3LTRsLjE3LS4zMyw2LjE4LTEyLjE2LDcuOC0xNS4zN0wyNC43Nyw1LjMxbC0uMjgtLjU1YTgsOCwwLDAsMC0zLjQyLTMuMjMsOCw4LDAsMCwwLTMuNDEsMy4yM2wtLjI4LjU1TDIsMzUuNTJsLS4zNy43M2E3Ljg2LDcuODYsMCwwLDAsNy4xOSwxMVoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xIC0wLjcxKSIgZmlsbD0idXJsKCNiKSIvPjxwYXRoIGQ9Ik0yOS44NSwxNS4zNGwtNS4xLTEwLS4yOC0uNTVhNy45NCw3Ljk0LDAsMCwwLTMuNDEtMy4yM0E4LjMxLDguMzEsMCwwLDEsMjIuNTUsMWE4LjE2LDguMTYsMCwwLDEsMi0uMjVIMzUuMjNhNy45Miw3LjkyLDAsMCwxLDYuODYsNGwuMjguNTVMNTYuMTgsMzIuNjZsNS4wOSwxMCwuMjguNTVBOCw4LDAsMCwwLDY1LDQ2LjQ3YTguMDUsOC4wNSwwLDAsMS0zLjQ3LjgxSDUwLjc5YTcuOTEsNy45MSwwLDAsMS02Ljg1LTRsLS4yOS0uNTVaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMSAtMC43MSkiIGZpbGw9IiNmZjhjNDQiLz48L3N2Zz4K // @match *://www.namecheap.com/shoppingcart/* // @grant GM_addStyle // @version 2025.7.25 // @author ayersltd // @description 支持PC 用于统计购物车域名列表,方便统计计算 // @license GPL-3.0-only // @require https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.6.2/fuse.min.js // @namespace https://greasyfork.org/users/1497923 // ==/UserScript== (function() { // 添加自定义样式 GM_addStyle(` #domainListPanel { position: fixed; top: 50px; right: 50px; background: #fff; border: 1px solid #e1e1e1; border-radius: 8px; box-shadow: 0 8px 30px rgba(0,0,0,0.12); z-index: 99999; width: 380px; max-height: 85vh; display: flex; flex-direction: column; font-family: 'Segoe UI', system-ui, sans-serif; } .panel-header { padding: 16px; background: #f8f8f8; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; align-items: center; border-radius: 8px 8px 0 0; } .panel-title { font-weight: 600; font-size: 16px; color: #333; margin: 0; } .panel-close { background: none; border: none; font-size: 18px; cursor: pointer; color: #888; } .panel-actions { padding: 12px 16px; display: flex; gap: 8px; border-bottom: 1px solid #eee; } .search-box { flex: 1; padding: 8px 12px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; } .action-btn { padding: 6px 12px; background: #f2f2f2; border: 1px solid #ddd; border-radius: 4px; cursor: pointer; font-size: 13px; } .action-btn:hover { background: #e8e8e8; } .panel-content { flex: 1; overflow: auto; padding: 0; } .domain-list { list-style: none; padding: 0; margin: 0; } .domain-item { padding: 12px 16px; border-bottom: 1px solid #f5f5f5; font-size: 14px; display: flex; justify-content: space-between; align-items: center; } .domain-name { word-break: break-all; padding-right: 10px; } .domain-count { background: #f0f5ff; color: #2f5bea; border-radius: 12px; padding: 3px 8px; font-size: 12px; font-weight: 500; min-width: 60px; text-align: center; } .panel-footer { padding: 12px 16px; text-align: center; background: #f8f8f8; border-top: 1px solid #eee; font-size: 13px; color: #666; border-radius: 0 0 8px 8px; } .view-toggle { display: flex; gap: 8px; margin-bottom: 12px; justify-content: center; } .view-option { padding: 4px 12px; border-radius: 15px; background: #f0f0f0; cursor: pointer; font-size: 12px; } .view-option.active { background: #e1ecff; color: #2f5bea; font-weight: 500; } .section-title { padding: 10px 16px; background: #f8f8f8; font-weight: 600; font-size: 13px; color: #666; border-bottom: 1px solid #eee; position: sticky; top: 0; } .tld-group { margin-bottom: 15px; } `); // 主功能 function initDomainList() { // 创建面板容器 const panel = document.createElement('div'); panel.id = 'domainListPanel'; // 添加头部 panel.innerHTML = ` <div class="panel-header"> <h3 class="panel-title">域名购物车</h3> <button class="panel-close">×</button> </div> <div class="panel-actions"> <input type="text" class="search-box" placeholder="搜索域名..." id="domainSearch"> <button class="action-btn" id="copyAllBtn">复制所有</button> </div> <div class="view-toggle"> <span class="view-option active" data-view="list">列表视图</span> <span class="view-option" data-view="tld">按后缀分组</span> </div> <div class="panel-content"> <ul class="domain-list" id="domainList"></ul> </div> <div class="panel-footer"> <div class="domain-count">共计: <span id="totalCount">0</span> 个域名</div> </div> `; document.body.appendChild(panel); // 获取元素引用 const domainList = document.getElementById('domainList'); const searchBox = document.getElementById('domainSearch'); const copyAllBtn = document.getElementById('copyAllBtn'); const totalCount = document.getElementById('totalCount'); const closeBtn = document.querySelector('.panel-close'); const viewOptions = document.querySelectorAll('.view-option'); let allDomains = []; let currentView = 'list'; // 关闭面板 closeBtn.addEventListener('click', () => { panel.style.display = 'none'; }); // 视图切换 viewOptions.forEach(option => { option.addEventListener('click', () => { viewOptions.forEach(o => o.classList.remove('active')); option.classList.add('active'); currentView = option.dataset.view; updateDomainListView(allDomains); }); }); // 搜索功能 searchBox.addEventListener('input', (e) => { const keyword = e.target.value.trim().toLowerCase(); if (!keyword) { updateDomainListView(allDomains); return; } const filteredDomains = allDomains.filter(domain => domain.toLowerCase().includes(keyword) ); updateDomainListView(filteredDomains); }); // 复制所有域名 copyAllBtn.addEventListener('click', () => { if (allDomains.length === 0) return; const domainsText = allDomains.join('\n'); navigator.clipboard.writeText(domainsText).then(() => { showNotification(`已复制 ${allDomains.length} 个域名到剪贴板`); }); }); // 拖拽功能 initPanelDrag(panel); // 初始加载域名 setTimeout(loadDomainList, 1500); // 加载域名列表 function loadDomainList() { const domains = []; // 使用XPath查找所有域名文本节点 const xpath = "//div[@data-e2e-id='sc-product-container']//p[@data-e2e-id='sc-product-sub-title']/text()"; const result = document.evaluate( xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); // 提取域名文本 for (let i = 0; i < result.snapshotLength; i++) { const node = result.snapshotItem(i); const domain = node.nodeValue.trim(); if (domain) domains.push(domain); } if (domains.length === 0) { showNotification("未找到有效域名"); return; } allDomains = domains; totalCount.textContent = domains.length; updateDomainListView(domains); } // 更新域名列表视图 function updateDomainListView(domains) { domainList.innerHTML = ''; if (domains.length === 0) { domainList.innerHTML = '<div class="domain-item">未找到匹配域名</div>'; return; } if (currentView === 'tld') { renderTLDGroupView(domains); } else { renderListView(domains); } } // 渲染列表视图 function renderListView(domains) { domains.forEach((domain, index) => { const li = document.createElement('li'); li.className = 'domain-item'; li.innerHTML = ` <span class="domain-name">${index + 1}. ${domain}</span> `; domainList.appendChild(li); }); } // 渲染TLD分组视图 function renderTLDGroupView(domains) { // 按TLD分组 const groups = {}; domains.forEach(domain => { const tld = domain.split('.').pop(); if (!groups[tld]) groups[tld] = []; groups[tld].push(domain); }); // 渲染分组视图 Object.entries(groups).forEach(([tld, domainListInGroup]) => { const section = document.createElement('div'); section.className = 'tld-group'; section.innerHTML = ` <div class="section-title">.${tld} (${domainListInGroup.length})</div> `; const ul = document.createElement('ul'); ul.className = 'domain-list'; domainListInGroup.forEach((domain, index) => { const li = document.createElement('li'); li.className = 'domain-item'; li.innerHTML = `<span class="domain-name">${index + 1}. ${domain}</span>`; ul.appendChild(li); }); section.appendChild(ul); domainList.appendChild(section); }); } } // 拖拽功能 function initPanelDrag(panel) { let isDragging = false; let offsetX, offsetY; const header = panel.querySelector('.panel-header'); header.addEventListener('mousedown', (e) => { isDragging = true; offsetX = e.clientX - panel.getBoundingClientRect().left; offsetY = e.clientY - panel.getBoundingClientRect().top; }); document.addEventListener('mousemove', (e) => { if (isDragging) { panel.style.left = `${e.clientX - offsetX}px`; panel.style.top = `${e.clientY - offsetY}px`; } }); document.addEventListener('mouseup', () => { isDragging = false; }); } // 显示通知 function showNotification(message) { const notification = document.createElement('div'); notification.textContent = message; notification.style.cssText = ` position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background: #4caf50; color: white; padding: 12px 24px; border-radius: 4px; z-index: 10000; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: fadeInOut 3s ease; `; document.body.appendChild(notification); setTimeout(() => { notification.remove(); }, 3000); } // 延迟初始化,确保页面加载完成 if (document.readyState === 'complete') { initDomainList(); } else { window.addEventListener('load', initDomainList); } })();