2013-09-28 4 views
0

Существует веб-сайт, который я использую, написанный на каком-то могучем отличном javascript. Вряд ли какие-либо глобальные блоки, замыкания повсюду, и он использует строгий режим. Это делает его очень трудно внедрить мои собственные функции на сайт.Как заменить, удалить или перехватить событие jQuery из сценария Greasemonkey?

Веб-сайт клиента объекты инициализируются в jQuery.ready() вызова:

$(window).ready(function() { 
    var a, b, c, d; 

    // Setup global data [...] 
    // Setup configuration [...] 

    a = GlobalFoo.ConstructorA(); 
    b = GlobalFoo.ConstructorB(a); 
    // Really wish I could put stuff here 
    c = GlobalFoo.ConstructorC(a, b); 
    d = GlobalFoo.ConstructorD(b, c); 
    // etc. 
}); 

Как можно, например, заменить b.someMethod() с моим собственным кодом, прежде чем другие конструкторы называются?

Могу ли я остановить событие готовности или заменить его собственным кодом? Поскольку он довольно мал, я могу просто дублировать модифицированную версию в своем коде.

+0

возможного дубликата [Изменения Javascript на HTML странице вне моего контроля] (HTTP: // StackOverflow. com/questions/10472569/change-javascript-on-html-page-out-of-my-control) –

ответ

2

После немного больше поиска я нашел this wonderful page от dindog. Существует также this page в wiki GreaseSpot, описывающих @run-at.

@run-at позволяет выполнять регистрацию пользователя перед любым другим кодом. Событие beforescriptexecute позволяет вам проверять каждый скрипт перед его выполнением. Затем вы можете пропустить или изменить его.

Мое окончательное решение:

// ==UserScript== 
// @name  ... 
// @description ... 
// @namespace ... 
// @include  ... 
// @version  1 
// @run-at  document-start 
// @grant  none 
// ==/UserScript== 

(function (w) { 
    // Remove the current jQuery ready code 
    function pre_script_execute_handler (e) { 
     var target = e.target; 
     if (target.innerHTML.indexOf("$(window).ready(") != -1) { 
      console.log('Removed ready'); 
      e.preventDefault(); 
      e.stopPropagation(); 
      addReady(); 
     } 
    } 
    w.addEventListener('beforescriptexecute', pre_script_execute_handler); 

    // Add new jQuery ready code 
    function addReady() { 
     console.log('Adding new ready'); 
     w.$(window).ready(function() { 
      console.log('Our ready called'); 
     }); 
    } 


}) (unsafeWindow); 
+0

@BrockAdams Я искал SO и Google, но не заметил этого сообщения. Возможно, я проигнорировал это из-за очень неопределенного вопроса. Я бы не сказал, что сообщение dindog происходит из вашего сообщения SO, поскольку структура кода выглядит совсем по-другому. – Annan

+0

Я не сказал, что его сообщение было получено от моего. Но из другой информации о SO. Но, поскольку я не могу это доказать, я отказываюсь от своего заявления. –

0

В общем, хирургически отключить или изменить JavaScript разметке страницы, используйте checkForBadJavascripts, как показано на "How to alter this javascript with Greasemonkey?". (.. Обратите внимание, что это только Firefox Там до сих пор нет хорошего способа сделать это в Chrome)

В этом случае ваш сценарий будет что-то вроде:

// ==UserScript== 
// @name  _Replace page's ready function 
// @include http://YOUR_SERVER.COM/YOUR_PATH/* 
// @require https://gist.github.com/raw/2620135/checkForBadJavascripts.js 
// @run-at document-start 
// @grant GM_addStyle 
// ==/UserScript== 
/*- The @grant directive is needed to work around a design change 
    introduced in GM 1.0. It restores the sandbox. 
*/ 
console.log ("Script run"); 
checkForBadJavascripts ([ 
    [ false, 
     /\$\(window\)\.ready\b/, 
     function() { addJS_Node (null, null, addBetterReady); } 
    ] 
]); 

function addBetterReady() { 
    //-- The space before "ready" is CRUCIAL to avoid recursion. 
    $(window). ready (function() { 
     // YOUR READY CODE HERE. 
    }); 
} 


... Если предположить, рядный JavaScript.

Если функция ready находится во внешнем файле, измените checkForBadJavascripts вызов на что-то вроде:

checkForBadJavascripts ([ 
    [ true, 
     /unwantedFilename\.js/, 
     function() { addJS_Node (null, null, addBetterReady); } 
    ] 
]); 
Смежные вопросы