简体   繁体   中英

Why is my ajaxSuccess jQuery event not being fired in Greasemonkey?

I have a basic greasemonkey script shown below, in which I want to run some code every time an AJAX request is sent by the website I'm running the script on.

I'm using the ajaxSuccess jQuery handler and it's not being fired. I suspect this might be because the AJAX requests are being sent with the global flag set to false (see http://docs.jquery.com/Ajax_Events ). Is there some better way to achieve this that will work even when global is set to false?

Code:

// ==UserScript==
// @name           MyTestScript
// @require        http://code.jquery.com/jquery-1.7.1.min.js
// @namespace      NRA
// @include        http://www.mysamplewebsite.com/view/*
// ==/UserScript==

$(document).ajaxSuccess(function(e, xhr) {
    alert("ajax success hit!");
    // I will do my other handling here
});

Thanks

The jQuery in your userscript runs in a separate environment from the page's jQuery .

You need to intercept the page's AJAX calls so you can use either (A) unsafeWindow or (B) Inject your script.

(A) unsafeWindow looks like:

unsafeWindow.$(document).ajaxSuccess(function(e, xhr) {
    alert("ajax success hit!");
    // I will do my other handling here
});


(B) Script injection looks like:

function scriptWrapper () {

    //--- Intercept Ajax
    $('body').ajaxSuccess (
        function (event, requestData) {
            alert ("ajax success hit!");
            doStuffWithAjax (requestData);
        }
    );

    function doStuffWithAjax (requestData) {
        console.log ('doStuffWithAjax: ', requestData.responseText);
    }

    //--- DO YOUR OTHER STUFF HERE.
    console.log ('Doing stuff outside Ajax.');
}

function addJS_Node (text, s_URL, funcToRun) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ    = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}

addJS_Node (null, null, scriptWrapper);


Note that in both cases, you must be conscious that data does not flow from page scope back to GM scope easily -- be careful about mixing the two .

One workaround, for transmitting data across the sandbox, can be found in this answer .

It could have something to do with the greasemonkey sandboxing.

http://greasemonkey.mozdev.org/authoring.html

Sometimes, you will want to access the global variables in the content document. For example, maybe the content document defines a function which you want to call. In these cases, you can access the content document's global scope with the unsafeWindow variable. Just be aware that accessing the members of this variable means that content scripts can detect your script and potentially interfere with it if they choose.

Ie document in the greasemonkey script may not be the same as document in the actual web page, so you might have to use unsafeWindow.document or something.

Or maybe jQuery's ajax methods simply don't work in greasemonkey without alteration (requiring special override of XHR objects)...

Eg http://www.monperrus.net/martin/greasemonkey+jquery+and+xmlhttprequest+together

and http://ryangreenberg.com/archives/2010/03/greasemonkey_jquery.php

... JQuery AJAX in Greasemonkey then looks like:

$.ajax({
  url: '/p/',// this even works for cross-domain requests by default
  xhr: function(){return new GM_XHR();},
  type: 'POST',
  success: function(val){
  .... 
  }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM