- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在创建一个扩展,我需要能够在单击页面操作按钮时多次运行内容脚本。我的 background.js 中有这个:
chrome.pageAction.onClicked.addListener(function(tab) {
alert('calling content_script');
chrome.tabs.executeScript(null, {
file: 'content_script.js'
},function(){alert("success");});
});
这在第一次单击按钮时有效。第二次单击时,弹出窗口显示“正在调用 content_script”,但内容脚本从未执行过。这是为什么?
完整的后台脚本如下:
function checkForValidUrl(tabId, ChangeInfo, tab){
if(tab.url.indexOf("tiger.armstrong")> -1){
chrome.pageAction.show(tabId);
if(tab.url.indexOf("tiger.armstrong") == 0){
chrome.pageAction.hide(tabId);
}
}
}
chrome.tabs.onUpdated.addListener(checkForValidUrl);
chrome.pageAction.onClicked.addListener(function(tab) {
alert('calling content_script');
chrome.tabs.executeScript(null, {
file: 'content_script.js'
},function(){alert("success");});
});
这是 list :
{
"name": "LiveLab Post Grades",
"version": "2.0",
"permissions": [
"activeTab","tabs","http://*/*","https://*/*"
],
"background": {
"scripts": ["jquery.min.js","background3.js"],
"persistent": false
},
"page_action": {
"default_icon": {
"19": "GIcon.png"
},
"default_title": "LiveLab Tools"
},
"content_scripts": [ {
"js": [ "jquery.min.js" ],
"matches": [ "http://*/*", "https://*/*"],
"run_at": "document_end"
}],
"manifest_version": 2
}
这是内容脚本:
var livelabtools = {
/**
* this function is like window.open, but it can POST (rather than GET) from js
* source: http://canop.org/blog/?p=426
*/
canop_open: function (verb, url, data, target) {
var form = document.createElement("form");
form.action = url;
form.method = verb;
form.target = target || "_self";
if (data) {
//for (var key in data) {
var input = document.createElement("input");
input.name = 'data';
input.value = data;//typeof data[key] === "object" ? JSON.stringify(data[key]) : data[key];
form.appendChild(input);
//console.log(form);
//}
}
// these two lines are only needed for ie
//form.style.display = 'none';
//document.body.appendChild(form);
form.submit();
console.log("form submit === " + form);
form.remove();
},
post_grades: function () {
alert('in post grades!!!!');
var str, exercise,
i = 0;
grades = {};
do {
ex_str = "form1:tabSet1:tabInstr:lp2:tabSet4:tabp:lpProgress:ts1:tab7:lp7:table3:rg3:" + i + ":tc3:st3";
lname_str = "form1:tabSet1:tabInstr:lp2:tabSet4:tabp:lpProgress:ts1:tab7:lp7:table3:rg3:" + i + ":tc1:st1";
grade_str = "form1:tabSet1:tabInstr:lp2:tabSet4:tabp:lpProgress:ts1:tab7:lp7:table3:rg3:" + i + ":tc7:st7_field";
exercise = document.getElementById(ex_str);
lname = document.getElementById(lname_str);
grade = document.getElementById(grade_str);
if (exercise != null) {
if (grades[lname.innerHTML] === undefined)
grades[lname.innerHTML] = {};
console.log(lname.innerHTML + ", " + exercise.innerHTML + ", " + grade.innerHTML);
if (grade.value != null && grade.value != '')
grades[lname.innerHTML][exercise.innerHTML] = grade.value;
else
grades[lname.innerHTML][exercise.innerHTML] = "0";
}
i++;
} while (exercise != null);
// console.log(JSON.stringify(grades));
// console.log(JSON.stringify(grades).length)
//window.open("http://aspen2.cscofc.info/jsontocsv.php?data="+JSON.stringify(grades));
console.log('posting...' + "\n JSON.String... = "+ JSON.stringify(grades));
livelabtools.canop_open("post", "http://aspen2.cscofc.info/jsontocsv.php", JSON.stringify(grades));
console.log('done');
return "function end";
}
}
console.log(livelabtools.post_grades());
除非有人问,否则我不会详细介绍,但要注意的重要部分是返回语句和控制台日志。第一次单击页面操作按钮时,一切都运行良好,完成后,我将“功能结束”打印到控制台。然而,在初始运行之后,每当我单击页面操作按钮时,我都会收到一条提示“正在调用 content_script”,并且没有其他任何反应。为什么我的内容脚本不会运行多次?
最佳答案
似乎当脚本已经被注入(inject)时,它不会再次被注入(inject)。
因此,要走的路是通过将消息传递给内容脚本来启动您的操作。 (当然,如果content script还没有注入(inject),需要先注入(inject)。)
我想到的一个解决方案(经过测试确认它工作正常)如下:
在 pageAction.onClicked
上,从后台页面向内容脚本发送一条消息,要求它做某事(例如发布成绩)。另外,请求响应发送回后台页面。
[另见 chrome.tabs.sendMessage(...) .]
如果内容脚本已经被注入(inject),让它接收消息,将确认发送回后台页面并继续做一些事情(例如发布成绩)。您可以根据需要多次执行此过程。
[另见 chrome.runtime.onMessage .]
第一次触发 pageAction.onClicked
时,不会有内容脚本监听消息。在这种情况下,将不会有消息确认。而是 chrome.runtime.lastError 将被设置。那样的话,后台页面就得先注入(inject)内容脚本,然后再发送消息。
[另见 chrome.runtime.lastError .]
从理论上讲,应该可以!
实际上,这是对我有用的示例代码:
list .json:(注意:如果您对需要访问的页面有更具体的要求,您可以将它们合并到 list 中并删除一些权限。)
{
...
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"page_action": {
"default_title": "Test Extension"
},
"permissions": [
"tabs",
"http://*/*",
"https://*/*"
]
...
}
background.js:
function checkForValidURL(tabId, info, tab) {
var idx = tab.url.indexOf("tiger.armstrong");
if (idx > 0) {
chrome.pageAction.show(tabId);
} else {
chrome.pageAction.hide(tabId);
}
}
chrome.tabs.onUpdated.addListener(checkForValidURL);
function onPageActionClicked(tab) {
// Send message to content script, asking to post grades
alert("Calling content_script...");
chrome.tabs.sendMessage(tab.id, { action: "postGrades" }, function() {
if (chrome.runtime.lastError) {
// The error indicates that the content script
// has not been injected yet. Inject it and...
chrome.tabs.executeScript(tab.id, {
file: "content.js"
}, function() {
if (!chrome.runtime.lastError) {
// ...if injected successfully, send the message anew
onPageActionClicked(tab);
}
});
} else {
// The content script called our response callback,
// confirming that it is there and got our message
alert("Message got through !");
}
});
};
chrome.pageAction.onClicked.addListener(onPageActionClicked);
content.js:
var livelabtools = {
/**
* This function is like window.open, but it can POST (rather than GET) from
* JS source: http://canop.org/blog/?p=426
*/
canop_open: function (method, url, data, target) {
var form = document.createElement("form");
form.action = url;
form.method = method;
form.target = target || "_self";
// 'data' is an object with key-value pairs
// of fields to be sent
if (data) {
for (var key in data) {
var input = document.createElement("input");
input.name = key;
input.value = (typeof(data[key]) === "object")
? JSON.stringify(data[key]) : data[key];
form.appendChild(input);
}
}
form.submit();
form.remove();
},
post_grades: function () {
console.log("Posting some grades...");
livelabtools.canop_open("POST",
"http://aspen2.cscofc.info/jsontocsv.php",
"{}");
console.log("Grades sent !");
}
}
// Listen for messages from the background page
// (It actually listens for messages from anyone in the context,
// but the background page is the one that interrests us)
chrome.runtime.onMessage.addListener(function(msg, sender, response) {
// If we've been asked to post grades...
if (msg.action && (msg.action == "postGrades")) {
// ...confirm we got the message and...
response();
// ...do what we do best: post grades !
livelabtools.post_grades();
}
});
让我们希望这涵盖了它:)
关于javascript - 每次单击页面操作按钮时,Chrome 扩展都不会运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19555483/
所以我有这个 javascript 片段,它有两个按钮可以进入全屏,一个按钮可以退出全屏。我想做到这一点,如果我不在全屏模式下,按钮会显示转到全屏模式,而当我处于全屏模式时,按钮会显示退出全屏模式..
我在自定义控件中添加了一个新属性作为可扩展属性,例如属性网格中的字体属性。在 Windows 窗体应用程序项目中使用我的自定义控件后,我在属性网格中看到一个省略号 (…) 按钮,如字体属性的“…”按钮
我在自定义控件中添加了一个新属性作为可扩展属性,例如属性网格中的字体属性。在 Windows 窗体应用程序项目中使用我的自定义控件后,我在属性网格中看到一个省略号 (…) 按钮,如字体属性的“…”按钮
我尝试将 Twitter 上的“Tweet Me”按钮 ( http://twitter.com/goodies/tweetbutton ) 添加到我的网站。然而,每当按下按钮时,我都会收到此 Jav
我试图在我的文本区域中获取一个按钮值,如果我使用 则工作正常但如果我使用那么它就不起作用了。你能找出问题所在吗? HTML 1 2 3 4 JavaScript $(document).read
我的 C# Winform 面板中有一堆文本框。每行文本框的命名如下: tb1 tbNickName1 comboBox1 tb2 tbNickName2 comboBox2 tb3 tbNickNa
我有一个表单,其中过滤器下方有按钮(应用过滤器和清除过滤器),我试图在单击“应用”按钮时显示“清除”,并在单击“清除”按钮时隐藏“清除”按钮。 下面的代码(如果我的表有的话):
excel 按钮正在工作,但是当我添加 pdf 按钮时,它添加仅显示 pdf 按钮 excel 按钮在 pdf 按钮添加后隐藏 $(document).ready(function() { $
我想创建一个 div 作为标题并分成 3 列,并按以下顺序在其中放置 2 个按钮和一个标题:Button1(左位) Title(居中) Button2(右位) 这是我为这个 div 编写的代码:
仅当选中所有框时才应禁用“允许”按钮。我该怎么做?我已经完成了 HTML 部分,如下所示。如何执行其中的逻辑部分?即使未选中一个复选框,也应禁用“允许”按钮
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
如您所知,您可以使用 2 种方法在 HTML5 中呈现按钮: 使用 void 元素 或 如果您需要内容,请使用 元素(不是空元素)。 在JSF2中,有2种方式生成按钮;与UICommand或 UIOu
我尝试根据表单元素的更改禁用/启用保存按钮。但是,当通过弹出按钮选择更改隐藏输入字段值时,保存按钮不受影响。 下面是我的代码。我正在尝试序列化旧的表单值并与更改后的表单值进行比较。但我猜隐藏的字段值无
我有用于在消息(电子邮件、短信)上输入内容的 EditText。我希望在单击 ActionDone 按钮时立即发布消息。我为此使用以下代码: message.setOnEditorActionList
我的 Android 应用程序中有一堆 EditText,每个都将 InputMethod 设置为 numberSigned。我的目标设备没有硬件键盘,而是使用软件键盘输入数字。 Android 将输
我无法以编程方式隐藏弧形菜单中的 fab 按钮。我正在使用https://github.com/saurabharora90/MaterialArcMenu在我的代码中。如何在Java中以编程方式隐藏
我已经看到这在其他类型的对话框窗口中是可能的,例如“showConfirmDialog”,其中可以指定按钮的数量及其名称;但是使用“showInputDialog”时是否可以实现相同的功能?我似乎无法
相同的按钮用于激活和停用。第一次,当代码运行按钮单击并成功“停用”时。但第二次,代码无法找到该元素。第一个案例按钮位于第二个“a”标签中,然后停用第一个“a”标签中的按钮。 案例1: Edit
是否可以将按钮的 onclick 操作设置为 JavaScript 变量?这个想法是我们用 JavaScript 控制一个表。每当点击该表的一行时,我们就会更新一个 JavaScript 变量。该 v
我想创建一个按钮,它包含左侧的文本和右侧的复选框(或任何其他组件)。我怎样才能做到这一点? 我发现我可以制作自己的 View extends Button,但是如果可以的话我应该如何实现 onDraw
我是一名优秀的程序员,十分优秀!