kkm*_*our 7 html javascript google-chrome-extension firefox-addon-webextensions
我的Chrome扩展程序弹出窗口中有一个文本区域和一个按钮.我希望用户在文本区域中输入所需的文本.然后,一旦他们点击该按钮,它将注入一个内容脚本,以更改当前页面上的字段<textarea class="comments">文本,该文本必须是用户<textarea>在Chrome扩展程序弹出窗口中输入的文本.
我的问题是,我怎样才能从文本<textarea>中我popup.html,并从它传递popup.js的内容脚本?
这就是我目前所拥有的:
popup.html:
<!doctype html>
<html>
<head><title>activity</title></head>
<body>
<button id="clickactivity3">N/A</button>
<textarea rows="4" cols="10" id="comments" placeholder="N/A Reason..."></textarea>
<script src="popup.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
popup.js:
function injectTheScript3() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
// query the active tab, which will be only one tab
//and inject the script in it
chrome.tabs.executeScript(tabs[0].id, {file: "content_script3.js"});
});
}
document.getElementById('clickactivity3').addEventListener('click', injectTheScript3);
Run Code Online (Sandbox Code Playgroud)
content_script3:
//returns a node list which is good
var objSelectComments = document.querySelectorAll('.comments');
//desired user input how?
function setCommentsValue(objSelectComments,){
//This will be for loop to iterate among all the text fields on the page, and apply
// the text to each instance.
for (var i=0; i<objSelectComments.length; i++) {
objSelectComments[i]= //user's desired text
}
Run Code Online (Sandbox Code Playgroud)
Mak*_*yen 15
有三种一般方法可以做到这一点:
chrome.storage.local(MDN)传递数据(在注入脚本之前设置).chrome.storage.local(在执行脚本之前设置)使用此方法可以维护您正在使用的执行范例,即注入执行函数的脚本然后退出.它也没有使用动态值来构建执行代码的潜在安全问题,这在下面的第二个选项中完成.
从弹出脚本:
chrome.storage.local.set()(MDN)存储数据chrome.storage.local.set(),调用tabs.executeScript()(MDN)var updateTextTo = document.getElementById('comments').value;
chrome.storage.local.set({
updateTextTo: updateTextTo
}, function () {
chrome.tabs.executeScript({
file: "content_script3.js"
});
});
Run Code Online (Sandbox Code Playgroud)
从您的内容脚本:
chrome.storage.local.get()(MDN)读取数据storage.local(例如,删除密钥:chrome.storage.local.remove()(MDN)).chrome.storage.local.get('updateTextTo', function (items) {
assignTextToTextareas(items.updateTextTo);
chrome.storage.local.remove('updateTextTo');
});
function assignTextToTextareas(newText){
if (typeof newText === 'string') {
Array.from(document.querySelectorAll('textarea.comments')).forEach(el => {
el.value = newText;
});
}
}
Run Code Online (Sandbox Code Playgroud)
见:注1和2.
在执行脚本之前,您可以注入一些代码,这些代码在内容脚本上下文中设置一个变量,然后主脚本可以使用该代码:
安全问题:
以下用于"'" + JSON.stringify().replace(/\\/g,'\\\\').replace(/'/g,"\\'") + "'"将数据编码为文本,在将其解释为代码之前将其作为正确的JSON,然后再将其放入code字符串中..replace()需要这些方法A)在用作代码时将文本正确解释为字符串,并且B)引用'数据中存在的任何文本.然后,它JSON.parse()用于将数据返回到内容脚本中的字符串.虽然此编码并非严格要求,但最好不要知道要发送到内容脚本的值的内容.这个值可能很容易破坏你注入的代码(即用户可能正在使用'和/或"在他们输入的文本中).如果不以某种方式逃避该值,则存在可能导致执行任意代码的安全漏洞.
从弹出脚本:
chrome.tabs.executeScript()(MDN)的回调中,调用tabs.executeScript()注入脚本(注意:tabs.executeScript()将按照您调用的顺序执行脚本tabs.executeScript(),只要它们具有相同的值runAt.因此,等待小的回调code不是严格要求的).var updateTextTo = document.getElementById('comments').value;
chrome.tabs.executeScript({
code: "var newText = JSON.parse('"
+ JSON.stringify(updateTextTo).replace(/\\/g,'\\\\').replace(/'/g,"\\'") + "';"
}, function () {
chrome.tabs.executeScript({
file: "content_script3.js"
});
});
Run Code Online (Sandbox Code Playgroud)
从您的内容脚本:
if (typeof newText === 'string') {
Array.from(document.querySelectorAll('textarea.comments')).forEach(el => {
el.value = newText;
});
}
Run Code Online (Sandbox Code Playgroud)
请参阅:注释1,2和3.
这需要您的内容脚本代码为弹出窗口或后台脚本发送的消息安装监听器(如果与UI的交互导致弹出窗口关闭).它有点复杂.
从弹出脚本:
tabs.query()(MDN)确定活动选项卡.tabs.executeScript()(MDN)tabs.executeScript(),使用tabs.sendMessage()(MDN)(需要知道tabId),将数据作为消息发送.var updateTextTo = document.getElementById('comments').value;
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {
file: "content_script3.js"
}, function(){
chrome.tabs.sendMessage(tabs[0].id,{
updateTextTo: updateTextTo
});
});
});
Run Code Online (Sandbox Code Playgroud)
从您的内容脚本:
chrome.runtime.onMessage.addListener()(MDN)添加侦听器runtime.onMessage听众#3.2是可选的.您可以使代码保持活动状态等待另一条消息,但这会将您正在使用的范例更改为加载代码的范例,并且它会驻留在等待消息启动操作的驻留位置.
chrome.runtime.onMessage.addListener(assignTextToTextareas);
function assignTextToTextareas(message){
newText = message.updateTextTo;
if (typeof newText === 'string') {
Array.from(document.querySelectorAll('textarea.comments')).forEach(el => {
el.value = newText;
});
}
chrome.runtime.onMessage.removeListener(assignTextToTextareas); //optional
}
Run Code Online (Sandbox Code Playgroud)
见:注1和2.
注意1:Array.from()如果您没有多次使用并使用具有它的浏览器版本(Chrome> =版本45,Firefox> = 32),则使用正常.在Chrome和Firefox中,Array.from()与从NodeList获取数组的其他方法相比,速度较慢.要更快,更兼容地转换为数组,您可以使用此答案中的asArray()代码.该答案中提供的第二个版本也更强大.asArray()
注意2:如果您愿意将代码限制为Chrome版本> = 51或Firefox版本> = 50,则Chrome有一个自v51 以来的NodeListsforEach()方法.因此,您不需要转换为数组.显然,如果使用不同类型的循环,则不需要转换为数组.
注3:虽然我以前在我自己的代码中使用过这种方法(用变量值注入一个脚本),但我还是提醒一下,在阅读这个答案时我应该把它包含在这里.
| 归档时间: |
|
| 查看次数: |
3256 次 |
| 最近记录: |