137 votes

Le script utilisateur doit attendre le chargement de la page avant d'exécuter le code technique ?

J'écris un utilisateur Greasemonkey script, et je veux que le code spécifique s'exécute lorsque la page finit complètement de se charger, car il renvoie un compte div que je veux afficher.

Le problème est que cette page particulière prend parfois un peu de temps avant que tout ne se charge.

J'ai essayé, document $(function() { }); y $(window).load(function(){ }); enveloppes. Cependant, aucun d'entre eux ne semble fonctionner pour moi, même si je les applique peut-être mal.

Le mieux que je puisse faire est d'utiliser un setTimeout(function() { }, 600); qui fonctionne, même si elle n'est pas toujours fiable.

Quelle est la meilleure technique à utiliser dans Greasemonkey pour s'assurer que le code spécifique sera exécuté à la fin du chargement de la page ?

9voto

bilabila Points 331

Si vous voulez manipuler les noeuds, comme obtenir la valeur des noeuds ou changer le style, vous pouvez attendre ces noeuds en utilisant cette fonction.

const waitFor = (...selectors) => new Promise(resolve => {
    const delay = 500
    const f = () => {
        const elements = selectors.map(selector => document.querySelector(selector))
        if (elements.every(element => element != null)) {
            resolve(elements)
        } else {
            setTimeout(f, delay)
        }
    }
    f()
})

puis utiliser promise.then

// scripts don't manipulate nodes
waitFor('video', 'div.sbg', 'div.bbg').then(([video, loading, videoPanel])=>{
    console.log(video, loading, videoPanel)
    // scripts may manipulate these nodes
})

ou utiliser async&await

//this semicolon is needed if none at end of previous line
;(async () => {
    // scripts don't manipulate nodes
    const [video, loading, videoPanel] = await waitFor('video','div.sbg','div.bbg')
    console.log(video, loading, video)
    // scripts may manipulate these nodes
})()

Voici un exemple icourse163_enhance

3voto

Dave B Points 41

Pour détecter si le XHR a fini de se charger dans la page Web, il déclenche une fonction. J'obtiens ceci de Comment utiliser JavaScript pour enregistrer les messages "XHR finished loading" dans la console de Chrome ? et ça marche vraiment.

    //This overwrites every XHR object's open method with a new function that adds load and error listeners to the XHR request. When the request completes or errors out, the functions have access to the method and url variables that were used with the open method.
    //You can do something more useful with method and url than simply passing them into console.log if you wish.
    //https://stackoverflow.com/questions/43282885/how-do-i-use-javascript-to-store-xhr-finished-loading-messages-in-the-console
    (function() {
        var origOpen = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function(method, url) {
            this.addEventListener('load', function() {
                console.log('XHR finished loading', method, url);
                display();
            });

            this.addEventListener('error', function() {
                console.log('XHR errored out', method, url);
            });
            origOpen.apply(this, arguments);
        };
    })();
    function display(){
        //codes to do something;
    }

Mais s'il y a plusieurs XHR dans la page, je ne sais pas comment filtrer le XHR défini.

Une autre méthode, waitForKeyElements(), est intéressante. https://gist.github.com/BrockA/2625891
Il y a un échantillon pour l'utilisation de Greasemonkey. Exécuter Greasemonkey script sur la même page, plusieurs fois ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X