2012-03-28 41 views
47

Tôi đang cố gắng để Tiện ích mở rộng của Chrome chạy chức năng init() bất cứ khi nào trang mới được tải, nhưng tôi đang gặp sự cố khi cố gắng hiểu cách thực hiện điều này. Từ những gì tôi hiểu, tôi cần phải làm như sau trong background.html:Mã mở rộng của Chrome so với tập lệnh Nội dung và tập lệnh được nhúng

  1. Sử dụng chrome.tabs.onUpdated.addListener() để kiểm tra khi trang được thay đổi
  2. Sử dụng chrome.tabs.executeScript để chạy một kịch bản.

Đây là code tôi có:

//background.html 
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { 
    chrome.tabs.executeScript(null, {code:"init();"}); 
}); 

//script.js 
function init() { 
    alert("It works!"); 
} 

Tôi cũng tự hỏi nếu init() chức năng sẽ có quyền truy cập vào các chức năng khác của tôi nằm trong các tập tin JS khác?

Trả lời

142

mã JavaScript trong phần mở rộng Chrome có thể được chia thành các nhóm sau:

  • đang mở rộng - Toàn quyền truy cập đến tất cả các phép chrome.* API.
    Điều này bao gồm background page và tất cả các trang có quyền truy cập trực tiếp vào thông qua chrome.extension.getBackgroundPage(), chẳng hạn như browser pop-ups.

  • Content scripts (thông qua file manifest hoặc chrome.tabs.executeScript) - Partial quyền truy cập vào một số các chrome API, đầy đủ quyền truy cập vào DOM của trang (không với bất kỳ window đối tượng, bao gồm cả khung).
    Các tập lệnh nội dung chạy trong phạm vi giữa tiện ích mở rộng và trang. Đối tượng window toàn cục của tập lệnh Nội dung khác với không gian tên chung của trang/tiện ích mở rộng.

  • Đoạn mã được nhúng (qua this method trong tập lệnh Nội dung) - Toàn quyền truy cập vào tất cả các thuộc tính trong trang. Không có quyền truy cập vào bất kỳ API chrome.* nào.
    Các tập lệnh được nhúng hoạt động như thể chúng được bao gồm bởi chính trang đó và không được kết nối với tiện ích theo bất kỳ cách nào. Xem this post để tìm hiểu thêm thông tin về các phương pháp tiêm khác nhau.

Để gửi thư từ tập lệnh được tiêm tới tập lệnh nội dung, sự kiện phải được sử dụng. Xem this answer để biết ví dụ. Lưu ý: Thư được chuyển trong một phần mở rộng từ ngữ cảnh này sang ngữ cảnh khác là tự động (JSON) -serialised và được phân tích cú pháp.


Trong trường hợp của bạn, mã trong trang nền (chrome.tabs.onUpdated) có khả năng gọi trước khi kịch bản nội dung script.js được đánh giá. Vì vậy, bạn sẽ nhận được một ReferenceError, bởi vì init thì không.

Ngoài ra, khi bạn sử dụng chrome.tabs.onUpdated, hãy chắc chắn rằng bạn kiểm tra xem trang được nạp đầy đủ, bởi vì sự kiện cháy hai lần: Trước khi tải, và lớp sơn hoàn thiện:

//background.html 
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { 
    if (changeInfo.status == 'complete') { 
     // Execute some script when the page is fully (DOM) ready 
     chrome.tabs.executeScript(null, {code:"init();"}); 
    } 
}); 
+0

Cảm ơn bạn về mẹo 'chrome .tabs.onUpdated' kích hoạt hai lần. Vì vậy, câu hỏi của tôi tôi đoán là làm thế nào tôi sẽ tiêm 'init()'? Tôi có nên tiêm tất cả các JavaScripts của mình không? 'init()' thường được gọi khi người dùng nhấp vào biểu tượng Hành động trình duyệt, và 'init()' kích hoạt một loạt các hàm khác. – Jon

+1

@ user1277607 Khi nó phải truy cập bất kỳ biến toàn cục nào của trang, hãy tiêm tập lệnh. Khi 'hàm init' phải truy cập cả mã trang và tiện ích mở rộng, hãy sử dụng tập lệnh nội dung. Xem ** [câu trả lời được liên kết] (http://stackoverflow.com/a/9517879/938089?building-a-chrome-extension-inject-code-in-a-page-using-a-content-script) * * để xem cách chèn tập lệnh và ** [câu trả lời này] (http://stackoverflow.com/a/9636008/938089?chrome-extension-retrieving-gmails-original-message) ** để biết hướng dẫn triển khai Tập lệnh nội dung phải truy cập vào các biến của trang. –

+0

cảm ơn bạn rất nhiều. Nó hoạt động rất tốt :) – Jon

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