Заменить jQuery-версию страницы с Greasemonkey - PullRequest
6 голосов
/ 09 октября 2011

Как я могу заменить jquery-версию страницы greasemonkey?

Я пытаюсь протестировать сайт с более новой версией jquery, но у меня нет среды разработки.

Ответы [ 3 ]

10 голосов
/ 09 октября 2011

Создание среды разработки, использование системы управления версиями и письменного контрольного списка выпуска избавит вас от горя (и является требованием для большинства оплачиваемых работ).
~~~ * * 1002

Лучший способ заменить версию jQuery на существующей странице (которую вы не контролируете):

  1. Остановить загрузку собственного jQuery страницы.
  2. Создайте <script> узел, содержащий нужную вам версию jQuery, которая загружает перед любыми последующими сценариями, использующими jQuery.

К сожалению, Greasemonkey не может сделать # 1. Он может вмешиваться только в собственный jQuery страницы после загрузки - подход, который может работать, но замедляет работу страницы и создает условия для гонки.

Итак, я рекомендую решение с двумя инструментами:

  1. Убедитесь, что ваш Firefox имеет дополнение Adblock (которое является отличным дополнением для использования независимо) и / или дополнение RequestPolicy .

  2. Используйте Adblock или RequestPolicy , чтобы временно заблокировать старый jQuery.
    Например, для StackOverflow, блок http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js. (Обратите внимание, что RequestPolicy позволяет ограничить блокировку URL только для определенного сайта.)

  3. Затем используйте Greasemonkey для загрузки нужной версии jQuery (что он может делать независимо от настроек Adblock или RequestPolicy ) в начале страницы.

    Например, этот скрипт обновит jQuery Meta SO до 1.6.2 вместе с блоком из шага 2:

    // ==UserScript==
    // @name            _upgrade jQuery
    // @include         http://meta.stackexchange.com/questions/*
    // @run-at          document-start
    // ==/UserScript==
    
    /*--- Important!
            (1) We need another add-on, besides Greasemonkey, to
                disable the old, undesired script.
            (2) The DOM is not available yet
                (@run-at == document-start).
            (3) We cannot use a loop to check for the DOM because
                loading is halted while the loop runs.
            (4) setTimeout() and setInterval() are not fast enough due
                to minimum interval clamping.  By the time they detect
                the DOM, scripts that we need to precede may have
                loaded.
            (5) Therefor, we use a "set Zero Timeout" function as
                explained by David Baron at
                    http://dbaron.org/log/20100309-faster-timeouts .
            (6) By the time FF reports that the `document.head` is
                available, several head elements have loaded!
                (Is this a bug?)
                That means that if any dependent scripts are loaded
                before we can inject our jQuery version, then we must
                also reload those dependent scripts.
    */
    
    //////  setZeroTimeout() implementation: BEGIN
    
    /*--- Only add setZeroTimeout to the window object, and hide
        everything else in a closure.
    */
    ( function () {
        var timeouts    = [];
        var messageName = "zero-timeout-message";
    
        /*--- Like setTimeout, but only takes a function argument.
            There's no time argument (always zero) and no arguments.
            You have to use a closure.
        */
        function setZeroTimeout(fn) {
            timeouts.push(fn);
            window.postMessage(messageName, "*");
        }
    
        function handleMessage(event) {
            if (event.source == window && event.data == messageName) {
                event.stopPropagation();
                if (timeouts.length > 0) {
                    var fn = timeouts.shift();
                    fn();
                }
            }
        }
    
        window.addEventListener ("message", handleMessage, true);
    
        // Add the one thing we want added to the window object.
        window.setZeroTimeout = setZeroTimeout;
    })();
    
    //////  setZeroTimeout() implementation: END
    
    /*--- Now wait for the DOM and then add our version of jQuery,
        first thing.
    */
    function SearchForDOM () {
    
        var targetNode;
        if (typeof document.head == "undefined")
            targetNode = document.querySelector ("head, body");
        else
            targetNode = document.head;
        if (targetNode) {
    
            var scriptNode      = document.createElement ("script");
            scriptNode.src      = 'http://ajax.googleapis.com/ajax/'
                                + 'libs/jquery/1.6.2/jquery.min.js';
            targetNode.appendChild (scriptNode);
    
            /*--- By the time FF reports that the head element is
                available, a key dependent script has loaded!
                So, we reload it here, so that it can run with jQuery
                available.
            */
            var scriptNode      = document.createElement ("script");
            scriptNode.src      = location.protocol
                                + '\/\/' + location.host
                                + '/content/js/stub.js?v=49f661361016';
            targetNode.appendChild (scriptNode);
        }
        else
            setZeroTimeout (SearchForDOM);
    }
    
    SearchForDOM ();
    


    Обратите внимание: из-за ограничений JS, GM и Firefox может потребоваться перезагрузка скриптов, которые также зависят от jQuery. (В данный момент это относится к переполнению стека мета).

5 голосов
/ 09 октября 2011

Я знаю, что вы спрашиваете о jQuery и Greasemonkey для этого, но позвольте мне исключить полностью другую альтернативу, Fiddler .

Если вы тестируете сайт с новой версией jQuery, и вы на самом деле хотите протестировать любые критические изменения и т. Д. ... вы хотите протестировать сайт , как он будет , тогда как замена на основе JavaScript (greasemonkey) не является точной симуляцией.

С помощью fiddler вы можете заменить файл jQuery , который браузер запрашивает (без ведома браузера). Таким образом, вы на самом деле полностью его тестируете, вы без промедления сбрасываете новую версию на странице, нет никаких внутристраничных трюков JS, которые могут оказаться не совсем точными (обработчики уже подключены, порядок загрузки и т. Д.). )

Эрик Лоу (создатель Fiddler) имеет отличный пост в блоге о том, как сделать точно это:

Обмен JQuery с Fiddler

Пост был написан для замены минифицированной версии полной версией (также удобной!) или более новой версией для отладки, не забудьте отметить оба варианта использования ... они оба очень полезно для экономии времени отладки / тестирования.

0 голосов
/ 27 августа 2017

То, что не сработало для моего случая, похоже, подходит для этого вопроса, блокировщик не требуется. В GreaseMonkey:

// ==UserScript==
// @name        alternative jquery
// @namespace   ben@host
// @description intercept
// @include     https://somehost.com/*
// @grant       GM_getResourceText
// @resource    jquery_new jquery_new.js
// @run-at      document-start
// @version     1
// ==/UserScript==

var jquery_source = GM_getResourceText( 'jquery_new' );
console.log('jQuery Lenght =',jquery_source.length);

window.addEventListener('beforescriptexecute',  
function(e){
    if (e.target.src &&
        e.target.src.search('/1.12.4/jquery.min.js') >= 0 ) {
            console.log('intercepted: '+e.target.src);
            e.preventDefault();
            e.stopPropagation();
            window.eval(jquery_source);
        }
});

Примечание: обратная сторона - beforescriptexecute срабатывает после того, как оригинальный скрипт извлечен и готов к выполнению, поэтому, если исходный внешний файл js не удалось загрузить, этот подход не будет работать.

...