#javascript #html #google-chrome #google-chrome-devtools #mutation-observers
#javascript #HTML #google-chrome #google-chrome-devtools #наблюдатели мутаций
Вопрос:
На первоначально заданный вопрос получен ответ. Кроме того, кто-то за пределами Stackoverflow предоставил полное решение того, чего я пытался достичь с помощью моего скрипта, который я добавил в качестве ответа на свой вопрос. Сам скрипт и краткое описание конкретной проблемы, которую он решает, подробно описаны в моем собственном ответе.
Оригинальный вопрос:
К сожалению, я не программист, поэтому мой опыт очень ограничен.
Мой браузер перезаписывает правильное img
src
на неправильное src
через пару секунд после его запуска.
Предполагаемая функция моего скрипта — это обходной путь, позволяющий немедленно заменить неисправное src
на правильное src
снова, в то время как мой браузер перезаписывает правильное src
.
function getElementsBySrc(srcValue) {
var nodes = [];
var e = document.getElementsByTagName('img');
for (var i = 0; i < e.length; i ) {
if (e[i].hasAttribute('src') amp;amp; e[i].getAttribute('src') == srcValue) {
nodes.push(e[i]);
}
}
return nodes;
}
function initMod(){
if(!document.querySelector("#browser")){
setTimeout(initMod, 1000);
return;
}
var targetNode = document.getElementsByTagName('img');
var config = { attributes: true, childList: false, subtree: false, characterData: false };
var callback = function(mutationsList, observer) {
for(var mutation of mutationsList) {
if (mutation.type == 'attributes') {
console.log('The ' mutation.attributeName ' attribute was modified.');
var n = getElementsBySrc('https://hyperspace.marquiskurt.net/icons/favicon-32x32.png');
for (var i = 0; i < n.length; i ) {
n[i].setAttribute('src', 'chrome://favicon/https://hyperspace.marquiskurt.net/app/');
}
}
}
};
var observer = new MutationObserver(callback);
observer.observe(targetNode, config);
}
initMod();
Скрипт загружается непосредственно при запуске моего браузера. Моя консоль Chrome Devtools выдает ошибку:
Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.
Комментарии:
1.
document.getElementsByTagName('img');
это не УЗЕЛ, этоHTMLcollection
набор узлов2. кстати, такой запуск
observer.observe(targetNode, config); observer.disconnect();
гарантирует, что наблюдатель все равно никогда не запустится: p3. также стоит упомянуть, что
img.getAttribute('src')
не всегда совпадает сimg.src
— вы уверены, что знаете, какой из них соответствует вашим требованиям?4. Спасибо. Я вижу, это объясняет некоторые проблемы со скриптом. Я не программист, так что в скрипте определенно не все в порядке. И да, я уверен, что мне это
img.getAttribute('src')
неimg.src
нужно.5. Скрипт работает без наблюдателя мутаций, однако он полагается на задержку, которая не идеальна, потому что это означает, что я действительно увижу визуальное изменение того, что
src
было нарушено, а затем исправлено снова. Я думаю, мне все еще нужно дождаться кого-то, кто будет достаточно любезен, чтобы показать мне, как исправить основную проблему в моем скрипте. (Я также обновил скрипт для удаленияobserver.disconnect();
.
Ответ №1:
поскольку document.getElementsByTagName('img');
возвращает список элементов, а не узел, вы не можете использовать targetNode
(потому что это не узел)
Здесь я использую document.querySelectorAll
вместо этого тот же результат, но у него есть метод forEach, который я использую для создания наблюдателей мутаций для каждого IMG
function initMod() {
if(!document.querySelector("#browser")){
setTimeout(initMod, 1000);
return;
}
const callback = (mutationsList, observer) => {
for(let mutation of mutationsList) {
if (mutation.type == 'attributes') {
console.log('The ' mutation.attributeName ' attribute was modified.');
const n = getElementsBySrc('https://hyperspace.marquiskurt.net/icons/favicon-32x32.png');
for (let e of n) {
e.setAttribute('src', 'chrome://favicon/https://hyperspace.marquiskurt.net/app/');
}
}
}
};
const config = { attributes: true, childList: false, subtree: false, characterData: false };
document.querySelectorAll('img').forEach(targetNode => {
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
});
}
Комментарии:
1. Спасибо. Я протестировал скрипт. Это исправило ошибку, указанную в консоли. Похоже, что скрипт по-прежнему не выполняет то, для чего он предназначен, поскольку сломанный src не заменяется. Я также уменьшил задержку инициализации до 200, и, похоже, она все еще не работает. Что, я немного ошарашен.
2. Возможно ли, что скрипт обнаруживает другие изменения в атрибутах img и не может найти
src
set ashttps://hyperspace.marquiskurt.net/icons/favicon-32x32.png
, а затем останавливается на этом?3. Ведение журнала консоли поможет вам определить, что происходит
Ответ №2:
Кто-то очень любезно предоставил решение, которое достигло именно того, что я пытался сделать.
const selector = "#panels img[src='https://hyperspace.marquiskurt.net/icons/favicon-32x32.png']";
function fixImages() {
const maybeBadImage = document.querySelector(selector);
if(maybeBadImage){
maybeBadImage.src = "chrome://favicon/https://hyperspace.marquiskurt.net/app/";
}
}
const observer = new MutationObserver(fixImages);
function initMod() {
if(!document.querySelector(selector)){
setTimeout(initMod, 0);
return;
}
observer.observe(document.querySelector(selector), { attributes: true });
fixImages();
}
initMod();
При setTimeout
значении 0 неисправность src
немедленно исправляется без каких-либо визуальных изменений, которые может видеть пользователь. Этот скрипт может быть изменен для использования, если у кого-либо еще возникает проблема, из-за которой веб-браузер Vivaldi неправильно изменяет src
для значка определенной добавленной пользователем веб-панели.