onClick в расширении Chrome не работает
это, кажется, самая простая вещь, чтобы сделать, но это просто не работает. В обычном браузере то .html и .JS файлы работают отлично, но в расширении Chrome onClick функция не выполняет то, что она должна делать.
.js file:
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". И снова - он отлично работает в браузере, но не работает в расширении. Вы знаете зачем? На всякий случай я прикрепляю манифест.JSON ниже, а также.
спасибо заранее!
манифест.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/"
]
}
3 ответов:
расширения Chrome не позволяют вам иметь встроенный JavaScript (документация). Вам придется сделать что-то похожее на это.
присвоить ID к ссылке (
<a onClick=hellYeah("xxx")>становится<a id="link">), и использоватьaddEventListenerдля привязки события. Поместите следующее в свойpopup.jsfile:document.addEventListener('DOMContentLoaded', function() { var link = document.getElementById('link'); // onClick's logic below: link.addEventListener('click', function() { hellYeah('xxx'); }); });
причина
это не работает, потому что Chrome запрещает любой вид встроенного кода в расширениях через политику безопасности контента.
встроенный JavaScript не будет выполняться. Это ограничение запрещает как inline
<script>блоки и встроенные обработчики событий (например,<button onclick="...">).как определить
если это действительно проблема, Chrome приведет к следующей ошибке консоль:
отказано в выполнении встроенного скрипта, поскольку он нарушает следующую директиву политики безопасности контента:"script-src 'self' chrome-extension-resource:". Либо ключевое слово 'unsafe-inline', хэш ('sha256-...'), или nonce ('nonce-...') требуется для включения встроенного выполнения.
чтобы получить доступ к консоли JavaScript всплывающего окна (что полезно для отладки в целом), щелкните правой кнопкой мыши кнопку вашего расширения и выберите" проверить всплывающее окно контекстное меню.
более подробная информация об отладке всплывающего окна доступна здесь.
как исправить
нужно удалить все встроенные JavaScript. Есть руководство в документации Chrome.
предположим, что оригинал выглядит так:
<a onclick="handler()">Click this</a> <!-- Bad -->нужно удалить
onclickатрибут и дать элементу уникальный идентификатор:<a id="click-this">Click this</a> <!-- Fixed -->а затем прикрепите прослушиватель из скрипта (который должно быть предположим
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событие. Это гарантирует, что элемент существует во время выполнения. Теперь добавьте тег script, например в<head>документ:<script src="popup.js"></script>альтернатива, если вы используете jQuery:
// jQuery $(document).ready(function() { $("#click-this").click(handler); });спокойного политика
Q: сообщение об ошибке упоминает способы, позволяющие встроенного кода. Я не хочу / не могу изменить свой код, как мне это сделать включить встроенные скрипты?
A: несмотря на то, что ошибка говорит, Вы не может включить встроенный скрипт:
нет механизма для ослабления ограничения на выполнение встроенного JavaScript. В частности, установка политики сценария, которая включает
'unsafe-inline'не будет иметь никакого эффекта.обновление: начиная с Chrome 46, можно включить в белый список определенный встроенный код блоки:
начиная с Chrome 46, встроенные скрипты могут быть занесены в белый список, указав в политике хэш исходного кода в кодировке base64. Этот хэш должен иметь префикс используемого хэш-алгоритма (sha256, sha384 или sha512). Смотрите использование хэша для
<script>элементов для примера.однако я не вижу причин использовать это, и он не будет включать встроенные атрибуты, такие как
onclick="code".
У меня была та же проблема, и я не хотел переписывать код, поэтому я написал функцию для изменения кода и создания встроенных объявленных событий:
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, "< custom_id='"+item_with_event.custom_id+"' "); } $(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 вместо этого.
Comments