Я разрабатываю расширение для Chrome, чтобы сделать веб-сайт более удобным.
У меня есть доступ к модели DOM страницы, но мне также нужно взаимодействовать со "собственным" JS на этой странице, чего я не могу сделать с помощью своего расширения. .
Я могу вводить произвольные теги на страницу (в первую очередь также теги <script>
), но поскольку экранирование строк, таких как
{
html: '<div onclick="doSomething(this, \'someName\')"></div>'
}
это настоящая боль, я хотел бы свести вводимый код к абсолютному минимуму.
Я попытался внедрить прослушиватели событий на страницу, чтобы получить переменные JS со страницы, но столкнулся с проблемой.
Похоже, что если CustomEvent
передается из расширения на веб-сайт или обратно, и если CustomEvent.detail
содержит определенные типы объектов (по крайней мере, функций и ошибок) где-то, все CustomEvent.detail
будет очищено, т.е. обнулено.
Пример
Скрипт (расширение.js):
(function()
{
var script = document.createElement('script');
script.innerHTML = [
"window.addEventListener('xyz', function(ev)",
" { ",
" console.log('after dispatch:'); ",
" console.log(ev.detail); ",
" }); ",
].join('\n');
document.head.appendChild(script);
// JSON-serializable data
var e = new CustomEvent('xyz', { detail: { x: 42, name: 'Schroedinger' } });
console.log('before dispatch:')
console.log(e.detail);
window.dispatchEvent(e);
// non-JSON-serializable data
var detail = { x: 42, name: 'Schroedinger' };
detail.detail = detail; // Create circular reference
e = new CustomEvent('xyz', { detail: detail });
console.log('before dispatch:')
console.log(e.detail);
window.dispatchEvent(e);
// data with function
e = new CustomEvent('xyz', { detail: { x: 42, name: 'Schroedinger', func: function(){} } });
console.log('before dispatch:');
console.log(e.detail);
window.dispatchEvent(e);
// data with error object
e = new CustomEvent('xyz', { detail: { x: 42, name: 'Schroedinger', err: new Error() } });
console.log('before dispatch:');
console.log(e.detail);
window.dispatchEvent(e);
})();
Вывод (абзац для удобочитаемости):
before dispatch:
Object {x: 42, name: "Schroedinger"}
after dispatch:
Object {x: 42, name: "Schroedinger"}
before dispatch:
Object {x: 42, name: "Schroedinger", detail: Object}
after dispatch:
Object {x: 42, name: "Schroedinger", detail: Object}
before dispatch:
Object {x: 42, name: "Schroedinger", func: function (){}}
after dispatch:
null
before dispatch:
Object {x: 42, name: "Schroedinger", err: Error at chrome-extension://...}
after dispatch:
null
Сначала я думал, что проблема заключается в JSON-сериализуемости, но циклические ссылки прекрасно проходят в событиях, тогда как при JSON-сериализации они ломались бы.
Похоже, что некоторые объекты "искажают" детали события таким же образом изображения, не относящиеся к другим источникам, портят холсты, за исключением того, что в консоли ничего нет.
Мне не удалось найти какую-либо документацию, касающуюся этого поведения, и (как предположил Пол С.) для этого не существует «привилегии» на Список разрешений Chrome.
Протестировано в Chrome 40.0.2214.115m, 43.0.2357.124m и 48.0.2547.0-dev.
ev.detail
в вашем коде? Не знаю, что такоеevent
. - person Bergi   schedule 24.02.2015window.event
доступен при запуске обработчика событий... и @PaulS.: Кажется, для этого нет разрешения на этот список. - person Siguza   schedule 24.02.2015