您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds primary indicators to the OVTLYR 9
// ==UserScript== // @name OVTLYR Indicators // @description Adds primary indicators to the OVTLYR 9 // @run-at document-idle // @include /^https?://(www\.)?ovtlyr\.com/dashboard/[a-zA-Z]+$/ // @grant none // @license GPL // @version 0.0.1.20250829074731 // @namespace https://greasyfork.org/users/1509889 // ==/UserScript== (function() { 'use strict'; // Tooltip text for the indicators (you can edit these) // Checks the browser's language to use "favourite" or "favorite" const isAmericanEnglish = navigator.language === 'en-US'; const bftTooltipText = isAmericanEnglish ? "Batman's Favorite Trade" : "Batman's Favourite Trade"; const tbtTooltipText = "The Big Trend"; // Lists of box IDs for each indicator type const bftBoxes = ['div_sectorFG', 'div_marketBreadth', 'div_stockTrend']; const tbtBoxes = ['div_marketTrend', 'div_sectorBreadth', 'div_stockTrend']; // A map of boxes and the indicator text they should have, along with their position const indicatorsData = [{ id: 'div_sectorFG', text: 'BFT', right: '5px' }, { id: 'div_marketBreadth', text: 'BFT', right: '5px' }, { id: 'div_stockTrend', text: 'BFT', right: '5px' }, { id: 'div_marketTrend', text: 'TBT', left: '5px' }, { id: 'div_sectorBreadth', text: 'TBT', left: '5px' }, { id: 'div_stockTrend', text: 'TBT', left: '5px' }]; // A single, reusable tooltip element for the entire page let tooltip; function createTooltip() { tooltip = document.createElement('div'); tooltip.style.position = 'absolute'; tooltip.style.display = 'none'; tooltip.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; tooltip.style.color = 'white'; tooltip.style.padding = '5px 10px'; tooltip.style.borderRadius = '5px'; tooltip.style.zIndex = '9999'; tooltip.style.fontSize = '12px'; tooltip.style.whiteSpace = 'nowrap'; document.body.appendChild(tooltip); } function addIndicator(targetId, text, position) { const targetBox = document.getElementById(targetId); if (targetBox) { if (targetBox.querySelector(`.indicator-${text}`)) { return; } const indicator = document.createElement('span'); indicator.className = `indicator-${text}`; indicator.style.position = 'absolute'; indicator.style.top = '5px'; indicator.style.padding = '2px 5px'; indicator.style.borderRadius = '5px'; indicator.style.color = '#FFFFFF'; indicator.style.fontSize = '10px'; indicator.style.fontWeight = 'bold'; indicator.textContent = text; indicator.style.transition = 'background-color 0.5s ease-in-out, box-shadow 0.2s ease-in-out'; indicator.style.zIndex = '1'; indicator.style.cursor = 'pointer'; if (text === 'BFT') { indicator.dataset.tooltipText = bftTooltipText; } else if (text === 'TBT') { indicator.dataset.tooltipText = tbtTooltipText; } if (position.right) { indicator.style.right = position.right; } else if (position.left) { indicator.style.left = position.left; } const computedStyle = window.getComputedStyle(targetBox); if (computedStyle.position === 'static') { targetBox.style.position = 'relative'; } targetBox.appendChild(indicator); indicator.addEventListener('mouseenter', (event) => { const rect = event.target.getBoundingClientRect(); tooltip.textContent = event.target.dataset.tooltipText; tooltip.style.left = `${rect.left + window.scrollX}px`; tooltip.style.top = `${rect.bottom + window.scrollY + 5}px`; tooltip.style.display = 'block'; const indicatorType = event.target.textContent; const allIndicators = document.querySelectorAll(`.indicator-${indicatorType}`); allIndicators.forEach(el => { el.style.boxShadow = '0 0 5px 2px #fff'; }); }); indicator.addEventListener('mouseleave', (event) => { tooltip.style.display = 'none'; const indicatorType = event.target.textContent; const allIndicators = document.querySelectorAll(`.indicator-${indicatorType}`); allIndicators.forEach(el => { el.style.boxShadow = 'none'; }); }); } } function updateAllIndicatorColors() { const isBftPink = bftBoxes.some(id => { const el = document.getElementById(id); return el && el.classList.contains('pink_backg'); }); const bftColor = isBftPink ? '#FF0000' : '#008000'; const isTbtPink = tbtBoxes.some(id => { const el = document.getElementById(id); return el && el.classList.contains('pink_backg'); }); const tbtColor = isTbtPink ? '#FF0000' : '#008000'; indicatorsData.forEach(item => { const box = document.getElementById(item.id); if (box) { const indicator = box.querySelector(`.indicator-${item.text}`); if (indicator) { if (item.text === 'BFT') { indicator.style.backgroundColor = bftColor; } else if (item.text === 'TBT') { indicator.style.backgroundColor = tbtColor; } } } }); } window.addEventListener('load', () => { createTooltip(); const allUniqueBoxes = [...new Set([...bftBoxes, ...tbtBoxes])]; allUniqueBoxes.forEach(id => { const targetNode = document.getElementById(id); if (targetNode) { indicatorsData.filter(item => item.id === id).forEach(item => { if (item.right) { addIndicator(item.id, item.text, { right: item.right }); } else if (item.left) { addIndicator(item.id, item.text, { left: item.left }); } }); const observer = new MutationObserver(updateAllIndicatorColors); observer.observe(targetNode, { attributes: true, attributeFilter: ['class'] }); } }); updateAllIndicatorColors(); }); })();