I've had a good look, but I can't seem to find and answer to this question (well, one that works for me anyway).
I've made a Chrome extension that should run the code that's in my content script on click of the icon only, but it always runs as soon as the page loads. Is there a way to prevent this from happening? None of the possible strings I can enter for run_at really cater for this.
Here is example code in both scripts:
Content Script:
function runIt() {
console.log('working');
}
runIt();
background.js:
chrome.browserAction.onClicked.addListener(function(activeTab) {
chrome.tabs.executeScript(null, {file: "content.js"});
});
It will log 'working' as soon as the page loads, and for each button click after that. Is there a way to stop it running as soon as the page loads?
Thanks in advance for all contributions.
The browserAction.onClicked code in your background page does exactly what you want. If you want to stop content.js from running as content script on page load, simply don't include it as a content script in your manifest.
Specifically, in your manifest.json file, you have some lines that look something like this:
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["content.js"]
}
],
Simply remove those lines, and the script will stop running on page load, while your click listener code will continue working.
Related
I want to ask is there ANY way or extension that can pre-highlight text within the iframe whenever a new window is opened containing iframe? I have tried many extension but none of them works.
I need to filter out content based on certain keywords and the content is within iframe. I can do it with CTRL+F but there are many keywords like 10-15 within each article to be found. So it makes my job very tough and time consuming. Few extensions that I have tried from chrome are multi highlighter, pearls, FF but none of them seems to work.
I also know the reason why these extension can't access content within the iframe i.e. due to cross origin policies.
But I also remember around an year ago I worked with chrome extension named 'Autofill' that could pre-select form elements whenever I opened new chrome window containing iframe.
So is there any work around?
You can set your extension permission to run content scripts in all frames as document at http://developer.chrome.com/extensions/content_scripts.html#registration by setting all_frames to true in the content scripts section of your manifest file. Adding to Google's example from that page, part of your manifest file might look like
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"css": ["mystyles.css"],
"js": ["jquery.js", "myscript.js"],
"all_frames": true
}
],
...
}
You'll need to be careful since your content scripts are going to be inject into the page once for the parent page and one for each iFrame on the page. Once your content script is injected into all frames on the page you can work your magic with finding and highlighting text.
if (window === top) {
console.log('Running inside the main document', location.href);
} else {
console.log('Running inside the frame document', location.href,
[...document.querySelectorAll('*')]);
}
To simplify the scenario, lets say I'm working on an extension that just contains: alert("Hello") whenever you load a page in example.com. Relevant manifest.json part:
"content_scripts":
[
{
"matches": ["*://*.example.com/*"],
"js": ["script.js"]
}
]
When I first visit the website, it works fine. But the problem is some of the links in the website don't reload the page, they just manipulate the DOM. So a link for example will take you to example.com/foo, the script doesn't run. Even when I return to the home page, it doesn't run again, and all the edits that were made the first time are removed.
How do I make the add-on recognize that the page has changed, and rerun the script?
After spending hours on this, I was finally able to achieve what I want, though not in the way I expected it would be. This is my solution:
document.addEventListener("click", function(){
editStuff();
});
This works just fine for the website I'm making the add-on for. There is some wasted computational power, as some clicks don't really require the function to work again, but its minimal in my use case.
I'm working on a chrome extension that allows you to hide threads from a message board. I have it working, but the "Hide Me" link flickers into existence after the page loads. It works fine, but I'd like to load the link along with the rest of the DOM and not appear after the page load.
I tried adding "run_at": "document_start" to manifest.json, but it prevented the Hide Me link from even rendering.
$('a.topictitle').after(" | <a class='hideMe'>Hide Me</a>");
$('.hideMe').on('click', function(){
var thread = $(this).closest('li')
console.log(thread)
thread.remove()
});
Is this possible, or do I just have to deal with it happening after the fact?
According to this answer, $(function(){}) runs when the DOM is ready, so try that out.
=edit There's also document.addEventListener("DOMContentLoaded", function(event)
First of all, I am a newbie in chrome extension development. I am developing a chrome extension to collect user inputs from a form on a specific webpage.
In my manifest.json, I have added javascripts to be used for this purpose inside "content_scripts" and they are invoked when the matched URL loads. In my javsacript, I have added eventlisteners for triggering functions when a button is clicked.
The problem I am facing is that, evenlisteners work fine and the required functions get executed when the button is clicked for first time.
But when the button is clicked for second time, it does not trigger the listener.
Can anyone please recommend me a way to overcome this issue?
Content script part of my manifest.json:
"content_scripts": [
{
"matches": ["*://domain/pathtofile*"],
"all_frames": true,
"js": ["myscript.js"],
"run_at": "document_end"
}
]
And in "myscript.js", I use this:
document.getElementById("elementid").addEventListener("click", functiontocall);
Thank you
Sujith
------ Edit ------
Extension I am developing is for a specific client and this is an unlisted extension in chrome store. So I am not able to provide the URL due to NDA with client.
The URL (example: "http://www.domain.com/urlpath/form.php") has a DIV inside it, which contains an HTML form. So when this URL is loaded, it matches with the manifest and loads a javascript "myscript.js". In "myscript.js", I have written a code:
document.getElementById("formbuttonelement").addEventListener("click", getFormData);
The function "getFormData()" just contains basic javascripts to take values from each form element and prepare a query string and send to another PHP script ("collectForm.php") using AJAX.
After the form button is clicked, the DIV element will close. In the web page, there is a button to open this DIV (HTML form) again, and user can input data in form and click "formbuttonelement" again to submit form.
So, my problem is that, when I open the URL "http://www.domain.com/urlpath/form.php" for the first time, everything works as expected, including the addEventListener part and I can get the form data in "collectForm.php". And, as mentioned earlier, the DIV element will close.
But when the DIV is opened again (which does not load the URL again), addEventListener is not working. I presume that it is because the URL is not reloading, thereby not invoking "myscript.js" again.
I am looking for an option to restart event listener even if the web page is not reloaded.
I hope I have explained the situation.
Thanks & Regards
Sujith
In the following google chrome extension file why do i cannot use a jquery script inside myscript.js file,Is jquery not loaded inside myscript.js file, what changes should be done in manifest file to use jquery inside myscript.js
Manifest.json
{
"manifest_version": 2,
"name": "One-click Kittens",
"description": "This extension demonstrates a browser action with kittens.",
"version": "1.0",
"background": { "scripts": ["jquery-1.9.1.min.js","myscript.js"] },
"permissions": [
"tabs", "http://*/*"
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
}
}
myscript.js
alert($("#extension-command-list").val()); //undefined
alert($("#extension-command-list").html()); //undefined
$(document).ready(function() {
alert("hello world"); //not seen
});
EDIT:
"background": { "scripts": ["jquery-1.9.1.min.js"] },
"content_scripts": [
{
"matches": ["https://*/*"],
"js": ["myscript.js"] or "js": ["jquery-1.9.1.min.js","myscript.js"]
}
],
The reason you are getting undefined is becaus you are not specifying a background page.
So.. the background page Chrome generates, looks just like
<html>
<head></head>
<body>
<script src="jquery-1.9.1.min.js"></script>
<script src="myscript.js"></script>
</body>
</html>
As you see there isn't any Element which can be selected, thats why your first too alert's return undefined.
Anyway, the alert("hello world") should be shown too, as the DOMContentLoaded or similar should be fired any way.
Could it be that you want to select Elements of an site you are visiting ?
If so, you should put myscript.js in an Content Script instead of a background page.
There you get access to the DOM of the site.
So the question is, what are you up to ?
If you actually want to select Elements in your background page, you have to specify one,
Looking at the background pages site shows you, its as easy as:
{
"name": "My extension",
...
"background": {
"page": "background.html"
},
...
}
Edit:
"default_popup" : "popup.html"
Refers to a Browser Actions Popup. A browser Action is used
[...] to put icons in the main Google Chrome toolbar, to the right of the address bar. In addition to its icon, a browser action can also have a tooltip, a badge, and a popup.
So
If a browser action has a popup, the popup appears when the user clicks the icon. The popup can contain any HTML contents that you like, and it's automatically sized to fit its contents.
To add a popup to your browser action, create an HTML file with the popup's contents. Specify the HTML file in the default_popup field of browser_action in the manifest, or call the setPopup method.
"background":"{...}"
A common need for extensions is to have a single long-running script to manage some task or state. Background pages to the rescue.
As the architecture overview explains, the background page is an HTML page that runs in the extension process. It exists for the lifetime of your extension, and only one instance of it at a time is active.
Also has a background script access to all parts of the Chrome Extension's Api. chrome.* if you have requested the permissions respectively
Now lets say, you want to for example extend the ContextMenu of chrome with some functionalities.
To do this, you first have create a contextMenuEntry in the background page.
And just like your background page has only one instance of it running at a time, and that for the lifetime of the extension, so should your contextMenuEntry only have one instance of it, which gets created when your extension runs and remains for the lifetime of your extension.
Now assume you want to display the currently selected text of the page you are visiting in one of you Menu Entries.
To do that, you need access to the chrome.contextMenus API Method but a contentscript is not allowed to use this.
To get this to work you need to pass a message with the selected text to the background page through e.g. chrome.extension.sendMessage
In the background page you can then update your existing contextmenuentry to display the selected text.
sry i couldn't think of a better example right now