36

Tôi có một tập lệnh Greasemonkey hoạt động tốt trong Firefox và Opera. Tuy nhiên, tôi đã đấu tranh để đưa nó vào làm việc trong Chrome. Vấn đề là tiêm một hàm vào trang có thể được gọi bằng mã từ trang. Dưới đây là những gì tôi đang làm cho đến thời điểm này:Đưa các hàm JS vào trang từ tập lệnh Greasemonkey trên Chrome

Trước tiên, tôi nhận được tham chiếu trợ giúp cho số unsafeWindow cho Firefox. Điều này cho phép tôi có cùng một mã cho FF và Opera (và Chrome, tôi nghĩ).

var uw = (this.unsafeWindow) ? this.unsafeWindow : window; 

Tiếp theo, tôi chèn một hàm vào trang. Nó thực sự chỉ là một wrapper rất mỏng mà không làm gì nhưng cách gọi các chức năng tương ứng trong bối cảnh kịch bản GM của tôi:

uw.setConfigOption = function(newValue) { 
    setTimeout(setConfigOption, 0, newValue); 
} 

Sau đó, có chức năng tương ứng ngay trong kịch bản của tôi:

setConfigOption = function(newValue) { 
    // do something with it, e.g. store in localStorage 
} 

ngoái, Tôi chèn một số HTML vào trang với một liên kết để gọi hàm.

var p = document.createElement('p'); 
p.innerHTML = '<a href="javascript:setConfigOption(1)">set config option to 1</a>'; 
document.getElementById('injection-point').appendChild(p); 

Để tóm tắt: Trong Firefox, khi người dùng nhấp rằng tiêm liên kết, nó sẽ thực hiện các cuộc gọi chức năng trên unsafeWindow, mà sau đó gây nên một thời gian chờ để gọi chức năng tương ứng trong bối cảnh kịch bản GM của tôi, mà sau đó thực hiện xử lý thực tế. (Sửa tôi nếu tôi sai ở đây.)

Trong Chrome, tôi chỉ nhận được lỗi "Lỗi tham chiếu không xác định: setConfigOption không được xác định". Và thực sự, nhập "window.setConfigOption" vào giao diện điều khiển mang lại "không xác định". Trong Firebug và bảng điều khiển dành cho nhà phát triển Opera, chức năng này ở đó.

Có thể có một cách khác để thực hiện việc này, nhưng một vài chức năng của tôi được gọi bởi một đối tượng Flash trên trang, mà tôi tin rằng cần phải có các chức năng trong ngữ cảnh trang.

Tôi đã xem nhanh alternatives to unsafeWindow trên wiki Greasemonkey, nhưng tất cả đều trông khá xấu xí. Tôi hoàn toàn đi sai đường ở đây hay tôi nên nhìn kỹ hơn vào những thứ này?

GIẢI PHÁP: Tôi đã theo dõi Max S.' advice và hoạt động trong cả Firefox và Chrome ngay bây giờ. Bởi vì các chức năng tôi cần để có sẵn cho trang đã phải gọi lại vào các trang thông thường, tôi đã chuyển toàn bộ tập lệnh của mình sang trang, tức là nó được bọc hoàn toàn vào hàm mà anh ta gọi là 'main()'.

Để làm cho sự xấu xí thêm của hack đó một chút bearable, tôi ít nhất có thể thả việc sử dụng không an toànWindow và wrapJSObject bây giờ.

Tôi vẫn chưa quản lý để nhận được content scope runner từ wiki Greasemonkey hoạt động. Nó nên làm như vậy và có vẻ như để thực thi tốt, nhưng các chức năng của tôi không bao giờ truy cập được vào các phần tử <a> từ trang đó. Tôi vẫn chưa tìm ra lý do tại sao.

Trả lời

58

Cách duy nhất để giao tiếp với mã đang chạy trên trang trong Chrome là thông qua DOM, vì vậy, bạn sẽ phải sử dụng bản hack như chèn thẻ <script> cùng với mã của mình. Lưu ý rằng điều này có thể chứng minh lỗi nếu tập lệnh của bạn cần chạy trước mọi thứ khác trên trang.

EDIT: Sau đây là cách thực hiện điều này the Nice Alert extension:

function main() { 
    // ... 
    window.alert = function() {/* ... */}; 
    // ... 
} 

var script = document.createElement('script'); 
script.appendChild(document.createTextNode('('+ main +')();')); 
(document.body || document.head || document.documentElement).appendChild(script); 
+1

Tôi đã thử 'nhân vật phạm vi nội dung' (thực hiện chính xác điều đó, nếu tôi không nhầm lẫn) và trong khi các chức năng có sẵn cho tập lệnh của tôi, chúng dường như không có sẵn cho trang (ví dụ: neo nhãn). Bạn có bất kỳ mã ví dụ nào hay bất kỳ thứ gì bạn có thể liên kết đến? Tôi không quan tâm lắm đến thứ tự thực hiện. Tôi có thể làm việc xung quanh khi tôi quản lý để gọi một chức năng tiêm từ trang. :) –

+0

Thứ tự thực thi tập lệnh nội dung có thể được xác định thông qua câu lệnh 'run_at' http://code.google.com/chrome/extensions/content_scripts.html – NVI

+0

re run_at: Tôi không viết tiện ích mở rộng của Chrome, mặc dù (và tôi không có ý định, quá nhiều công việc để duy trì hai kịch bản). Đây chỉ là một tập lệnh Greasemonkey mà tôi đang cố gắng làm cho đủ tương thích để Chrome có thể thực hiện 'tự động chuyển đổi' các tập lệnh GM thành tiện ích mở rộng. –

4

I took a quick look at the alternatives to unsafeWindow on the Greasemonkey wiki, but they all look pretty ugly. Am I completely on the wrong track here or should I look more closely into these?

Bạn nên tìm, bởi vì nó chỉ có sẵn tùy chọn. Tôi muốn sử dụng location hack.

myscript.user.js:

function myFunc(){ 
    alert('Hello World!'); 
} 

location.href="javascript:(function(){" + myFunc + "})()" 

example.com/mypage.html

<script> 
myFunc() // Hello World! 
</script> 

Chắc chắn, đó là xấu xí. Nhưng nó hoạt động tốt.


Phương thức nội dung Phương pháp Runner, được đề cập bởi Max S. tốt hơn là hack vị trí, vì dễ debug hơn.

+0

Bạn có thể vui lòng đăng một ví dụ về cách mà có thể được sử dụng để xác định một hàm có thể được gọi bởi một đối tượng neo hoặc một đối tượng Flash không? –

+0

Bạn có ý nghĩa gì "bởi một neo"? – NVI

15

Tôi có điều này:

contentscript.js:

function injectJs(link) { 
var scr = document.createElement('script'); 
scr.type="text/javascript"; 
scr.src=link; 
document.getElementsByTagName('head')[0].appendChild(scr) 
//document.body.appendChild(scr); 
} 

injectJs(chrome.extension.getURL('injected.js')); 

injected.js:

function main() { 
    alert('Hello World!'); 
} 

main(); 
+2

Điều này thật tuyệt vời! Ngoài ra shortcut cho những người sử dụng jQuery: 'function injectjs (link) { $ ('

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