2017-07-06 25 views
-1

ウェブサイトのフラット情報を取得するためのシンプルなChrome拡張機能を作成しようとしていますが、JQueryのオン/クリック機能を使用することさえできません。私はここでの問題が何であるかわからないんだけどJQueryのオン/クリック機能が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、ブートストラップは3.3.7です。ここにはJQueryに関連するChrome拡張機能に関する多くの質問はありません。私はこの1つを見つけたChrome extensions with jQueryしかし、私はすでに他のコードをカプセル化する文書準備機能を持っています。この1つを$(document).click() not working in chrome extensionでも見ましたが、その解決策はJQueryのクリック/オン機能を利用していません。

+1

サイトはおそらく、文書準備完了イベントが発生した後にその内容を動的に追加します。これを確認するには、コンテンツスクリプトにconsole.log($( "#hello")[0])を追加します。 null/undefinedの場合は、setTimeout/setIntervalまたはwindow.onloadまたはMutationObserverを使用して待機する必要があります。 – wOxxOm

+0

それは私には意味をなさないundefinedを返します。私の仮定は、$(document)は実際のWebページではなくpopup.htmlを参照しているということです。しかし、それは間違っているようです。私は何を理解していないのですか? – Adam

+1

[拡張アーキテクチャの概要](https://developer.chrome.com/extensions/overview#arch)を必ずお読みください。コンテンツスクリプトもポップアップも、お互いを直接参照することはできず、ブラウザの異なる部分で実行されます。 – wOxxOm

答えて

3

申し訳ありませんが、ここで問題となったのは、JSファイルのそれぞれが実行され、Chromeのメッセージングシステムが誤解されていたためです。そこで、私のコードの変更点を以下に概説します。これを行うにはより良い方法があるかもしれませんが、これは初めてChrome拡張機能を開発したときです。

manifest.jsonを

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

下に示すように、私は、バックグラウンドスクリプトを追加しただけでなく、代わりに、content.js

popup.jsことがpopup.htmlで使用されるスクリプトを変更manifest.jsonを改変popup.jsを以下に示します。これは私がonMessageのイベントを使用してリスナーを作成したpopup.htmlに延長のコンテキストで実行したとbackground.js

popup.js background.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); 
    }); 
} 

にハンドラをキックオフChromeにメッセージを送信していますchrome.runtimeのAPI。これにより、実際のWebページのコンテキストでスクリプト(content.js)を実行するchrome.tabs.executeScriptが呼び出されます。メッセンジャーリスナーは、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; 
     } 
    } 
); 

次の部分は、Webページのコンテキストで実行され、私は気にデータをつかむ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のを使用していますから、情報をつかんでいますので、jQueryのcontent.jsで働いていた唯一の理由だったと思うことを言及する必要があります。私はtabs.executeScript - passing parameters and using libraries?background.jsの行に沿って何かをして、コンテキストにJQueryを挿入しなければならなかったので、そうでない場合はcontent.jsがそれを使うことができます。

編集

私はmanifest.json

エンド編集

content_scripts部を介して、私は問題を解決することができたいずれかの方法をjQueryのを注入することだということで^^これは間違っていました。私も参照のためにこれを使用しましたPass a parameter to a content script injected using chrome.tabs.executeScript()

これを行う良い方法がある場合は、自由にコメントしてください。私が言ったように、これはChrome拡張機能の最初の試みでした。

+0

* manifest.json *は、* popup.js *をコンテンツのスクリプトとあなたの* popup.html *。そうすることは、ほとんどの場合、Bad Idea™です。一般的には、単一のスクリプトを複数のコンテキスト(ライブラリ(jQueryなど)など)にロードするだけです。あるコンテキストで動作するように特別に記述されたスクリプトは、別のコンテキストでそれらを使用しようとすると、通常は問題が発生します。そうすることで、これらのタグには*多くの*質問の出典があります。 – Makyen

+0

それで 'popup.js'とブートストラップスクリプトはウェブページのコンテキストに挿入するので、私は' popup.js'とそれを取り除くべきです。私はそれがpopup.htmlで動作するようにしなければならないと思った。私は先に行くとそれを削除します。だから私は 'content.js'でJQueryを使うことができるコンテンツスクリプトとしてJQueryを注入しているからです。 – Adam

+0

はい。ちょうどFYI:ポップアップとコンテンツスクリプトのコンテキストは完全に別です。同じスクリプト(ライブラリを除く)を複数の異なるコンテキストに注入する必要はありません。しかし、あなたが意図的にそれをプログラムするのではなく、通常はもっと努力しているのであれば、問題が生じるだけです。 – Makyen

関連する問題