问题
I'm trying to make a chrome extension that replaces the last word typed in the current <textarea>
when the user makes a certain keydown
event fire. So I've tried this but it doesn't really work.
Here are the files of my extension:
My extension's manifest.json
:
{
"name": "Test",
"description": "test",
"version": "0.0.1",
"permissions": [
"activeTab"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_title": "replace test"
},
"manifest_version": 2
}
Its background.js
:
chrome.tabs.executeScript(null, {file: "content_script.js"});
And its content_script.js
:
document.onkeydown = replacePrevWord;
// Azerty: Ctrl + ²
// Qwerty: Ctrl + '
function KeyPress(e) {
var evtobj = window.event? event : e
if (evtobj.keyCode == 222 && evtobj.ctrlKey)
return true;
}
function getCaretPosition(ctrl) {
var CaretPos = 0; // IE Support
if (document.selection) {
ctrl.focus();
var Sel = document.selection.createRange();
Sel.moveStart('character', -ctrl.value.length);
CaretPos = Sel.text.length;
}
// Firefox support
else if (ctrl.selectionStart || ctrl.selectionStart == '0')
CaretPos = ctrl.selectionStart;
return (CaretPos);
}
function returnWord(text, caretPos) {
var index = text.indexOf(caretPos);
var preText = text.substring(0, caretPos);
if (preText.indexOf(" ") > 0) {
var words = preText.split(" ");
return words[words.length - 1]; //return last word
}
else {
return preText;
}
}
function replacePrevWord() {
if(KeyPress()){
var text = document.activeElement;
var caretPos = getCaretPosition(text)
var word = returnWord(text.value, caretPos);
if (word != null) {
text.value = text.value.replace(word,"replaced");
}
}
}
This works fine on JSFiddle (http://jsfiddle.net/cyo646cr/3/), but I don't know how to do this in a Chrome extension.
Any ideas?
Thanks.
回答1:
Issue
You are not injecting the script correctly. It's easy to say, because calling this simple line
chrome.tabs.executeScript(null, {file: "content_script.js"});
in your background.js
will result in injecting the script only one time and in the current tab (because no tabId is specified). Therefore your script will run only once for every session of Google Chrome in the first tab you open.
Take a look at the documentation for chrome.tabs.executeScript.
Work around
To work around this problem you've got two options:
- Declare the
"content_scripts"
field in yourmanifest.json
so it will be injected in any page that matches a pattern. - Add a listener with the
chrome.tabs.onUpdated.addListener
method and inject the script on the tab.
Option 1
Declare the "content_scripts"
field in your manifest.json
like this:
...
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content_script.js"],
"run_at": "document_idle",
"all_frames": true
}
],
...
Now your content script will be injected in every page (because "<all_urls>"
will match all the pages) and in all the frames of the pages. You can find helpful informations about the "content_scripts"
here.
Option 2
Request the permissions for the chrome.tabs
API and the URLs you want in your manifest.json
:
...
"permissions": [
"activeTab",
"tabs",
"<all_urls>"
]
...
In your background.js
, add a listener to chrome.tabs.onUpdated
, which will fire on every tab update (i.e. url update), and inject your script using chrome.tabs.executeScript
, like this:
chrome.tabs.onUpdated.addListener(function(tabID, info, tab) {
chrome.tabs.executeScript(tabID, {file: "content_script.js"});
});
See the documentation for chrome.tabs.onUpdated.
来源:https://stackoverflow.com/questions/26335530/chrome-extension-replace-word-in-current-textarea