这似乎是最简单的事情,但它只是不起作用。在普通浏览器中,.html和.js文件运行正常,但在Chrome扩展程序中,onClick
功能无法执行预期的操作。
.js文件:
function hellYeah(text) {
document.getElementById("text-holder").innerHTML = text;
}
.html文件:
<!doctype html>
<html>
<head>
<title>
Getting Started Extension's Popup
</title>
<script src="popup.js"></script>
</head>
<body>
<div id="text-holder">
ha
</div>
<br />
<a onClick=hellYeah("xxx")>
hyhy
</a>
</body>
</html>
所以基本上一旦用户点击“hyhy”,“ha”应该变成“xxx”。再次 - 它在浏览器中完美运行,但在扩展中不起作用。你知道为什么吗?以防我在下面附上manifest.json。
提前致谢!
的manifest.json:
{
"name": "My First Extension",
"version": "1.0",
"manifest_version": 2,
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"http://api.flickr.com/"
]
}
答案 0 :(得分:109)
Chrome扩展程序不允许您使用内联JavaScript(documentation)。你将不得不做类似的事情。
为链接分配ID(<a onClick=hellYeah("xxx")>
变为<a id="link">
),并使用addEventListener
绑定事件。将以下内容放在popup.js
文件中:
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementById('link');
// onClick's logic below:
link.addEventListener('click', function() {
hellYeah('xxx');
});
});
答案 1 :(得分:36)
这不起作用,因为Chrome forbids any kind of inline code通过内容安全政策进行了扩展。
不会执行内联JavaScript。此限制禁止内联
<script>
块和内联事件处理程序(例如<button onclick="...">
)。
如果这确实是问题,Chrome会在控制台中产生以下错误:
拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“script-src'self'chrome-extension-resource:”。要启用内联执行,需要使用'unsafe-inline'关键字,散列('sha256 -...')或nonce('nonce -...')。
要访问弹出窗口的JavaScript控制台(通常对调试很有用),请右键单击扩展程序的按钮,然后从上下文菜单中选择“检查弹出窗口”。
有关调试弹出窗口的更多信息,请访问here。
需要删除所有内联JavaScript。有a guide in Chrome documentation。
假设原件如下:
<a onclick="handler()">Click this</a> <!-- Bad -->
需要删除onclick
属性并为元素提供唯一ID:
<a id="click-this">Click this</a> <!-- Fixed -->
然后从脚本(必须在.js
文件中,假设popup.js
)附加侦听器:
// Pure JS:
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("click-this").addEventListener("click", handler);
});
// The handler also must go in a .js file
function handler() {
/* ... */
}
请注意DOMContentLoaded
事件中的换行。这确保了元素在执行时存在。现在添加脚本标记,例如在文档的<head>
中添加:
<script src="popup.js"></script>
如果您使用的是jQuery,请选择
// jQuery
$(document).ready(function() {
$("#click-this").click(handler);
});
问:该错误提到了允许内联代码的方法。我不想/不能更改我的代码,如何启用内联脚本?
答:尽管错误说明了,但您cannot enable inline script:
没有放松对执行内联JavaScript的限制的机制。特别是,设置包含
'unsafe-inline'
的脚本策略将不起作用。
更新:自Chrome 46以来,可以将特定内联代码块列入白名单:
从Chrome 46开始,可以通过在策略中指定源代码的base64编码哈希来将内联脚本列入白名单。此哈希必须以使用的哈希算法(sha256,sha384或sha512)作为前缀。有关示例,请参阅Hash usage for
<script>
elements。
但是,我没有看到使用此功能的原因,也不会启用onclick="code"
等内联属性。
答案 2 :(得分:2)
如前所述,由于安全原因,Chrome扩展程序不允许使用内联JavaScript,因此您也可以尝试这种解决方法。
HTML文件
<!doctype html>
<html>
<head>
<title>
Getting Started Extension's Popup
</title>
<script src="popup.js"></script>
</head>
<body>
<div id="text-holder">ha</div><br />
<a class="clickableBtn">
hyhy
</a>
</body>
</html>
<!doctype html>
popup.js
window.onclick = function(event) {
var target = event.target ;
if(target.matches('.clickableBtn')) {
var clickedEle = document.activeElement.id ;
var ele = document.getElementById(clickedEle);
alert(ele.text);
}
}
或者如果您包含一个Jquery文件,那么
window.onclick = function(event) {
var target = event.target ;
if(target.matches('.clickableBtn')) {
alert($(target).text());
}
}
答案 3 :(得分:1)
我遇到了同样的问题,并且不想重写代码,因此我编写了一个函数来修改代码并创建内联声明的事件:
function compile(qSel){
var matches = [];
var match = null;
var c = 0;
var html = $(qSel).html();
var pattern = /(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/mg;
while (match = pattern.exec(html)) {
var arr = [];
for (i in match) {
if (!isNaN(i)) {
arr.push(match[i]);
}
}
matches.push(arr);
}
var items_with_events = [];
var compiledHtml = html;
for ( var i in matches ){
var item_with_event = {
custom_id : "my_app_identifier_"+i,
code : matches[i][5],
on : matches[i][3],
};
items_with_events.push(item_with_event);
compiledHtml = compiledHtml.replace(/(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/m, "<$2 custom_id='"+item_with_event.custom_id+"' $7 $8");
}
$(qSel).html(compiledHtml);
for ( var i in items_with_events ){
$("[custom_id='"+items_with_events[i].custom_id+"']").bind(items_with_events[i].on, function(){
eval(items_with_events[i].code);
});
}
}
$(document).ready(function(){
compile('#content');
})
这应该从所选节点中删除所有内联事件,并使用jquery重新创建它们。
答案 4 :(得分:0)
我决定发布我在案例中使用的示例。我试图使用脚本替换div中的内容。我的问题是Chrome无法识别/未运行该脚本。
更详细的说明我想做什么:单击一个链接,然后该链接“读取”一个外部html文件,它将被加载到div部分中。
该脚本必须使用被告知的document.addEventListener('DOMContentLoaded',function()进行编码
<body>
<a id=id_page href ="#loving" onclick="load_services()"> loving </a>
<script>
// This script MUST BE under the "ID" that is calling
// Do not transfer it to a differ DIV than the caller "ID"
document.getElementById("id_page").addEventListener("click", function(){
document.getElementById("mainbody").innerHTML = '<object data="Services.html" class="loving_css_edit"; ></object>'; });
</script>
</body>
<div id="mainbody" class="main_body">
"here is loaded the external html file when the loving link will
be clicked. "
</div>