您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Hover tooltip of image displaying alt attribute, original title, some accessibility-related properties, and URL info.
当前为
// ==UserScript== // @name Image Alt to Title // @namespace myfonj // @include * // @grant none // @version 1.6.1 // @run-at document-start // @description Hover tooltip of image displaying alt attribute, original title, some accessibility-related properties, and URL info. // @license CC0 // ==/UserScript== /* * https://gf.qytechs.cn/en/scripts/418348/versions/new * * § Trivia: * ¶ Hover tooltip displays content of nearest element's title attribute (@title). * ¶ Alt attribute (@alt) is possible only at IMG element. * ¶ IMG@alt is not displayed in tooltip. * ¶ IMG cannot have children. * ¶ @title is possible on any element, including IMG. * ¶ IMG@src is also valuable. * * Goal: * Display image alt attribute value in images hover tooltip, add valuable @SRC chunks. * * Details * Pull @alt from image and set it so it is readable as @title tooltip * so that produced title value will not obscure existing parent title * that would be displayed otherwise. Also include image filename from @src, * and additionally path or domain. * * Means * Upon "hover" set image's title attribute. Luckily tooltips delay catches augmented value. * * § Tastcases * * FROM: * <a> * <img> * </a> * TO: * <a> * <img title="Alt missing."> * </a> * * FROM: * <a> * <img alt=""> * </a> * TO: * <a> * <img alt="" title="Alt: ''"> * </a> * * FROM: * <a> * <img alt="░"> * </a> * TO: * <a> * <img alt="░" title="Alt: ░"> * </a> * * FROM: * <a> * <img alt="░" title="▒"> * </a> * TO: * <a> * <img title="Alt: ░, title: ▒"> * </a> * FROM: * <a title="▒"> * <img alt="░"> * </a> * TO: * <a> * <img title="Alt: ░, title: ▒"> * </a> * */ // do not run at image-only pages if (document.querySelector('body>img[alt="' + document.location.href + '"]:only-child')) { // @ts-ignore (GreaseMonkey script is in fact function body) return } const originalTitles = new WeakMap(); const docEl = document.documentElement; const listenerConf = { capture: true, passive: true }; docEl.addEventListener('mouseenter', altToTitle, listenerConf); docEl.addEventListener('mouseleave', restoreTitle, listenerConf); function altToTitle (event) { const tgt = event.target if (tgt.tagName && tgt.tagName == 'IMG') { originalTitles.set(tgt, tgt.getAttribute('title')); altPic(tgt); } } function restoreTitle (event) { const tgt = event.target; if (originalTitles.has(tgt)) { let ot = originalTitles.get(tgt); if(ot === null) { tgt.removeAttribute('title'); } else { tgt.title = ot; } originalTitles.delete(tgt); } } /** * @param {HTMLImageElement} img */ function altPic (img) { try { const separator = '---'; const info = []; const alt = img.getAttribute('alt'); let altText = alt; const title = getClosestTitle(img); const role = img.getAttribute('role'); const isPresentation = role === 'presentation'; if (role) { info.push('Role: ' + role); } switch (alt) { case null: info.push(isPresentation ? `(Alt missing but not needed for this role.)` : `⚠ Alt missing`); break; case '': info.push(`Alt: ""`); break; default: if( alt != alt.trim() ) { // "quote" characters are generally useful only to reveal leading/trailing whitespace altText = `»${alt}«`; } if (alt == title) { info.push(`Alt (=title): ${altText}`); } else { info.push(`Alt: ${altText}`); } } if (title && alt != title) { info.push(separator); info.push('Title: ' + title); } const descby = img.getAttribute('aria-describedby'); if (descby) { info.push(separator); info.push('Described by `' + descby + '`: ' + (document.getElementById(descby) || { textContent: '(element not found)' }).textContent); } // depreated, but let's see // https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/longDesc // https://www.stylemanual.gov.au/format-writing-and-structure/content-formats/images/alt-text-captions-and-titles-images const longdesc = img.getAttribute('longdesc'); if (longdesc) { info.push(separator); info.push('Long Description: ' + longdesc); } const arialabel = img.getAttribute('aria-label'); if (arialabel) { info.push(separator); info.push('Label (ARIA): ' + arialabel); } // https://html5accessibility.com/stuff/2021/02/09/aria-description-by-public-demand-and-to-thunderous-applause/ const histeve = img.getAttribute('aria-description'); if (histeve) { info.push(separator); info.push('Description: ' + histeve); } var fig = getClosestEl(img, 'FIGURE'); if( fig ){ let capt = fig.querySelector('figcaption'); if( capt) { info.push(separator); info.push('Figcaption: ' + capt.textContent.trim()); } } info.push(separator); const srcURI = new URL(img.currentSrc || img.src, img.baseURI); const slugRx = /[^/]+$/; switch (srcURI.protocol) { case 'http:': case 'https:': { if (srcURI.search) { info.push('Params: ' + srcURI.search); } info.push('File: ' + srcURI.pathname.match(slugRx)); let path = srcURI.pathname.replace(slugRx, ''); if(path && path != '/') { info.push('Path: ' + srcURI.pathname.replace(slugRx, '')); } if (document.location.hostname != srcURI.hostname || window != window.top) { info.push('Host: ' + srcURI.hostname); } break; } case 'data:': { let durichunks = srcURI.href.split(','); info.push(durichunks[0] + ', + ' + durichunks[1].length + ' b.'); break; } default: info.push('Src: ' + srcURI.href); } var CSSsizes = `${img.width}×${img.height}px`; if (img.naturalWidth && img.naturalHeight) { // SVG have zero naturals if (img.naturalWidth == img.width && img.naturalHeight == img.height) { CSSsizes += ` (Natural)`; } else { CSSsizes += ` (Natural: ${img.naturalWidth}×${img.naturalHeight}px)`; } } info.push('CSS Size: ' + CSSsizes); img.title = info.join('\n'); } catch (e) { // console.error('altPic ERROR', e, img); } } /** * @param {HTMLElement} el */ function getClosestTitle (el) { do { if (el.title) { return el.title; } } while (el = el.parentElement); return '' } /** * @param {HTMLElement} el */ function getClosestEl (el, tagName) { do { if (el.tagName == tagName) { return el; } } while (el = el.parentElement); return false }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址