2011-10-09 34 views

Trả lời

5

Tôi biết bạn đang hỏi về jQuery và Greasemonkey để làm điều này, nhưng hãy để tôi ra một hoàn toàn thay thế khác nhau, Fiddler.

Nếu bạn đang thử nghiệm một trang web với phiên bản mới của jQuery và bạn thực sự là muốn kiểm tra bất kỳ thay đổi đột phá nào, v.v ...bạn muốn kiểm tra trang web vì nó sẽ là, trong khi một thay thế sau khi thực tế dựa trên JavaScript (mỡ) không phải là mô phỏng chính xác.

Với trình phát, bạn có thể thay thế tệp jQuery mà trình duyệt yêu cầu (không có trình duyệt biết). Bằng cách này bạn đang thực sự thử nghiệm nó hoàn toàn, bạn đang thẳng lên thả các phiên bản mới trong trang, không có thủ thuật JS trong trang mà có thể không được ở tất cả chính xác để đạt được điều đó (xử lý đã được nối, tải thứ tự, vv)

Eric Law (tác giả của Fiddler) có một bài đăng blog tuyệt vời về cách làm chính xác này:

Swapping out JQuery with Fiddler

các bài được viết để bơm nạp tiếp ra phiên bản rút gọn với phiên bản đầy đủ (cũng tiện dụng!) hoặc phiên bản mới hơn để gỡ lỗi, hãy nhớ lưu ý cả hai cách sử dụng ... chúng đều là rất hữu ích trong việc tiết kiệm thời gian gỡ lỗi/thử nghiệm.

10

Làm môi trường phát triển, sử dụng kiểm soát nguồn và danh sách kiểm tra bản phát hành sẽ giúp bạn tiết kiệm nhiều đau buồn (và là yêu cầu đối với hầu hết công việc được trả tiền).
~~~

Cách tốt nhất để thay thế phiên bản jQuery trên một trang đã có sẵn (mà bạn không kiểm soát) là:

  1. Dừng của trang có nguồn gốc từ jQuery tải.
  2. Tạo nút <script>, chứa phiên bản jQuery bạn muốn, tải trước bất kỳ tập lệnh tiếp theo nào sử dụng jQuery.

Thật không may, Greasemonkey không thể thực hiện # 1. Nó chỉ có thể giả mạo với bản gốc của trang jQuery sau khi nó đã tải - Một phương pháp có thể hoạt động, nhưng điều đó làm chậm trang và rủi ro điều kiện chủng tộc.

Vì vậy, tôi khuyên bạn nên một giải pháp hai công cụ:

  1. Hãy chắc chắn rằng Firefox của bạn có the Adblock add-on (đó là một add-on tuyệt vời để sử dụng bất kể) và/hoặc the RequestPolicy add-on.

  2. Sử dụng Adblock hoặc RequestPolicy để tạm thời chặn jQuery cũ. Ví dụ: đối với StackOverflow, chặn http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js. (Lưu ý rằng RequestPolicy phép bạn giới hạn URL chặn để chỉ một trang web cụ thể.)

  3. Sau đó sử dụng Greasemonkey để tải phiên bản mong muốn của jQuery (mà nó có thể làm bất kể của Adblock hoặc RequestPolicy cài đặt) ở đầu trang.

    Ví dụ, kịch bản này sẽ nâng cấp jQuery Meta SO để 1.6.2, kết hợp với khối từ bước 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(); 
    


    Lưu ý: đó là do những hạn chế của JS, GM, và Firefox , có thể cần phải tải lại các tập lệnh phụ thuộc vào jQuery. (Đây là trường hợp cho Meta Stack Overflow, vào lúc này.)

+0

Hóa ra tôi đang cố gắng làm điều tương tự! Tôi đang cố gắng tải lại SO trong FF56, kể từ khi Google CDN là ngưỡng 0 tốc độ. Tôi sử dụng uMatrix để chặn nó. Trên tài liệu đã sẵn sàng, hãy quét các nút tập lệnh thành hàng đợi, đảo ngược và nối thêm mọi tập lệnh vào đầu bắt đầu từ jquery. Trước đó, tôi đã thử chạy @ document-start và event beforescriptexecute để chặn, cuộn tải trang. Bây giờ m cố gắng theo cách của bạn với window.eval(). nó hoạt động hoàn hảo. Vì thế. chỉ để nói lời cảm ơn vì mẹo 0timout. – Ben

0

Điều gì không hiệu quả đối với trường hợp của tôi, dường như phù hợp với câu hỏi này, không yêu cầu chặn. Trong GreaseMonkey:

// ==UserScript== 
// @name  alternative jquery 
// @namespace [email protected] 
// @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); 
     } 
}); 

Lưu ý: Nhược điểm - beforescriptexecute cháy sau khi kịch bản gốc được lấy ra và sẵn sàng để được thực thi, vì vậy bản gốc tập tin js bên ngoài nên không thể tải, phương pháp này sẽ không hoạt động.

Các vấn đề liên quan