fail link show

标识无效的a标签

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         fail link show
// @namespace    [email protected]
// @description  标识无效的a标签
// @version      0.3
// @match        *://*.3d66.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(() => {
  "use strict";

  const STYLE_ID = "__query_only_mark_style__";
  const MARK_CLASS = "__query_only_mark";
  const BADGE_CLASS = "__query_only_badge";

  const ensureStyle = () => {
    if (document.getElementById(STYLE_ID)) return;
    const styleEl = document.createElement("style");
    styleEl.id = STYLE_ID;
    styleEl.textContent = `
      a.${MARK_CLASS}{
        outline:none !important;
      }
      a.${MARK_CLASS} .${BADGE_CLASS}{
        position:absolute !important;top:4px !important;right:4px !important;z-index:99999 !important;
        pointer-events:none !important;
        display:inline-flex !important;align-items:center !important;justify-content:center !important;
        width:16px !important;height:16px !important;
        font-size:10px !important;line-height:1 !important;border-radius:999px !important;
        font-weight:700 !important;
        color:#fff !important;
        background:linear-gradient(145deg,#ff6b6b,#d32f2f) !important;
        border:1px solid rgba(211,47,47,.9) !important;
        box-shadow:0 0 0 1px rgba(255,255,255,.9), 0 1px 4px rgba(211,47,47,.35) !important;
      }
    `;
    document.head.appendChild(styleEl);
  };

  const isEmptyHref = (href) => href == null || href.trim() === "";

  const isQueryOnlyHref = (href) => {
    if (isEmptyHref(href)) return false;
    const trimmed = href.trim();
    return trimmed.startsWith("?");
  };

  const applyBadges = () => {
    ensureStyle();
    document.querySelectorAll("a").forEach((a) => {
      const rawHref = a.getAttribute("href");
      const badge = a.querySelector(`.${BADGE_CLASS}`);
      const isBadLink = isEmptyHref(rawHref) || isQueryOnlyHref(rawHref);
      if (!isBadLink) {
        a.classList.remove(MARK_CLASS);
        badge?.remove();
        return;
      }

      const rect = a.getBoundingClientRect();
      const hasImg = a.querySelector("img") !== null;
      // 判断是否为卡片/块级元素:有图片,或尺寸较大,或绝对定位
      const computed = getComputedStyle(a);
      const isAbsolute = computed.position === "absolute" || computed.position === "fixed";
      const isCard = hasImg || (rect.height > 40 && rect.width > 40) || isAbsolute;

      // 基础样式
      const baseStyle =
        "z-index:99999;pointer-events:none;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;font-weight:700;color:#fff;background:linear-gradient(145deg,#ff6b6b,#d32f2f);border:1px solid rgba(211,47,47,.9);box-shadow:0 0 0 1px rgba(255,255,255,.9), 0 1px 4px rgba(211,47,47,.35);";

      let finalStyle = "";
      if (isCard) {
        // 卡片模式:右上角绝对定位
        if (computed.position === "static") {
          a.style.position = "relative";
        }
        finalStyle = `${baseStyle} position:absolute;top:4px;right:4px;width:16px;height:16px;font-size:10px;line-height:1;margin:0;transform:none;`;
      } else {
        // 文本模式:行内追加,不遮挡文字
        // 不需要设置 relative
        finalStyle = `${baseStyle} position:static;width:14px;height:14px;font-size:9px;line-height:1;margin-left:4px;vertical-align:middle;transform:translateY(-1px);`;
      }

      const ensureBadge = () => {
        if (!badge) {
          const nextBadge = document.createElement("span");
          nextBadge.className = BADGE_CLASS;
          nextBadge.textContent = "!";
          nextBadge.style.cssText = finalStyle;
          a.appendChild(nextBadge);
        } else {
          badge.style.cssText = finalStyle;
          // 确保在最后,防止位置不对
          if (a.lastElementChild !== badge) {
            a.appendChild(badge);
          }
        }
      };
      ensureBadge();
    });
  };

  let rafId = null;
  const scheduleApply = () => {
    if (rafId) return;
    rafId = requestAnimationFrame(() => {
      rafId = null;
      applyBadges();
    });
  };

  const observer = new MutationObserver(() => scheduleApply());
  observer.observe(document.documentElement, { subtree: true, childList: true, attributes: true });

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", () => applyBadges(), { once: true });
  } else {
    applyBadges();
  }
})();