Сценарії вмісту виконуються в середовищі "ізольованого світу" . Ви повинні ввести свій state()
метод у саму сторінку.
Коли ви хочете використовувати один із chrome.*
API в скрипті, вам потрібно застосувати спеціальний обробник подій, як описано в цій відповіді: Розширення Chrome - отримання вихідного повідомлення Gmail .
В іншому випадку, якщо вам не потрібно використовувати chrome.*
API, я настійно рекомендую вставити весь свій JS-код на сторінку, додавши <script>
тег:
Зміст
- Спосіб 1: Вставте інший файл
- Спосіб 2: Вставте вбудований код
- Спосіб 2б: Використання функції
- Спосіб 3: Використання вбудованої події
- Динамічні значення введеного коду
Спосіб 1: Вставте інший файл
Це найпростіший / найкращий метод, коли у вас багато коду. Скажімо, включіть власний код JS у файл у своєму розширенні, скажімо script.js
. Тоді нехай ваш сценарій вмісту буде наступним (пояснено тут: Google Chome "Ярлик програми" Спеціальний Javascript ):
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
Примітка. Якщо ви використовуєте цей метод, script.js
до "web_accessible_resources"
розділу ( приклад ) потрібно додати введений файл . Якщо цього не зробити, Chrome відмовиться завантажувати ваш сценарій та відображатиме таку помилку на консолі:
Заперечення завантаження хромованого розширення: // [EXTENSIONID] /script.js. Ресурси повинні бути вказані в маніфестному веб-ключі web_accessible_resources для завантаження сторінок поза розширенням.
Спосіб 2: Вставте вбудований код
Цей метод корисний, коли потрібно швидко запустити невеликий фрагмент коду. (Див. Також: Як відключити гарячі клавіші facebook із розширенням Chrome? ).
var actualCode = `// Code here.
// If you want to use a variable, use $ and curly braces.
// For example, to use a fixed random number:
var someFixedRandomValue = ${ Math.random() };
// NOTE: Do not insert unsafe variables in this way, see below
// at "Dynamic values in the injected code"
`;
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Примітка: літералі шаблону підтримуються лише в Chrome 41 і вище. Якщо ви хочете, щоб розширення працювало в Chrome 40-, використовуйте:
var actualCode = ['/* Code here. Example: */' + 'alert(0);',
'// Beware! This array have to be joined',
'// using a newline. Otherwise, missing semicolons',
'// or single-line comments (//) will mess up your',
'// code ----->'].join('\n');
Спосіб 2б: Використання функції
Для великого фрагмента коду цитування рядка неможливо. Замість використання масиву можна використовувати функцію та строфікувати:
var actualCode = '(' + function() {
// All code is executed in a local scope.
// For example, the following does NOT overwrite the global `alert` method
var alert = null;
// To overwrite a global variable, prefix `window`:
window.alert = null;
} + ')();';
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Цей метод працює, оскільки +
оператор на рядках і функція перетворює всі об'єкти в рядок. Якщо ви плануєте використовувати код не один раз, розумно створити функцію, щоб уникнути повторення коду. Реалізація може виглядати так:
function injectScript(func) {
var actualCode = '(' + func + ')();'
...
}
injectScript(function() {
alert("Injected script");
});
Примітка: Оскільки функція серіалізована, початкова область дії та всі пов'язані властивості втрачаються!
var scriptToInject = function() {
console.log(typeof scriptToInject);
};
injectScript(scriptToInject);
// Console output: "undefined"
Спосіб 3: Використання вбудованої події
Іноді ви хочете одразу запустити якийсь код, наприклад, запустити якийсь код до створення <head>
елемента. Це можна зробити, вставивши <script>
тег за допомогою textContent
(див. Метод 2 / 2b).
Альтернативою, але не рекомендується, є використання вбудованих подій. Це не рекомендується, оскільки якщо на сторінці визначена політика безпеки вмісту, яка забороняє вбудовані сценарії, тоді слухачі вбудованих подій блокуються. Вбудовані сценарії, введені розширенням, з іншого боку, все ще працюють. Якщо ви все ще хочете використовувати вбудовані події, ось так:
var actualCode = '// Some code example \n' +
'console.log(document.documentElement.outerHTML);';
document.documentElement.setAttribute('onreset', actualCode);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');
Примітка. Цей метод передбачає, що немає інших глобальних слухачів подій, які б обробляли reset
подію. Якщо є, ви також можете вибрати одну з інших глобальних подій. Просто відкрийте консоль JavaScript (F12), введіть document.documentElement.on
і виберіть доступні події.
Динамічні значення введеного коду
Інколи ін'єктованій функції потрібно передавати довільну змінну. Наприклад:
var GREETING = "Hi, I'm ";
var NAME = "Rob";
var scriptToInject = function() {
alert(GREETING + NAME);
};
Щоб ввести цей код, вам потрібно передати змінні як аргументи анонімній функції. Обов’язково правильно його виконайте! Наступне не працюватиме:
var scriptToInject = function (GREETING, NAME) { ... };
var actualCode = '(' + scriptToInject + ')(' + GREETING + ',' + NAME + ')';
// The previous will work for numbers and booleans, but not strings.
// To see why, have a look at the resulting string:
var actualCode = "(function(GREETING, NAME) {...})(Hi, I'm ,Rob)";
// ^^^^^^^^ ^^^ No string literals!
Рішення полягає у використанні JSON.stringify
перед передачею аргументу. Приклад:
var actualCode = '(' + function(greeting, name) { ...
} + ')(' + JSON.stringify(GREETING) + ',' + JSON.stringify(NAME) + ')';
Якщо у вас є багато змінних, варто використати JSON.stringify
один раз, щоб поліпшити читабельність таким чином:
...
} + ')(' + JSON.stringify([arg1, arg2, arg3, arg4]) + ')';
player.addEventListener("onStateChange", state);