programing

코드 매개 변수를 실행하기 전에 페이지가 로드될 때까지 기다릴 사용자 스크립트?

stoneblock 2023. 8. 7. 22:17

코드 매개 변수를 실행하기 전에 페이지가 로드될 때까지 기다릴 사용자 스크립트?

나는 그리스몽키 사용자 스크립트를 작성하고 있으며, 페이지 로드가 완료되면 특정 코드가 실행되기를 원합니다. 왜냐하면 그것은 내가 표시하고 싶은 디바 카운트를 반환하기 때문입니다.

문제는 이 특정 페이지가 로드되기 전에 약간의 시간이 걸릴 수 있다는 것입니다.

노력해봤어, 문서$(function() { });그리고.$(window).load(function(){ });포장지하지만, 제가 잘못 적용했을 수도 있지만, 아무 것도 저에게 효과가 없는 것 같습니다.

제가 할 수 있는 최선은setTimeout(function() { }, 600);항상 신뢰할 수 있는 것은 아니지만 효과가 있습니다.

페이지 로드가 완료되었을 때 특정 코드가 실행되도록 보장하기 위해 그리스몽키에서 사용하는 가장 좋은 기술은 무엇입니까?

Greasmonkey(일반적으로)에는 jQuery가 없습니다.따라서 일반적인 접근 방식은

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

사용자 스크립트 내부

이것은 일반적인 문제이며, 당신이 말했듯이, 페이지 로드를 기다리는 것만으로는 충분하지 않습니다. 왜냐하면 AJAX는 그 이후에도 변경할 수 있고 변경할 수 있기 때문입니다.

이러한 상황에 대한 표준(ish) 강력한 유틸리티가 있습니다.유틸리티입니다.

다음과 같이 사용합니다.

// ==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.

    If in Tampermonkey, use "// @unwrap" to enable sandbox instead.
*/

waitForKeyElements ("YOUR_jQUERY_SELECTOR", actionFunction);

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

보다 구체적인 예를 들어 대상 페이지의 정확한 세부 정보를 제공합니다.

그리스몽키 3.6 (2015년 11월 20일) 기준 메타데이터 키@run-at새로운 가치를 지원합니다.document-idle이것을 그리스몽키 스크립트의 메타데이터 블록에 넣기만 하면 됩니다.

// @run-at      document-idle

설명서에서는 다음과 같이 설명합니다.

페이지가 로드되고 모든 리소스(이미지, 스타일시트 등)가 로드되고 페이지 스크립트가 실행된 후 스크립트가 실행됩니다.

브록의 대답은 좋지만, 저는 좀 더 현대적이고 우아한 AJAX 문제에 대한 또 다른 해결책을 제시하고 싶습니다.

그의 대본은 대부분의 다른 것들처럼, 또한 사용하기 때문에.setInterval()주기적으로 확인하기 위해(300ms), 즉시 응답할 수 없고 항상 지연이 발생합니다.또한 다른 솔루션에서는 동적 페이지에서 원하는 것보다 더 빨리 실행되는 온로드 이벤트를 사용합니다.

요소가 생성되는 즉시 DOM 변경 내용을 수신하고 응답하는 데 사용할 수 있습니다.

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

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

그 이후로check()모든 DOM 변경 사항에 대해 발생합니다. DOM이 매우 자주 변경되거나 상태를 평가하는 데 시간이 오래 걸리는 경우 관찰하는 대신 이는 느릴 수 있습니다.document가능한 한 작은 DOM 하위 트리를 관찰하여 범위를 제한합니다.

이 방법은 매우 일반적이며 많은 상황에 적용될 수 있습니다.여러 번 응답하려면 트리거될 때 관찰자의 연결을 끊지 마십시오.

다른 사용 사례는 특정 요소를 찾는 것이 아니라 페이지 변경이 중지되기만을 기다리는 경우 이 요소를 페이지에서 변경될 때마다 재설정되는 카운트다운과 결합할 수 있습니다.

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

// reset timer every time something changes
function resetTimer(changes, observer) {
    clearTimeout(timer);
    timer = setTimeout(action, 3000, observer);
}

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

이 방법은 매우 다양하여 속성 및 텍스트 변경 내용도 청취할 수 있습니다. 설하기정으로 설정하세요.attributes그리고.characterDatatrue

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

를 대을포기하장으로 $(window).load(function(){ })나에게 실패한 적이 없습니다.

페이지가 완료되었지만 일부 Ajax 콘텐츠가 로드되고 있습니다.

만약 그렇다면, 브록 아담스의 이 멋진 코드 조각은 당신을 도울 수 있습니다:
https://gist.github.com/raw/2625891/.jshttps ://gist.github.com/raw/2625891/waitForKeyElements.js

저는 보통 포스트백에 나타나는 요소를 모니터링하기 위해 그것을 사용합니다.

다음과 같이 사용합니다.waitForKeyElements("elementtowaitfor", functiontocall)

노드의 값을 가져오거나 스타일을 변경하는 등 노드를 조작하려면 이 기능을 사용하여 노드를 기다릴 수 있습니다.

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

여기 163_enhance의 예가 있습니다.

XHR이 웹 페이지에서 로드를 마쳤는지 감지한 다음 일부 기능을 트리거합니다.자바스크립트를 사용하여 "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
그리스 원숭이를 위한 샘플이 있습니다.같은 페이지에서 그리스 몽키 스크립트를 여러 번 실행하시겠습니까?

언급URL : https://stackoverflow.com/questions/12897446/userscript-to-wait-for-page-to-load-before-executing-code-techniques