效果图:
代码图:

content.js
javascript
// 从Chrome存储中获取需要匹配的网址字符
chrome.storage.sync.get(['matchText'], function (result) {
const matchText = result.matchText || ''; // 默认空字符(匹配所有网址)
const currentUrl = window.location.href;
// 判断当前网址是否包含指定字符(忽略大小写)
if (matchText && !currentUrl.toLowerCase().includes(matchText.toLowerCase())) {
return; // 不匹配则不执行统计
}
// 计算重仓加权涨跌幅的核心函数
async function calculateWeightedReturn() {
try {
// 找到目标表格(ui-table-hover)
const targetTable = document.querySelector('table.ui-table-hover');
if (!targetTable) {
console.log('未找到持仓表格');
return;
}
// 获取表格行(排除表头tr)
const tableRows = targetTable.querySelectorAll('tbody tr:not(:first-child)');
if (tableRows.length === 0) {
console.log('表格无持仓数据');
return;
}
let totalWeightedReturn = 0; // 加权涨跌幅总和
let totalPositionRatio = 0; // 总持仓占比(用于校验)
const stockDataList = []; // 存储单只股票数据(用于展示)
// 遍历每行提取数据
for (const row of tableRows) {
// 1. 提取股票名称
const stockName = row.querySelector('td.alignLeft a')?.title || '未知股票';
// 2. 提取持仓占比(去掉%转小数)
const positionRatioText = row.querySelector('td.alignRight.bold')?.textContent.trim() || '0%';
const positionRatio = parseFloat(positionRatioText.replace('%', '')) || 0;
// 3. 提取涨跌幅(去掉%转小数,处理正负号)
const returnRateText = row.querySelector('td.alignRight.bold span')?.textContent.trim() || '0%';
const returnRate = parseFloat(returnRateText.replace('%', '')) || 0;
// 4. 计算单只股票加权涨幅,累加至总和
const weightedReturn = positionRatio * returnRate / 100; // 持仓占比% * 涨跌幅% = ‰,转%需/100
totalWeightedReturn += weightedReturn;
totalPositionRatio += positionRatio;
// 存储单只股票数据
stockDataList.push({
name: stockName,
positionRatio: positionRatioText,
returnRate: returnRateText,
weightedReturn: weightedReturn.toFixed(4) + '%' // 格式化单只加权值
});
}
// 格式化最终加权涨幅(保留2位小数)
const formattedTotalReturn = totalWeightedReturn.toFixed(4) + '%';
// 格式化总持仓占比
const formattedTotalPosition = totalPositionRatio.toFixed(2) + '%';
// 创建统计结果显示面板
const statsPanel = document.createElement('div');
statsPanel.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
background: #fff;
border: 1px solid #ccc;
padding: 10px 15px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
z-index: 99999999;
font-family: Arial, sans-serif;
font-size: 14px;
color: #333;
max-height: 400px;
overflow-y: auto;
min-width: 300px;
`;
// 拼接面板HTML(总览+单只股票明细)
let panelHtml = `
<strong style="font-size:16px;">重仓加权涨幅统计</strong><br>
<hr style="margin:8px 0; border:0; border-top:1px solid #eee;">
总持仓占比:${formattedTotalPosition}<br>
加权总涨幅:<span style="color: ${totalWeightedReturn >= 0 ? '#e63946' : '#16a34a'}">${formattedTotalReturn}</span><br>
<hr style="margin:8px 0; border:0; border-top:1px solid #eee;">
<strong>单只股票明细</strong><br>
`;
// 拼接每只股票的明细
stockDataList.forEach(stock => {
panelHtml += `
<div style="margin:4px 0; padding:4px; background:#f8f9fa; border-radius:4px;">
${stock.name}<br>
持仓占比:${stock.positionRatio} | 涨跌幅:${stock.returnRate} | 加权贡献:${stock.weightedReturn}
</div>
`;
});
statsPanel.innerHTML = panelHtml;
// 先移除旧面板(避免重复),再插入新面板
const oldPanel = document.querySelector('div[style*="z-index: 99999999"]');
if (oldPanel) oldPanel.remove();
document.body.appendChild(statsPanel);
} catch (error) {
console.error('重仓涨幅计算失败:', error);
}
}
// 执行计算(DOM加载完成后执行,确保表格已渲染)
if (document.readyState === 'complete') {
calculateWeightedReturn();
} else {
window.addEventListener('load', calculateWeightedReturn);
}
});
manifest.json
javascript
{
"manifest_version": 3,
"name": "网页图片统计插件",
"version": "1.0",
"description": "自动统计指定网址的图片数量和数据量",
"permissions": ["storage"],
"host_permissions": ["<all_urls>"], // 解决跨域请求问题
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'" // Manifest V3 必须用对象格式
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_idle"
}
],
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
}
},
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
}
}
popup.html
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图片统计设置</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'self'"> <!-- 显式声明CSP(可选但推荐) -->
<style>
body { width: 200px; padding: 10px; }
.form-group { margin-bottom: 10px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input { width: 100%; padding: 5px; box-sizing: border-box; }
button { width: 100%; padding: 6px; background: #4285f4; color: #fff; border: none; border-radius: 4px; cursor: pointer; }
button:hover { background: #3367d6; }
</style>
</head>
<body>
<div class="form-group">
<label for="matchText">网址包含字符:</label>
<input type="text" id="matchText" placeholder="如:baidu、taobao">
</div>
<button id="saveBtn">保存设置</button>
<!-- 引入外部JS文件,替代内联脚本 -->
<script src="popup.js"></script>
</body>
</html>
popup.js
javascript
// 加载已保存的设置
chrome.storage.sync.get(['matchText'], function (result) {
if (result.matchText) {
document.getElementById('matchText').value = result.matchText;
}
});
// 保存设置到Chrome存储
document.getElementById('saveBtn').addEventListener('click', function () {
const matchText = document.getElementById('matchText').value.trim();
chrome.storage.sync.set({ matchText: matchText }, function () {
alert('设置保存成功!刷新网页生效');
});
});
图片自己随便找个替换即可。
将上述文件放到一个文件夹,打开chrome浏览器或qq浏览器。加载已解压的扩展插件,
最后大概基金页面(比如天天基金网),右上角就能看到啦
代码都是ai生成,你也试试吧