如何让 GreaseMonkey 脚本在页面中的元素显示之前对其产生影响?

2024-05-12

我试图确保不显示某个网站中的图像,但仍显示替代文本。最初,我尝试使用 Stylish(使用 Firefox)来完成此任务,并提出了以下问题:

如何强制显示图像的替代文本而不是图像? https://stackoverflow.com/questions/32122253/how-to-force-an-images-alt-text-to-display-instead-of-the-image/

接受的答案为我提供了使用 Greasemonkey 的替代解决方案。该脚本使用等待关键元素 https://gist.github.com/BrockA/2625891隐藏图像,即使它们是使用 AJAX 添加的。

我将给定的脚本更改为以下内容:

// ==UserScript==
// @name     _Hide pics except for alt text
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==

GM_addStyle ( "                                 \
    * {                                         \
        background-image: none !important;      \
    }                                           \
" );

waitForKeyElements ("img", hideImageExceptForAltText);

function hideImageExceptForAltText (jNode) {
    var imgAlt = jNode.attr("alt");
    var imgTitle = jNode.attr("title");

    jNode.css("display", "none");

    var newSpan = $("<span></span>");
    newSpan.attr("title", imgTitle);
    newSpan.append(imgAlt);

    jNode.parent().append(newSpan);
}

就像原始脚本一样,这存在一个问题,即在页面加载时图像仍会显示一段时间。

是否可以确保给定的函数将阻止页面上的图像立即显示,从而使它们根本不可见?

编辑:布洛克·亚当斯的回复提供了我所缺少的线索。如果有人正在寻找类似的东西,以下是我最终使用的。它在我需要它的网站上工作正常,但我不能保证它在其他网站或除 Firefox 之外的其他浏览器上也能工作。

以下隐藏图像并用链接替换它们(背景图像除外)。单击该链接将显示该图像。

// ==UserScript==
// @name        TCRF images
// @namespace   SOMETHING
// @include     http://YOUR_SERVER.COM/YOUR_PATH/*
// @require     http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// @version     1
// @grant       GM_addStyle
// @run-at      document-start
// ==/UserScript==

GM_addStyle ( "\
    * {\
       background-image: none !important;\
    }\
\
    img.gmImgHideHidden {\
       display: none !important;\
    }\
" );

var num = 0;

function gmImgHideShowImg(imgId, linkId)
{
    // Using plain JavaScript because the page itself may not have jquery
    var img = document.getElementById(imgId);
    img.className = img.className.replace( /(?:^|\s)gmImgHideHidden(?!\S)/g , '' );

    var lnk = document.getElementById(linkId);
    lnk.parentNode.removeChild(lnk);
}

// Exporting the "show image" function so that it can be used in the webpage
unsafeWindow.gmImgHideShowImg = exportFunction(gmImgHideShowImg, unsafeWindow);

waitForKeyElements ("img", hideImageExceptForAltText);

function hideImageExceptForAltText (jNode) {
    var imgId = jNode.attr("id");

    // Ensuring an id exists so the image can be searched for later
    if(typeof(imgId) == "undefined")
    {
        imgId = "gmImgHideImg" + num;
        jNode.attr("id", imgId);
    }

    var imgDisp = jNode.css("display");

    var imgAlt = jNode.attr("alt");
    jNode.addClass("gmImgHideHidden");

    var linkId = "gmImgHideLink" + num;

    var linkNode = $("<a></a>");
    linkNode.attr("id", linkId);
    linkNode.append("Image: " + imgAlt);
    linkNode.attr("onclick", "gmImgHideShowImg('" + imgId + "', '" + linkId + "'); return false;");

    jNode.parent().append(linkNode);

    num++;
}

变异观察者 https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver毫无疑问是这里最好的解决方案。结合早期注射@run-at document-start我们可以让脚本变得防弹。查看这把小提琴 http://jsfiddle.net/2qL845k9/19/(使用 Firefox 40 进行测试)以查看其实际效果。

我认为代码是非常不言自明的。我已经注释了其中的微妙之处,但如果有任何不明白的地方,请留下评论。

// ==UserScript==
// @run-at document-start
// ==/UserScript==
"use strict";

/* part one: <img> elements */

(new MutationObserver(function(Records, Obs) {
    for (let R of Records) {/* examine each mutation record: */
        /* if the record specifies an attribute mutation… */
        if (
            R.attributeName === "src" &&
            (R.target instanceof Element) && /* this check might be necessary */
            R.target.tagName.toLowerCase() === "img" &&
            R.target.getAttribute("src") !== "" /* avoid infinite loop */
        ) {
            R.target.setAttribute("src", "");
        };

        /* if the record specifies a sub-element mutation… */
        for (let N of R.addedNodes) {
            if (
                (N instanceof Element) && /* this check might be necessary */
                N.tagName.toLowerCase() === "img" &&
                N.getAttribute("src") !== "" /* avoid infinite loop */
            ) {
                N.setAttribute("src", "");
            };
        };
    };
})).observe(document, {
    /* changes wot we listen for */
    childList : true,
    subtree : true,
    attributes : true
});

/* part two: background-image styles */

let check_for_head_elem = function(_, Obs) {
    if (!document.head) {return;};
    Obs.disconnect();

    /* apply our style */
    let Style = document.createElement("style");
    document.head.appendChild(Style);
    Style.sheet.insertRule("* {background-image : none !important;}", 0);
};

let check_for_root_elem = function(_, Obs) {
    if (!document.documentElement) {return;};
    Obs.disconnect();

    /* observe until the <head> element is added */
    Obs = new MutationObserver(check_for_head_elem)
    Obs.observe(document.documentElement, {childList : true});
    check_for_head_elem(null, Obs); /* check here because it might exist already */
};

{/* observe until the <html> element is added */
    let Obs = new MutationObserver(check_for_root_elem);
    Obs.observe(document, {childList : true});
    check_for_root_elem(null, Obs); /* check here because it might exist already */
};

还有一些我没有考虑到的在页面上获取图像的其他方法(<iframe>, <svg>, <canvas>, <li>要点),但如果有必要,您也应该能够使用突变观察器或 CSS 来处理这些问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何让 GreaseMonkey 脚本在页面中的元素显示之前对其产生影响? 的相关文章

随机推荐