Je travaille sur un script utilisateur et je viens de constater que le script n'est pas exécuté lorsque la page principale effectue des requêtes AJAX.
Existe-t-il un moyen de déclencher le script utilisateur à la fois lors du chargement de la page principale et lors des requêtes AJAX?
La méthode intelligente pour réexécuter le code du script sur les demandes AJAX consiste à se concentrer sur les éléments clés de la page et à vérifier les modifications.
Par exemple, supposons qu'une page contienne du code HTML comme suit:
<div id="userBlather">
<div class="comment"> Comment 1... </div>
<div class="comment"> Comment 2... </div>
...
</div>
et vous vouliez que le script fasse quelque chose avec chaque commentaire au moment de son entrée.
Maintenant, vous pouvez intercepter tous les appels AJAX, ou écoutez (obsolète), ou utilisez DOMSubtreeModified
MutationObserver
s, mais ces méthodes peuvent être compliquées, difficiles et trop compliquées.
Un moyen plus simple et plus robuste d’obtenir du contenu ajax sur une page sauvage consiste à interroger ce contenu à l’aide de la fonction waitForKeyElements
ci-dessous.
Par exemple, ce script mettra en évidence les commentaires contenant "bière", comme ils le sont dans AJAX:
// ==UserScript==
// @name _Refire on key Ajax changes
// @include http://YOUR_SITE.com/YOUR_PATH/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
// ==/UserScript==
function highlightGoodComments (jNode) {
//***** YOUR CODE HERE *****
if (/beer/i.test (jNode.text () ) ) {
jNode.css ("background", "yellow");
}
//...
}
waitForKeyElements ("#userBlather div.comment", highlightGoodComments);
/*--- waitForKeyElements(): A utility function, for Greasemonkey scripts,
that detects and handles AJAXed content.
IMPORTANT: This function requires your script to have loaded jQuery.
*/
function waitForKeyElements (
selectorTxt, /* Required: The jQuery selector string that
specifies the desired element(s).
*/
actionFunction, /* Required: The code to run when elements are
found. It is passed a jNode to the matched
element.
*/
bWaitOnce, /* Optional: If false, will continue to scan for
new elements even after the first match is
found.
*/
iframeSelector /* Optional: If set, identifies the iframe to
search.
*/
) {
var targetNodes, btargetsFound;
if (typeof iframeSelector == "undefined")
targetNodes = $(selectorTxt);
else
targetNodes = $(iframeSelector).contents ()
.find (selectorTxt);
if (targetNodes && targetNodes.length > 0) {
btargetsFound = true;
/*--- Found target node(s). Go through each and act if they
are new.
*/
targetNodes.each ( function () {
var jThis = $(this);
var alreadyFound = jThis.data ('alreadyFound') || false;
if (!alreadyFound) {
//--- Call the payload function.
var cancelFound = actionFunction (jThis);
if (cancelFound)
btargetsFound = false;
else
jThis.data ('alreadyFound', true);
}
} );
}
else {
btargetsFound = false;
}
//--- Get the timer-control variable for this selector.
var controlObj = waitForKeyElements.controlObj || {};
var controlKey = selectorTxt.replace (/[^\w]/g, "_");
var timeControl = controlObj [controlKey];
//--- Now set or clear the timer as appropriate.
if (btargetsFound && bWaitOnce && timeControl) {
//--- The only condition where we need to clear the timer.
clearInterval (timeControl);
delete controlObj [controlKey]
}
else {
//--- Set a timer, if needed.
if ( ! timeControl) {
timeControl = setInterval ( function () {
waitForKeyElements ( selectorTxt,
actionFunction,
bWaitOnce,
iframeSelector
);
},
300
);
controlObj [controlKey] = timeControl;
}
}
waitForKeyElements.controlObj = controlObj;
}
Pour plus de commodité, waitForKeyElements()
est maintenant hébergé sur GitHub .
Cette réponse montre un exemple d'utilisation de la fonction hébergée .
Un autre moyen - plus simple et plus petit mais moins flexible - consiste à utiliser un délai JavaScript pour attendre le chargement et la fin du AJAX/jQuery. Par exemple, si le code HTML suivant a été généré dynamiquement après le premier chargement:
<div id="userBlather">
<div class="comment"> Comment 1... </div>
<div class="comment"> Comment 2... </div>
...
</div>
Alors un script greasemonkey comme celui-ci pourrait le modifier:
// Wait 2 seconds for the jQuery/AJAX to finish and then modify the HTML DOM
window.setTimeout(updateHTML, 2000);
function updateHTML()
{
var comments = document.getElementsByClassName("comment");
for (i = 0; i < comments.length; i++)
{
comments[i].innerHTML = "Modified comment " + i;
}
}
Voir les conseils ici: Sommeil/Pause/Attendre javascript