[英]how to run greasemonkey script before the page content is displayed?
[英]How to make a GreaseMonkey script affect elements in a page before they're displayed?
我正在嘗試確保不顯示某個網站中的圖像,但仍會顯示替代文字。 最初我嘗試使用Stylish(使用Firefox)完成此操作並詢問以下問題:
接受的答案為我提供了使用Greasemonkey的替代解決方案。 該腳本使用waitForKeyElements隱藏圖像,即使它們是使用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++;
}
MutationObserver毫無疑問是這里最好的解決方案。 結合@run-at document-start
早期注入,我們可以使腳本非常防彈。 看看這個小提琴 (用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也照顧這些。
一個簡單,健壯的方法是在頁面的任何其他頁面加載之前設置CSS first-thing。
@run-at document-start
和GM_addStyle()
執行此操作。 (在Firefox上;未在最新的Tampermonkey上測試)
這樣,圖像即使在幾分之一秒內也不會顯示,就像它們使用原始代碼或復雜,挑剔的MutationObserver
方法一樣。
這個完整的腳本顯示了該過程:
// ==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
// @run-at document-start
// ==/UserScript==
GM_addStyle ( " \
* { \
background-image: none !important; \
} \
img { \
display: none !important; \
} \
" );
/*--- $(document).ready() is not always needed for modern Firefox, but
use for maximum portability, when script runs at document-start.
*/
$(document).ready ( function () {
waitForKeyElements ("img", hideImageExceptForAltText);
} );
function hideImageExceptForAltText (jNode) {
var imgAlt = jNode.attr("alt") || "";
var imgTitle = jNode.attr("title") || "";
jNode.after ('<span title="' + imgTitle + '">' + imgAlt + '</span>');
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.