【问题标题】:I have to refresh the page for my Greasemonkey script to run?我必须刷新页面才能运行 Greasemonkey 脚本?
【发布时间】:2012-12-25 04:13:23
【问题描述】:

所以我知道这与 AJAX 有关,但我已经阅读了一些主题并且不太明白我必须做什么。目前一切正常,但我必须刷新页面才能运行我的脚本。需要对我的代码执行什么操作才能使其在不刷新的情况下正常工作?

// ==UserScript==
// @name    Job Aids
// @description Aid in closing tickets
// @include https://techaccess.ad.qintra.com/WorkJobs/WorkJobs.aspx*
// @namespace   camzilla.net
// @version     1.1.20121128
// ==/UserScript==

var url  = window.location.href.split(".aspx");
var page = url[1].toLowerCase();

if (page == "#finaltest") {
    window.addEventListener ("load", finalResults, false);
} else if (page == "#threetoneslope") {
    window.addEventListener ("load", toneSlopeResults, false);
} else if (page == "#codes") {
    window.addEventListener ("load", closingComments, false);
} else if (page == "#cras") {
    window.addEventListener ("load", crasResults, false);
} else if (page == "#jobinfo") {
    window.addEventListener ("load", addLinks, false);
} else if (page == "") {
    if (getCookie("updater") == null) {
        var d = new Date();

        setCookie("updater", d.getTime(), 1);
        try {
            updateCheck();
        } catch(err) {
            // alert('Update checking failed');
        }
    }

    // setTimeout(promptDispatch, 1000);
}

function addLinks() {
    var mydiv   = document.querySelector('div[data-bind="CurrentJob.addr"]');
    var address = 'https://maps.google.com/maps?q=' + mydiv.textContent + ", UT";
    address.replace(/ /g, '+');  
    var a       = document.createElement("a");
    var txt     = document.createTextNode(mydiv.textContent);
    mydiv.textContent = "";
    a.appendChild(txt);
    a.href   = address;
    a.target = '_blank';
    mydiv.appendChild(a);

    mydiv   = document.querySelector('div[data-bind="CurrentJob.cktid"]');
    address = 'http://acmspjv1.interprise.com/cgi-bin/QC/DSL/dslam6100Int.pl?telephoneNum=';
    address+= mydiv.textContent;
    a       = document.createElement("a");
    txt     = document.createTextNode(mydiv.textContent);
    mydiv.textContent = "";
    a.appendChild(txt);
    a.href   = address;
    a.target = '_blank';
    mydiv.appendChild(a);
}

function updateCheck() {
    try {
        GM_xmlhttpRequest(
        {
            method: 'GET',
            url: 'http://camzilla.net/downloads/jobAids.user.js?v' + getCookie("updater"),
            headers: {'Cache-Control': 'no-cache'},
            onload: function(resp) {
                var local_version, remote_version, rt, script_name;

                rt = resp.responseText;
                remote_version = (/@version\s*(.*?)\s*$/m.exec(rt)[1]);
                local_version  = GM_info.script.version;

                if (remote_version != local_version) {

                    if(confirm(GM_info.script.name+' update v'+remote_version+ ' is available.\nWould you like to install it now?')) {
                        GM_openInTab('http://camzilla.net/downloads/jobAids.user.js');
                    } else {
                        alert('You will be reminded again tomorrow');
                    }
                }
            }
        });
    } catch(err) {
        // do something here
    }
}

function setCookie(c_name, value, exdays) {
    var exdate=new Date();
    exdate.setDate(exdate.getDate() + exdays);
    var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
    document.cookie=c_name + "=" + c_value;
}

function getCookie(c_name) {
    var i,x,y,ARRcookies=document.cookie.split(";");

    for (i=0;i<ARRcookies.length;i++) {

        x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
        y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
        x=x.replace(/^\s+|\s+$/g,"");

        if (x==c_name) {
            return unescape(y);
        }
    }

    return null;
}

function finalResults() {
    var dc, current, loss, noise, pi, lb;

    dc      = getRandom(51, 49, 2);   
    current = getRandom(37, 29, 2);
    loss    = getRandom(7, 2, 2);
    noise   = getRandom(7, 1, 2);
    pi      = getRandom(67, 60, 2);
    lb      = getRandom(79, 70, 2);

    document.getElementById('finalTestInsightNo').click();

    document.getElementById("finalTestBeforeAcTg").value        = "0.00";
    document.getElementById("finalTestBeforeAcRg").value        = "0.00";
    document.getElementById("finalTestBeforeAcTr").value        = "0.00";
    document.getElementById("finalTestBeforeDcTr").value        = dc;
    document.getElementById("finalTestBeforeDcTg").value        = "0.00";
    document.getElementById("finalTestBeforeDcRg").value        = dc;
    document.getElementById("finalTestBeforeLoopCurrent").value = current;
    document.getElementById("finalTestAfterLoss").value         = loss;
    document.getElementById("finalTestAfterNoise").value        = noise;
    document.getElementById("finalTestAfterPi").value           = pi;
    document.getElementById("finalTestAfterLb").value           = lb;

    document.getElementById("finalTestAfterLb").focus();
    window.scrollTo(0, document.body.scrollHeight-250);

    // Store cookies to be used on cras page if needed
    setCookie("loss", loss, 1);
    setCookie("pi", pi, 1);
    setCookie("current", current, 1);
    setCookie("noise", noise, 1);
    setCookie("lb", lb, 1);
}

function crasResults() {
    document.getElementById("crasCircuitLoss").value    = getCookie("loss");
    document.getElementById("crasPowerInfluence").value = getCookie("pi");
    document.getElementById("crasLineCurrent").value    = getCookie("current");
    document.getElementById("crasCircuitNoise").value   = getCookie("noise");
    document.getElementById("crasBalance").value        = getCookie("lb");

    document.getElementById('crasFoundInF2').click();
}

function toneSlopeResults() {
    var dc = getRandom(51, 49, 2);   

    document.getElementById("ToneSlopeInsightNo").click();
    document.getElementById("ToneSlopeDmarcTaggedYes").click();
    document.getElementById("ToneSlopeClecDtPresentYes").click();

    document.getElementById("ToneSlopeBeforeDcTr").value    = dc;
    document.getElementById("ToneSlopeBeforeDcTg").value    = "0.00";
    document.getElementById("ToneSlopeBeforeDcRg").value    = dc;   
    document.getElementById("ToneSlopeRingbackTr").value    = getRandom(90,85,2);
    document.getElementById("ToneSlopeAfterResistTg").value = getRandom(998,20,0);
    document.getElementById("ToneSlopeAfterResistRg").value = getRandom(998,20,0);
    document.getElementById("ToneSlopeAfterResistTr").value = getRandom(998,20,0);

    document.getElementById("ToneSlopeAfter404").value      = "0.00";
    document.getElementById("ToneSlopeAfter1004").value     = getRandom(7, 3, 2);
    document.getElementById("ToneSlopeAfter2804").value     = "0.00";
    document.getElementById("ToneSlopeAfterNoise").value    = getRandom(7, 1, 2);
    document.getElementById("ToneSlopeAfterLb").value       = getRandom(79, 70, 2);
    document.getElementById("ToneSlopeCotName").value       = "NA";

    document.getElementById("ToneSlopeTn").focus();
}

function closingComments() {
    document.getElementById("flatRateJacks").value = "0";
    document.getElementById("rewiredJacks").value  = "0";

    document.getElementById("tripNo").click();
    document.getElementById("marketMass").click();
    document.getElementById("custTypeRes").click();
    document.getElementById("pairChangeNo").click();
    document.getElementById("tempDropNo").click();
    document.getElementById("goodCbrYes").click();

    document.getElementById("jobCloseComments").focus();
    window.scrollTo(0, 5000);
}

function getRandom(max, min, tenths) {
    var result = min + (Math.random() * (max - min + 1));
    return result.toFixed(tenths);
}

【问题讨论】:

    标签: javascript greasemonkey


    【解决方案1】:

    有关更多信息和类似情况,请参阅"addEventListener only working at page refresh?"

    您的脚本所期望的页面元素无疑会在load 事件触发后出现。此外,从您的 cmets 看来,页面的整个部分都被 AJAX 换掉了,但 AJAX 足够礼貌,可以更改 URL 哈希。这意味着您需要触发 hashchange 事件。

    在这种情况下不要使用addEventListener ("load"...。将the waitForKeyElements() utilityhashchange 结合使用。

    无需重构整个脚本以使用 jQuery(这将提供更清晰和更健壮的代码),将 function addLinks() {... 之前的所有内容替换为:

    // ==UserScript==
    // @name        Job Aids
    // @description Aid in closing tickets
    // @include     https://techaccess.ad.qintra.com/WorkJobs/WorkJobs.aspx*
    // @namespace   camzilla.net
    // @version     1.1.20121128
    // @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 design change
        introduced in GM 1.0.   It restores the sandbox.
    */
    
    //-- Pages are "loaded" via AJAX...
    window.addEventListener ("hashchange", fireOnNewPage,  false);
    
    waitForKeyElements ("#crasCircuitLoss",                 crasResults);
    waitForKeyElements ("#finalTestInsightNo",              finalResults);
    waitForKeyElements ("#flatRateJacks",                   closingComments);
    waitForKeyElements ("#ToneSlopeInsightNo",              toneSlopeResults);
    waitForKeyElements ("div[data-bind="CurrentJob.addr"]", addLinks);
    
    function fireOnNewPage () {
        switch (location.hash.toLowerCase() ) {
            case "#finaltest":
            case "#threetoneslope":
            case "#codes":
            case "#cras":
            case "#jobinfo":
                //-- No action needed, waitForKeyElements() handles this.
            break;
            default:
                if (getCookie("updater") == null) {
                    var d = new Date();
    
                    setCookie("updater", d.getTime(), 1);
                    try {
                        updateCheck();
                    } catch(err) {
                        // alert('Update checking failed');
                    }
                }
            break;
        }
    }
    fireOnNewPage ();   //-- Initial run on initial, full page load.
    

    【讨论】:

    • 我发布了整个脚本。我没有意识到你会需要所有这些。由于我是业余爱好者,为了避免混淆,您能否更新您的代码以准确显示我将如何使用它?
    • 好的,更新了答案。关键是选择合适的选择器。没有将脚本的其余部分移植到 jQuery,因为对于这个问题来说工作量太大而且超出了范围。但它应该与新的前端部分一起工作得更好。 (不能保证整个脚本;它使用了大量元素,但没有保护它们何时不存在。)
    • 还是要刷新每一页。在此处发布了 html pastebin.com/6KkKqC0C 当您单击以某种方式链接到它的按钮时,所有这些附加页面都会加载。
    • 我最终在其中放置了一个间隔,以每 1/3 秒检查一次我的页面并相应地运行代码。它有效,但假设还有更好的方法。
    • 查看更新后的答案。从您的 cmets 看来,该页面似乎正在通过 AJAX 进行重大交换,但对更新哈希很有礼貌。
    【解决方案2】:

    通过搜索查看网上的一些 ajax 示例。例如:http://www.w3schools.com/ajax/ajax_examples.asp

    AJAX,或 (A)synchronous (J)avascript (A)nd (X)ML(有趣的是,如今更倾向于使用 JSON),是一种 Javascript 使用浏览器对象与远程通信的系统服务器。这样做的一般用例是能够更新客户端的界面而无需转到另一个页面。不过,在我们开始之前,请注意几句。

    不建议将 Ajax 用于登录身份验证和发布表单 用户可以关闭 Javascript,或者由于 IT 政策可能会限制运行 Javascript

    考虑到这一点,建议您不要将 AJAX 用作关键用户功能的唯一解决方案!总是有一个后备! 注意:此社区 wiki 帖子使用 JQuery 来显示示例 AJAX 调用。推荐给新手,因为它隐藏了进行 AJAX 调用的浏览器兼容性问题。有关 JQuery 的更多信息,请查看 JQuery 网站。

    注意:示例使用与 PHP 服务器的通信,但任何服务器端语言都可以使用。

    AJAX 回调

    function makeAjaxCall() {
      $.ajax({
        url: 'ajax/test.html',
        success: function(data) {
          alert('Horray the AJAX call succeeded!');
        },
        error: function(xhr, error) {
          alert('Holy errors batman!');
        }
      });
    }
    

    AJAX 调用的性质

    AJAX 调用可以是异步的或同步的。异步意味着浏览器将发出 AJAX 请求并继续做其他事情。同步意味着浏览器将停止它正在执行的操作,直到 AJAX 调用完成。这是两个代码方面差异的示例:

    // An asynchronous call
    // This is the default
    $.ajax({
      url: '/server.php',
      success: function(data) {
        alert('Horray the AJAX call succeeded!');
      },
      error: function(xhr, error) {
        alert('Holy errors batman!');
      }
    });
    // This will get called right away
    myFunction();
    Now for a synchronous call:
    
    // A synchronous call
    $.ajax({
      url: '/server.php',
      async: false, // set the property here
      success: function(data) {
        alert('Horray the AJAX call succeeded!');
      },
      error: function(xhr, error) {
        alert('Holy errors batman!');
      }
    });
    

    【讨论】:

    • 这似乎不适用于这个问题。请记住,这是一个 Greasemonkey 上下文,因此用户无法控制目标页面。而且,他的脚本本身似乎并没有做 AJAX。
    猜你喜欢
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    相关资源
    最近更新 更多