Using JQuery in a content script - javascript

I am trying to use JQuery in my content script but The chrome console spits this out "Uncaught ReferenceError: $ is not defined ". I can successfully use JQuery in my background script so I'm not exactly sure whats up.
Here's the manifest file:
{
"name": "Something",
"version": "1.0",
"description": "SOmething",
"background": {
"scripts": ["background.js", "jquery.js"],
"persistent": true
},
"browser_action": {
"default_icon": "favicon.png",
"default_popup": "popup.html"
},
"permissions": [
"declarativeContent",
"http://localhost/",
"http://*/*",
"https://localhost/",
"https://*/*",
"tabs"
],
"icons": {
"48": "icon-48p.png"
},
"content_scripts": [{
"matches": [
"http://*/*",
"https://*/*"
],
"js": ["content.js", "jquery.js"]
}],
"web_accessible_resources": ["button.PNG", "jquery.js"],
"manifest_version": 2
}
Here's the content script:
var btn = document.createElement("input");
btn.id = "btn";
btn.type = "image";
btn.setAttribute("src", chrome.extension.getURL("button.PNG"));
btn.onclick = function() {
alert("Currently under development");
};
btn.className = "";
if (window.location.href.indexOf("mysite") > -1) {
$('#pageContainer').append('<ol><li>CATS</li><ol>'); //Fails here
}
if (window.location.href.indexOf("myother") > -1) {
document.getElementById("maindiv").appendChild(btn); //works
}
Edit: JQuery is in the project and it does work in background.js. The question is how do I get it working within my content script? I've specified in the manifest that I want jquery injected along with content.js.

Make jQuery the first content script listed in thecontent_scripts -> js array. Like:
"content_scripts": [{
"matches": [
"http://*/*",
"https://*/*"
],
"js": ["jquery.js", "content.js"]
}],
Your content script is trying to access jquery before it's loaded. The way your manifest is set up now, jQuery still should be loaded however. To verify this, type something like window.jQuery into the console on the content script page and make sure that it is defined.

As berrberr pointed out, you have to load jquery before your content.js script as follows
"js": ["jquery.js","content.js"]
or you can achieve the same in Pure JS using appendChild().
Also a note: If you are manipulating DOM elements, try injecting your script at document_end

Related

How do I add an element?

I'm creating extensions.
As a test, I want to add a button to YouTube.
I would like to add a button like the red frame on the left side of the button to rate and share the video as shown in the following image.
enter image description here
But I can't add it.
Here are the manifest.json .
{
"name": "test_extension",
"version": "1",
"manifest_version": 2,
"permissions": [
"tabs",
"storage",
"<all_urls>",
"input"
],
"content_scripts": [
{
"matches": ["https://www.youtube.com/*"],
"js": ["script/jquery-3.5.1.min.js","script/make-stamp.js"],
"all_frames": true
}
],
"icons": {
"48": "icon/48.png"
}
}
The script you want to run is here.
console.log("test extension : Start");
$("#container > #info > #menu-container").before("<div><button id=\"stamp-button\"></button></div>");
console.log("test extension : make element?");
The chrome console also shows test extension: Start and test extension: make element.

Chrome extension - collect HTMLcollection from file

I'm creating a in house chrome extension which collects data from a webpage (broke links etc for SEO) but i'm having issues. My original script injected the js onpage which was great as it had a box and collected what was needed, the only issue was it wasn't a Popup box so it didn't close correctly etc. I now have a script which on load pulls all dom data and a script which display and manipulates the data. The only issue I have is collecting the data from the file.
Manifest.json
{
"name": "",
"version": "1.2.4",
"manifest_version": 2,
"description": "",
"homepage_url": "",
"background": {
"scripts": [
"background.js",
"Returndocdata.js"
],
"persistent": true
},
"browser_action": {
"default_title": ""
},
"icons": { "16": "icon16.png" },
"permissions": [
"https://*/*",
"http://*/*",
"tabs"
],
"content_scripts": [
{
"matches": ["*://*/*"],
"run_at": "document_start",
"js": ["Returndocdata.js"]
}
]
}
background.js
chrome.browserAction.onClicked.addListener(function(tab, info) {
chrome.tabs.executeScript({file: 'Returndocdata.js'});
});
chrome.browserAction.onClicked.addListener(function(tab, info) {
chrome.browserAction.setPopup({popup: "inject.html"})
});
inject.html
<div id = "ContactDetails">
<input type="text" name="lname">
</div>
<script src="inject.js"></script>
Returndocdata.js
var all = document.getElementsByTagName("*");
console.log(all);
inject.js
this is the file that needs the returndocdata.js data, i need a way to grab that data and pull it into this keeping the formatting (the htmlcollection)
This works if I include the script in the header but due to it not being ran on the web page itself it only returns data from the popup extension.
It's most likely a small thing
Ta

Chrome Extension error tab.url

I'm essentially just trying to get the current tab url if they're on youtube.com. I keep getting an error from the script.
Error:
Uncaught TypeError: Cannot call method 'getSelected' of undefined
Manifest
{
"name": "YouTube Fix",
"version": "0.0.1",
"manifest_version": 2,
"description": "Fix some of the annoying little things in YouTube.",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"content_scripts": [{
"matches": ["http://www.youtube.com/*"],
"js": ["background.js"],
"run_at": "document_start"
}],
"permissions": ["tabs"]
}
Background.js
//this is what is giving me the error:
chrome.tabs.getSelected(null, function (tab) {
myFunction(tab.url);
});
function myFunction(tablink) {
if (tablink == "http://www.youtube.com") {
window.location = "http://www.youtube.com/feed/subscriptions/u";
}
document.getElementById("comments-textarea").disabled = false;
}
The following forks fine, no need for chrome.tabs.getSelected(null, function (tab) {}),because your page always runs for "matches": ["http://www.youtube.com/*"],;
More over add this condition to your code if(document.getElementById("comments-textarea") != null){
Working background.js
if (window.location == "http://www.youtube.com") {
window.location = "http://www.youtube.com/feed/subscriptions/u";
}
if (document.getElementById("comments-textarea") != null) {
document.getElementById("comments-textarea").disabled = false;
}
manifest.json
{
"name": "YouTube Fix",
"version": "0.0.1",
"manifest_version": 2,
"description": "Fix some of the annoying little things in YouTube.",
"content_scripts": [{
"matches": ["http://www.youtube.com/*"],
"js": ["background.js"],
"run_at": "document_start"
}],
"permissions": ["tabs"]
}
Let me know if you need more information.
You're running background.js as a content script rather than a background or event page, and https://developer.chrome.com/extensions/content_scripts.html says that "content scripts have some limitations. They cannot … Use chrome.* APIs (except for parts of chrome.extension)"
Instead, you should put something like
"background": {
"scripts": ["background.js"],
"persistent": false
},
into your manifest. See https://developer.chrome.com/extensions/event_pages.html for more details.
Quoted from here: https://groups.google.com/a/chromium.org/forum/?fromgroups=#!topic/chromium-extensions/A5bMuwCfBkQ
chrome.tabs.getSelected() is deprecated. The following page explains
how to use chrome.tabs.query instead:
http://code.google.com/chrome/extensions/whats_new.html#16 The relevant bit of text is:
"""
The methods getAllInWindow() and getSelected() have been deprecated.
To get details about all tabs in the specified window, use
chrome.tabs.query() with the argument {'windowId': windowID}. To get
the tab that is selected in the specified window, use
chrome.tabs.query() with the argument {'active': true}.
"""
chrome.tabs.getSelected is deprecated. Use chrome.tabs.query instead:
chrome.tabs.query({
"active": true
}, function(tab){
console.log(tab[0]); //selected tab
});
Also, content scripts can not access chrome.tabs APIs. Do this:
chrome.extension.getBackgroundPage().chrome.tabs.query(...
(This might not work. Not tested.)

Chrome extension: load different content scripts

I want to load a different content script depending on the page and tab that is currently selected. Right now, I have three content scripts. I want to use two of them for one page and the third one for another page.
Belonging to page 1:
content_script.js
load_content_script.js
Belonging to page2:
newtab_content_script.js
right now my manifest looks like this
{
"name": "A plugin for AdData express. Generate an instant excel document from the brands you check mark.",
"version": "1.0",
"background_page": "background.html",
"permissions": [
"cookies",
"tabs",
"http://*/*", "https://", "*", "http://*/*", "https://*/*",
"http://www.addataexpress.com", "http://www.addataexpress.com/*"
],
"content_scripts": [
{
"matches": ["<all_urls>","http://*/*","https://*/*"],
"js": ["load_content_script.js", "content_script.js", "newtab_content_script.js", "jquery.min.js", "json.js"]
}
],
"browser_action": {
"name": "AdData Express Plugin",
"default_icon": "icon.png",
"js": "jquery.min.js",
"popup": "popup.html"
}
}
how would I structure this in the manifest or elsewhere?
Just in the interest of completeness, the way you'd do this from the manifest is to have as many matches blocks under "content_scripts" as needed:
"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"css": ["mygooglestyles.css"],
"js": ["jquery.js", "mygooglescript.js"]
},
{
"matches": ["http://www.yahoo.com/*"],
"css": ["myyahoostyles.css"],
"js": ["jquery.js", "myyahooscript.js"]
}
],
Rather than using content scripts that are bound to URL expressions specified in the manifest, you should use executeScript, which lets you programmatically decide when to inject a JS snippet or file:
// background.js
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
// there are other status stages you may prefer to inject after
if (changeInfo.status === "complete") {
const url = new URL(tab.url);
if (url.hostname === "www.stackoverflow.com") {
// this is the line which injects the script
chrome.tabs.executeScript(tabId, {file: "content_script.js"});
}
}
});
Make sure to add tabs permission to manifest.json:
{
// ...settings omitted...
"permissions": [
"tabs", // add me
]
}
you should use Programmatic injection
chrome.tabs.executeScript(null, {file: "content_script.js"});

How to track page change (Chrome Context Script plugin)?

I'm writing a simple Chrome plugin that's intended to delete DOM elements from some site.
manifest.json
{
"name": "bla",
"version": "1.0",
"description": "bla",
"content_scripts": [
{
"matches": ["http://*/*"],
"js": ["myscript.js"]
}
],
"permissions": [
"tabs",
"http://*/*"
]
}
myscript.js
window.onload = start;
function start()
{
var ads = document.getElementById("left_ads");
ads.parentNode.removeChild(ads);
alert("bla");
}
When I load a target page everything works perfectly: div id="left_ads" is removed as intended. But, when I click a link to a page which also has a similar div id="left_ads" my script fails to work. I know that probably I should choose some other event, not window.onload(), but which one?
It turns out I've found a solution to this. I used background html file.
So, the plugin now looks like this:
manifest.json:
{
"name": "bla",
"version": "1.0",
"description": "bla",
"background_page": "background.html",
"permissions": [
"tabs",
"http://*/*"
]
}
background.html:
<html>
<script>
chrome.tabs.onUpdated.addListener(start);
function start(tabID, changeInfo, tab)
{
chrome.tabs.executeScript(null, { file: "myscript.js" })
}
</script>
</html>
myscript.js:
var ads = document.getElementById("left_ads");
ads.parentNode.removeChild(ads);
Works OK, on every page.

Categories

Resources