I am trying to make a Chrome extension with one line of jQuery code but it doesn't work. I'm trying to trigger a click on an element.
The console of chrome doesn't show any error at all,
and when I put ONLY the jQuery code in console it works fine.
My code:
content.js
$(document).ready(function() {
$('.like_post:contains(Like)').click();
});
background.js
chrome.windows.getCurrent( function(currentWindow) {
chrome.tabs.query({active: true, windowId: currentWindow.id}, function(activeTabs){
chrome.tabs.executeScript(
activeTabs[0].id, {file: 'jquery-2.1.3.min.js', allFrames: true}
);
chrome.tabs.executeScript(
activeTabs[0].id, {file: 'content.js', allFrames: true}
);
});
console.log(currentWindow.id);
});
manifest.json
{
"name": "plugin name",
"version": "0",
"description": "What do I do as an extension",
"manifest_version": 2,
"browser_action": {
"name": "project with jquery",
"icons": ["icon.png"],
"default_icon": "icon.png"
},
"content_scripts": [ {
"js": [ "jquery-2.1.3.min.js", "background.js", "content.js" ],
"matches": [ "http://*/*", "https://*/*"]
}]
}
I have also downloaded the jquery-2.1.3.min.js file and have it in the extension folder.
Can anyone explain why it doesn't work???
The root cause of the problem is that extension content scripts execute in an isolated world. One of the reasons for this is so that your code does not conflict with the page's code: for instance, you can use a different version of jQuery.
So, your content script has its own copy of jQuery. The way jQuery's .click() works is by maintaining a list of event handlers that are triggered by the click..
..and you may see the problem already. The content script's copy of jQuery is not aware of the page's copy list of handlers, and cannot trigger them.
That, by the way, explains why it works when you put it in the console - by default, console executes in the page's context and triggers the page's copy of jQuery.
There are ways to overcome this, but the most straightforward for your task is to emit a proper DOM event, that will be caught by the page's code. See this question for an example.
Related
In console I can input document.getElementById('...') and get a value back. Or even .textContent and get the string I want.
Once I pop this into my chrome extension and run it, it evaluates document.getElementById('...') as null. What's up?
Manifest.json:
{
"name": "CSUF RMP",
"version": "0.1",
"manifest_version" : 2,
"description": "Displays professor ratings on icon click",
"background" : {
"scripts" : ["background.js"]
},
"browser_action": {
"default_icon": "icon16.png"
},
"content_scripts": [
{
"matches": ["https://mycsuf.fullerton.edu/*"],
"js": ["script.js"]
}
],
"permissions": ["<all_urls>", "*://*/*", "http://*/*", "https://*/*"]
}
Background.js:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "script.js"});
});
My script.js is literally what I posted at the top. The script is supposed to have access to the web page's DOM (thus I need a content script) and run it on click of the icon (hence the background.js)
I can get the page to run and show an alert or something, but that line isn't evaluating the page's dom, just null.
I think I know what is the problem here,
you are executing script.js just like a normal script, and a normal script can't interact with the page DOM, you can think about it as just runing a script from a file- it don't have the content script's privileges that way.
What you can do is open a new tab (with the url of the content script), and then pass to the content script at that new tab a message which tells him to run a specific function there.
You can test it without using message sending by setting the onload of the content script to something like: onload=alert(document.getElementById('...')); and than open a new tab from the background page: chrome.tabs.create({"url":"https://mycsuf.fullerton.edu"});
tell me how it goes :)
Edit: forgot to mention that you need the 'tabs' permission in your manifest file in order to open new tabs and test the thing out.
Hello all i want to load the script whether or not user clicks on my extension icon
This is my extension it works great but i want it to work without making the user click on the icon to load the scripts ..
Here is the code .
{
"name": "Injecta",
"version": "0.0.1",
"manifest_version": 2,
"description": "Injecting stuff",
"background":
{
"scripts": ["jquery.js","background.js"]
},
"browser_action": {
"default_title": "Inject!"
},
"permissions": [
"https://*/*",
"http://*/*",
"tabs"
]
}
This is my background.js
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.executeScript({
file: 'jquery.js'
});
chrome.tabs.executeScript({
file: 'inject.js'
});
});
i just want the extension to load all the scripts with the page load. currently user has to click on the icon to load the scripts..
What executeScript does is basically creating a Content Script dynamically. This is called Programmatic Injection.
An alternative method of working with content scripts is specifying them in the manifest. This achieves exactly what you're asking: content scripts are executed automatically when the page is loaded.
"content_scripts" : [
{
"js": ["jquery.js", "inject.js"],
"matches": ["*://*/*"]
}
],
Adjust the matches parameter to only include match patterns for pages you want it to run on.
Make sure to check out the documentation of run_at parameter if you need to fine-tune when injection happens.
if (typeof jQuery === 'undefined') {}
I am trying to learn how to write a chrome extension. What I am looking for is the ability for to access the current page the user is on. I would like to append some of my own html to the current page the user is accessing. I then want to be able to see which element the user is currently clicking on the page.
I have figured out how to access the tab and run some javascript. But I am unclear how to append some HTML to that page. I also want to bring in jquery.
Here is what I have...
{
"background": {
"scripts": [ "jquery.min.js", "background.js"]
},
"browser_action": {
"default_icon": "icon128.png",
"default_title": "Test"
},
"description": "Make API's from regular websites",
"icons": {
"128": "icon128.png",
"16": "icon16.png",
"48": "icon48.png"
},
"manifest_version": 2,
"name": "Test",
"permissions": [ "tabs", "http://*/*", "https://*/*" ],
"version": "0.2"
}
Background.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {file: "bookmarklet.js"})
});
bookmarklet.js
(function() {
console.log($('.stuff'))
console.log(document.getElementById('yt-masthead'))
//open('http://www.google.com/'+encodeURIComponent(document.location.href),'_self').focus();
}
)();
When I run the program I am finding that I do not have access to jquery. I thought adding it to background in scripts gives me access? I also am unsure how/where I would store the html I want to append to the tab.
First off, you can probably drop the scary permissions in favor of the activeTab permission.
Second, to have jQuery you need to inject it yourself before your other script. Since injecting is asynchronous, make sure you chain it properly:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {file: "jquery.min.js"}, function(){
chrome.tabs.executeScript(tab.id, {file: "bookmarklet.js"});
});
});
Third, you probably want to generate the requisite HTML using jQuery in your content script, bookmarklet.js. Or at least store it there in a variable. It's easier to do it on the content script side, but if you have to do it in the background, you should check out Message Passing.
I am trying to create a chrome extension that will click a link when the page of a certain site is loaded/refresh. So far I have not been able to get it to work, I've tried different code snippets from different sources but no matter what I try it still doesnt do anything.
My manifest looks like this --
{
"name": "SITENAME",
"manifest_version": 2,
"version": "1",
"content_scripts": [
{
"matches": ["*://SITENAME.com/*"],
"js": ["sitenamelink.js"]
}
], "permissions": [
"tabs" , "*://SITENAME.com/*"
]
}
The site will have random dynamic variables appended to the end of it, such as "sitename.com/product/model...etc. etc." so theres really no way for it to be predictable, only way would to find the page url and update the extension everytime which is not something I want to have to do.
I was trying to keep the js coding clean and simple and the js I have now is --
$(document).ready(function(){
$('#addToCartLink').trigger('click');
});
I also tried this --
jQuery.noConflict();
jQuery(document).ready(function() {
jQuery('a#addToCartLink')[0].click();
});
and this --
$(document).ready(function(){
$('a#addToCartLink')[0].click();
});
The page that has the link, has it coded as such -- <a id="addToCartLink" href="javascript:addToCart()" onclick="showBubble(this)" onmouseout="hideBubble()"><span>Add to Cart</span></a>
Im not sure how to inspect it to see where my code is failing because when I inspect with chrome, it only shows the js errors from that page's coding.
So what am I doing wrong? Any help is much appreciated. Thanks.
Here's a test page, the size is selected if you follow this link, and now only requires for the add to cart link to be clicked. -- Test Page
My sample extension (see code below) worked fine for me.
E.g.: Visiting the Test Page you provided, the ADD TO CART link is clicked and the item is added to cart.
manifest.json:
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"offline_enabled": false,
"content_scripts": [{
"matches": ["*://*.sitename.com/*"],
"js": ["content.js"],
"run_at": "document_end",
"all_frames": false
}]
}
content.js:
document.getElementById('addToCartLink').click();
I'm trying to create a chrome extension. When the user clicks my extension's icon (browserAction) the content script appends an extra div to the body of the open page(current tab). It works fine in all the sites except google's search page and youtube. I'm not getting any error message or anything. It simply wont give any response.
This is my code in content.js:
alert('sdsd');
$('body').append("<div id='popup'>My extension name</div>");
I've put the alert for testing purpose. So when extension is toggled it should show an alert message followed by appending the div to body, ideally! But it wont for these 2 sites.
Any idea what could be going wrong here?
manifest
{
"name": "My first extension",
"version": "1.0",
"background": { "scripts": ["background.js"] },
"content_scripts": [{
"all_frames": true,
"css": ["style.css"],
"matches": ["http://*/*","https://*/*"]
}],
"permissions": [ "tabs","http://*/*" ],
"browser_action": { "name": "test" },
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function(tab){
chrome.tabs.executeScript(null,{file:"jquery.min.js"},function(){
chrome.tabs.executeScript(null,{file:"content.js"});
});
});
In Youtube's page, $ is overwritten and isn't jQuery. It's
bound: function ()
{
return document.getElementById.apply(document, arguments)
}
So your code makes an exception as there document.getElementById('body') is undefined.
You should try using noConflict().
EDIT :
Why aren't you simply listing jQuery.min.js and your content.js in the content_scripts instead of injecting them programmatically. This would avoid conflicts.
EDIT 2 :
Now that you use content scripts, you should use communication as described here to send from background.js to the content script the instruction to show the alert.
EDIT 3 :
Another solution would have been to use programmatic injection (as you initially did) and not use jquery, $('body').append("<div id='popup'>My extension name</div>"); being translated in vanilla JS to
var div = document.createElement('div');
div.id = 'popup';
document.body.appendChild(div);
document.getElementById('popup').innerHTML = "My extension name";
But it's generally cleaner (and requires less permissions) to avoid programmatic injection.