2017-07-06 100 views
-1

我想寫一個簡單的Chrome擴展來從網站上獲取平板信息,但我甚至無法從JQuery獲取on/click函數來工作。JQuery on/click功能在Chrome擴展中不起作用

的manifest.json

{ 
    "manifest_version": 2, 

    "name": "Flat", 
    "description": "Adds flats to app", 
    "version": "1.0", 

    "browser_action": { 
    "default_icon": "icon.png", 
    "default_popup": "popup.html" 
    }, 
    "permissions": [ 
    "activeTab", 
    ], 
    "content_scripts": [ 
    { 
     "matches": [ 
     "https://www.spareroom.co.uk/flatshare/flatshare_detail.pl*", 
     ], 
     "js": ["lib/jquery.min.js", "lib/bootstrap.min.js", "content.js"] 
    } 
    ] 
} 

content.js

$(document).ready(function() { 
    console.log('Viewing flat'); 
    $("#hello").on("click", function() { 
     console.log("Hello"); 
    }); 
    $("#hello").click(function() { 
     console.log("hello"); 
    }); 
}); 

popup.html

<html> 
<head> 
    <title>Popup</title> 
    <link rel="stylesheet" href="lib/bootstrap.min.css"> 
    <link rel="stylesheet" href="style.css"> 
    <script src="lib/jquery.min.js"></script> 
    <script src="lib/bootstrap.min.js"></script> 
    <script src="content.js"></script> 
</head> 
<body> 
    <div class="container"> 
     <button id="hello" class="btn btn-default">Add Flat</button> 
    </div> 
</body> 
</html> 

我不知道這裏的問題是。 JQuery是3.2.1,Bootstrap是3.3.7。這裏沒有很多與JQuery相關的Chrome擴展問題。我發現這一個Chrome extensions with jQuery,但我已經有封裝其他代碼的文檔就緒函數。也看了這個$(document).click() not working in chrome extension但該解決方案沒有利用JQuery點擊/開啓功能。

+1

在文檔就緒事件觸發後,該站點可能會動態添加其內容。您可以通過在內容腳本中添加console.log($(「#hello」)[0])來進行驗證。如果它爲空/未定義,則需要通過setTimeout/setInterval或window.onload或MutationObserver等待。 – wOxxOm

+0

那確實返回undefined對我來說沒有意義。我的假設是$(文檔)是指popup.html而不是實際的網頁。但是這看起來不正確。我不瞭解什麼? – Adam

+1

請務必閱讀[擴展體系結構概述](https://developer.chrome.com/extensions/overview#arch)。內容腳本和彈出框都不能直接互相引用,它們運行在瀏覽器的不同部分。 – wOxxOm

回答

3

好吧,所以這裏的問題是我對上下文的錯誤理解,每個JS文件都運行在Chrome中的消息系統中。所以我將概述下面我的代碼的更改。這樣做可能有更好的方法,但這是我第一次開發Chrome擴展。

我改性manifest.json如下所示

的manifest.json

... 
"background": { 
    "scripts": ["background.js"] 
}, 
"content_scripts": { 
    { 
    ... 
    "js": ["lib/jquery.min.js"] 
    } 
} 

我增加了背景腳本以及改變在popup.html使用的腳本是popup.js代替content.js

下面顯示了popup.js。這是在擴展的情況下運行在popup.html和發送一個消息給那個鉻序幕在background.js

popup.js一個處理程序

$(document).ready(function() { 
    console.log('Viewing flat'); 
    $("#hello").click(clickHandler); 
}); 

function clickHandler(e) { 
    console.log('Adding flat'); 
    chrome.runtime.sendMessage({directive: "get-flat"}, function (response) { 
     // 
     console.log("handler", response); 
    }); 
} 

background.js我創建使用在onMessage事件的監聽器API的chrome.runtime。然後這將調用chrome.tabs.executeScript在實際網頁的上下文中執行腳本(content.js)。信使監聽器與Redux w/React類似,所以這非常有趣。我發現這種模式在這個問題上Detect a button click in the browser_action form of a Google Chrome Extension

background.js

chrome.runtime.onMessage.addListener(
    function (request, sender, sendResponse) { 
     switch (request.directive) { 
      case "get-flat": 
       chrome.tabs.executeScript(null, { file: "content.js" }); 
       sendResponse("in get-flat directive"); 
       break; 
      case "process": 
       console.log("process", request.data); 
       break; 
      default: 
       break; 
     } 
    } 
); 

接下來的部分是content.js它運行在網頁的背景下,並抓住我關心的數據。然後它將該消息傳遞迴background.js以進行進一步操作。爲簡潔起見,我簡化了代碼。

內容。JS

function getFlat() { 
    console.log("in getFlat"); 
    // Do stuff 
    var val = $("#something").text(); 
    return val; 
} 
chrome.runtime.sendMessage({directive: "process", data: getFlat()}); 

我要指出,我認爲只有在JQuery的工作content.js的原因是因爲我從抓信息的網站也用了jQuery。我將不得不沿着tabs.executeScript - passing parameters and using libraries?background.js的行執行某些操作,以便將JQuery注入上下文,因此如果不是這種情況,content.js可以使用它。

編輯

^^這是,我通過content_scripts部分manifest.json

末編輯

無論哪種方式,我是能夠解決問題注入JQuery的不正確。我也用這個作爲參考Pass a parameter to a content script injected using chrome.tabs.executeScript()

如果有更好的方法做到這一點,隨時發表評論。就像我說的那樣,這是我第一次嘗試Chrome擴展。

+0

您的* manifest.json *似乎暗示您包含* popup.js *作爲內容腳本並在* popup.html *中。這樣做幾乎總是一個壞主意™。一般來說,你應該只加載一個腳本到多個上下文中,這是一個庫(例如jQuery等)。如果您嘗試在不同的環境中使用它們,專門爲在一個環境中工作而編寫的腳本通常會遇到問題。這樣做是這些標籤中*許多問題的來源。 – Makyen

+0

好的,我應該刪除'popup.js'以及引導腳本,因爲它將它們注入到網頁的上下文中。我以爲我必須這樣做,所以它會在popup.html中工作。我會繼續並將其刪除。因此,我將JQuery作爲內容腳本注入,這就是爲什麼我可以在'content.js'中使用它的原因? – Adam

+0

是的。僅供參考:彈出窗口和內容腳本上下文完全分離。您不應/不應將相同的腳本(庫除外)注入多個不同的上下文中。你可以,但是如果你不是這樣有意地編程的話,那通常會更加努力,它只會產生問題。 – Makyen