Userscript等待页面执行代码技术之前加载?(Userscript to wait for p

2019-06-18 12:57发布

我正在写一个Greasemonkey的用户脚本,并希望具体的代码,当页面完全加载完成,因为它返回的我要显示一个div计数执行。

问题是,这个特殊的网页,有时需要多一点的一切加载之前。

我试过,文件$(function() { });$(window).load(function(){ }); 包装。 然而,没有人可以对我的工作,虽然我可能会运用他们错了。

最好的我所能做的是使用setTimeout(function() { }, 600); 它的工作原理,但它并不总是可靠的。

什么是Greasemonkey的使用,以确保当页面完成加载特定的代码将执行最好的技术?

Answer 1:

Greasemonkey的(通常)没有jQuery的。 因此,常用的方法是使用

window.addEventListener('load', function() {
    // your code here
}, false);

您userscript内



Answer 2:

这是一个常见的问题,正如你所说,等待页面加载是不够的 - 因为AJAX能够和长后,它改变的东西。

有这些情况标准(ISH)强大的工具。 这是该waitForKeyElements()工具 。

使用它像这样:

// ==UserScript==
// @name     _Wait for delayed or AJAX page load
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a major design
    change introduced in GM 1.0.
    It restores the sandbox.
*/

waitForKeyElements ("YOUR_jQUERY_SELECTOR", actionFunction);

function actionFunction (jNode) {
    //-- DO WHAT YOU WANT TO THE TARGETED ELEMENTS HERE.
    jNode.css ("background", "yellow"); // example
}

给你的目标页面的具体细节进行更具体的例子。



Answer 3:

随着Greasemonkey的3.6(2015年11月20日),元数据键的@run-at支持新的价值document-idle 。 简单地说这在你的Greasemonkey脚本的元数据块:

// @run-at      document-idle

该文档描述,如下所示:

页面,所有的资源(图片,样式表等)被加载和页面脚本运行后,将运行该脚本。



Answer 4:

我的包裹脚本$(window).load(function(){ })从来没有给我。

也许你的页面已经完成,但仍有加载一些Ajax的内容。

如果是这样的话,从这个漂亮的一段代码布鲁克·亚当斯可以帮助你:
https://gist.github.com/raw/2625891/waitForKeyElements.js

我通常用它来监控上回发出现的元素。

使用这样的: waitForKeyElements("elementtowaitfor", functiontocall)



Answer 5:

如果你想操作节点就像得到节点的值或者改变风格,你可以使用此功能等待这些节点

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()
})

然后用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
})

或者使用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
})()

下面是一个例子icourse163_enhance



Answer 6:

Brock的答案是好的,但我想提供另一种解决AJAX的问题,为了保持完整性。 由于他的脚本也可以使用setInterval()检查定期(300毫秒),它不能立即响应。

如果您需要立即作出反应,你可以使用MutationObserver()监听DOM改变,并将它们一旦创建了响应元素

(new MutationObserver(check)).observe(document, {childList: true, subtree: true});

function check(changes, observer) {
    if(document.querySelector('#mySelector')) {
        observer.disconnect();
        // code
    }
}

虽然自check()在每一个DOM变化触发,如果DOM的变化十分频繁或你的病情需要很长的时间来评估,这可能是缓慢的。

另一种使用情况是,如果你不找任何特定的元素,而只是等待页面内停止改变。 你可以用这个组合setTimeout()来等待了。

var observer = new MutationObserver(resetTimer);
var timer = setTimeout(action, 3000, observer); // wait for the page to stay still for 3 seconds
observer.observe(document, {childList: true, subtree: true});

function resetTimer(changes, observer) {
    clearTimeout(timer);
    timer = setTimeout(action, 3000, observer);
}

function action(o) {
    o.disconnect();
    // code
}

这种方法是如此多才多艺,你可以听的属性和文本也会改变。 刚刚成立attributescharacterDatatrue的选项

observer.observe(document, {childList: true, attributes: true, characterData: true, subtree: true});


Answer 7:

为了检测是否XHR完成了在网页加载然后触发一些功能。 我得到这个从我如何使用JavaScript来存储在Chrome中控制台“XHR加载完成”的消息? 它真正的作品。

    //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;
    }

但是,如果有在页面是许多XHR时,我不知道如何筛选确定一个XHR。

另一种方法是waitForKeyElements()这是很好的。 https://gist.github.com/BrockA/2625891
有样品Greasemonkey的使用。 运行在同一页上的Greasemonkey脚本,多次吗?



文章来源: Userscript to wait for page to load before executing code techniques?