问题
Context:
- Writing a google chrome extension using JavaScript
- Using context menus library
- User should be able to right click into a textbox, select chrome extension, select "insert text", and then that text will get inserted into the selected text box.
- I am using pure javascript, please no jquery or AJAX.
- I am unable to edit the HTML page as it could be any generic web page with an HTML text box or editable field.
Code I have so far:
//the menu item
var menuItem_insert = chrome.contextMenus.create({"title": "Insert Timestamp", "contexts":[context], "onclick:": insertTimestamp});
//the onclick
function insertTimestamp(info, tab) {
//if info.editable is true then
alert(info.editable); //for debugging
//CODE GOES HERE: need to insert timestamp here
}
Question: How do I insert text into a selected textbox for which I may not have the "ID" for?
回答1:
avril alejandro answer is good, this is a different approach to solve the problem
Logic is, when user clicks your context menu item, menu will disappear and focus is back right where you need it, on origin element from which right click started (also from any point in that element if user clicked somewhere in the middle of existing text)
All you need to do is simulate copy/paste action.
so, in background script:
- in your
onClicked
listener createtextarea
- fill it with value you want to insert (date string in this example)
- focus it and select it
- use
document.execCommand('Copy')
to puttaxarea
value into clipboard - if click started from iframe, make sure you target only that frame, to avoid multiple script insertion and errors
- inject script into sender tab (you have all the info from
onClicked
listener) - injected script will do only one thing, pasting what was is in the clipboard
document.execCommand('paste')
background.js
chrome.contextMenus.onClicked.addListener(function(info, tab) {
var tArea = document.createElement('textarea'), _frame = null, date = new Date();
document.body.appendChild(tArea);
tArea.value = date.toLocaleString();
tArea.focus();
tArea.select();
document.execCommand('copy');
if(info.frameId) _frame = info.frameId;
chrome.tabs.executeScript(tab.id, {frameId: _frame, matchAboutBlank: true, code:
"document.execCommand('paste');"
}, function() {
if (chrome.runtime.lastError) console.log(chrome.runtime.lastError);
document.body.removeChild(tArea);
});
});
in your manifest add "clipboardWrite", "clipboardRead", "activeTab"
permissions
I'm using this logic in my Opera notes extension.
I never saw anyone using this trick, and it's very simple, plus it will remove all the hassle with targeting the right element, selections, ranges, rich text editors ...etc
回答2:
Through document.activeElement you can refer to the current active element:
document.activeElement.value = 'My value';
should put the "My value" string inside the input text you have selected at the moment of the invocation.
Unfortunately in your case you want that to happen after you click a button, so your active element will become your button at the moment of the click.
So you can find as workaround to define the element onblur
of your text input, so that clicking to the button you will refer to that input text.
So this is the HTML
<div>
<input type="text" onblur="trackElement(this)" />
<button onclick="test()">
Test
</button>
</div>
And this is the JS:
var myTxt = null;
function test() {
if (myTxt != null) {
myTxt.value = 'my value';
}
}
function trackElement(el) {
console.log(el);
myTxt = el;
}
https://jsfiddle.net/2459g8z5/4/
回答3:
according this reply
You can inject content script with mousedown
event listener and store element that was clicked:
manifest.json
..
"permissions": ["contextMenus"],
"background": {
"scripts": ["./bg.js"]
},
"content_scripts": [{
"js": ["./content.js"],
"matches": ["<all_urls>", "http://*/*" , "https://*/*", "file:///"],
"run_at": "document_end"
}],
"manifest_version": 2
..
background.js
function mycallback(info, tab) {
if (info.editable) {
chrome.tabs.sendMessage(tab.id, {
"text": "TEXT GOES HERE"
});
}
}
chrome.contextMenus.create({
title: "Insert Timestamp",
contexts: ["editable"],
onclick: mycallback
});
content.js
var clickedEl = null;
document.addEventListener("mousedown", function (event) {
//right click
if (event.button == 2) {
clickedEl = event.target;
}
}, true);
chrome.runtime.onMessage.addListener(function (request) {
clickedEl.value = request.text;
});
来源:https://stackoverflow.com/questions/43966106/how-to-insert-text-into-selected-textbox-in-javascript-without-id