将新浪股票接口的数据直接实时展示在浏览器的标签与页面上。
// ==UserScript==
// @name 新浪股票 API 数据实时展示
// @namespace https://github.com/yujinpan/tampermonkey-extension
// @version 1.1
// @license MIT
// @description 将新浪股票接口的数据直接实时展示在浏览器的标签与页面上。
// @author yujinpan
// @include http*://hq.sinajs.cn/*
// ==/UserScript==
class App {
intervalId = 0;
intervalTime = 3000;
data = {};
tableWrap = null;
constructor(code) {
this.code = code;
}
// 获取数据
getData() {
return fetch(`/list=${this.code}`)
.then((res) => res.blob())
.then((blob) => {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = function () {
resolve(reader.result);
};
reader.readAsText(blob, 'GBK');
});
});
}
// 格式化数据
formatData(resultData) {
try {
const arr = resultData
.match(/".*"/)[0]
.replace(/"/g, '')
.split(',');
const reduce = arr[3] - arr[2];
const percent = ((reduce / arr[2]) * 100).toFixed(2);
this.data = {
reduce,
percent,
date: arr[30],
time: arr[31],
name: arr[0],
start: arr[1],
end: arr[2],
current: arr[3],
max: arr[4],
min: arr[5]
};
} catch (e) {
console.log(e);
}
}
// 设置title
setTitle() {
document.title = `${this.data.name} ${this.data.current} ${
this.data.percent
}%`;
}
// 渲染table
renderTable() {
const params = this.data;
const sign = Math.sign(params.percent);
const color = sign < 0 ? 'green' : sign === 0 ? 'gray' : 'red';
// 如果没有容器就创建一个
if (!this.tableWrap) {
this.tableWrap = document.createElement('section');
this.tableWrap.style = `
padding: 0 20px;
margin-right: 20px;
border-right: 1px solid #ddd;
`;
document.body.appendChild(this.tableWrap);
}
this.tableWrap.innerHTML = `
<h4>${params.date} ${params.time}</h4>
<h4>${params.name}
<font color="${color}">
${params.current} ${params.percent}% ${params.reduce.toFixed(3)}
</font>
</h4>
<table border="1">
<thead>
<tr>
<td>今日开盘</td>
<td>昨日收盘</td>
<td>今日最高</td>
<td>今日最低</td>
</tr>
</thead>
</tbody>
<tr>
<td>${params.start}</td>
<td>${params.end}</td>
<td>${params.max}</td>
<td>${params.min}</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 30px;" />
<div><img width="600px" height="330px" src="${this.getMinImageUrl()}" /></div>
<div><img width="600px" height="330px" src="${this.getDayKImageUrl()}" /></div>
`;
}
// 创建搜索
renderSearch() {
const searchHistoryElem = this.getSearchHistory()
.map((item) => {
return `<li><a href="/list=${item.code}">${item.name}(${
item.code
})</a></li>`;
})
.join('');
const elem = `
<h5>搜索股票</h5>
<input id="search" autocomplete="false" style="width: 180px;" placeholder="输入股票代码,例如 sh000001" />
<button>搜索</button>
<h5>搜索历史</h5>
<ul>
${searchHistoryElem}
</ul>
<h5>指数</h5>
<ul>
<li><a href="/list=sh000001">上证指数</a></li>
</ul>
`;
const searchWrap = document.createElement('section');
searchWrap.innerHTML = elem;
const inputElem = searchWrap.querySelector('input');
// 点击与回车事件
searchWrap.addEventListener('click', (e) => {
if (e.target.tagName === 'BUTTON' && inputElem.value) {
this.targetTo(inputElem.value);
}
});
searchWrap.addEventListener('keyup', (e) => {
if (e.keyCode === 13 && e.target.tagName === 'INPUT' && inputElem.value) {
this.targetTo(inputElem.value);
}
});
document.body.appendChild(searchWrap);
}
// 跳转
targetTo(code) {
location.href = `/list=${code}`;
}
// 获取搜索历史
getSearchHistory() {
const history = localStorage.getItem('history');
if (history) {
return JSON.parse(history);
} else {
return [];
}
}
// 存储搜索历史
setSearchHistory(code, name) {
const history = this.getSearchHistory();
const index = history.findIndex((item) => item.code === code);
if (index !== -1) {
history.splice(index, 1);
}
history.unshift({code, name});
localStorage.setItem('history', JSON.stringify(history));
}
// 获取分时图
getMinImageUrl() {
return `http://image.sinajs.cn/newchart/min/n/${this.code}.gif?v=${Date.now()}`;
}
// 获取分时图
getDayKImageUrl() {
return `http://image.sinajs.cn/newchart/daily/n/${this.code}.gif?v=${Date.now()}`;
}
// 开始
start() {
const handle = () => {
return this.getData().then((res) => {
this.formatData(res);
if (this.data.current) {
this.setTitle();
this.renderTable();
return Promise.resolve(true);
} else {
alert('代码错误!');
this.stop();
return Promise.resolve(false);
}
});
};
this.intervalId = setInterval(() => handle(), this.intervalTime);
document.body.innerHTML = '';
document.body.style = `
display: flex;
`;
handle().then((res) => {
this.renderSearch();
if (res) {
this.setSearchHistory(
location.pathname.replace('/list=', ''),
this.data.name
);
}
});
}
// 停止
stop() {
clearInterval(this.intervalId);
}
}
// 初始化
(function () {
const code = location.pathname.replace('/list=', '');
const app = new App(code || 'sh000001');
app.start();
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址