2017-07-06 194 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