Обнаружение всех изображений с помощью Javascript на HTML-странице - PullRequest
0 голосов
/ 21 сентября 2018

Я пишу расширение Chrome и пытаюсь обнаружить все изображения на веб-странице.

Я пытаюсь в своем коде JS обнаружить все изображения на веб-странице, ивсе, что я имею в виду:

  1. Изображения, которые загружаются после загрузки веб-страницы
  2. Изображения, которые используются в качестве фона (в CSS или встроенном html)
  3. Изображениякоторый может быть загружен после завершения загрузки веб-страницы, например, при поиске изображений в Google легко найти все изображения, но как только вы нажмете одно изображение, чтобы увеличить его, это изображение не будет обнаружено.То же самое для просмотра веб-сайтов социальных сетей.

Код, который у меня есть сейчас, позволяет легко найти исходные изображения (1).Но я борюсь с двумя другими частями (2) и (3).

Вот мой текущий код в contentScript.js:

var images = document.getElementsByTagName('img');
for (var i = 0, l = images.length; i < l; i++) {
    //Do something
}

Как мне изменить его, чтобы он действительноможет обнаружить все другие изображения (2 и 3).

Я видел пару вопросов о (2) на SO, таких как это или это , нони один из ответов, по-видимому, полностью не отвечает моему второму требованию, и ни один из них не касается третьего.

Ответы [ 3 ]

0 голосов
/ 21 сентября 2018

Для изображений HTML (которые уже существуют к моменту запуска):

document.images

Для изображений CSS:

Возможно, вам потребуется использовать REGEX на страницеCSS (как встроенные, так и внешние файлы), но это сложно, потому что вам нужно динамически создавать полный путь из относительных путей, и это может не всегда работать.

Получение всех CSS, используемых в HTMLfile


Для изображений с отложенной загрузкой:

Вы можете использовать наблюдателя мутаций, как @filip предлагает в своем ответе

0 голосов
/ 09 октября 2018

Живая коллекция imgs

Найти все HTML-изображения, как сказал @vsync, так же просто, как var images = document.images.Это будет живой список, поэтому любые изображения, которые динамически добавляются или удаляются со страницы, будут автоматически отражаться в списке.

Извлечение фоновых изображений (встроенных и CSS)

Существует несколькоспособы проверки фоновых изображений, но, возможно, самый надежный способ - это перебрать все элементы страницы и использовать window.getComputedStyle, чтобы проверить, не равен ли backgroundImage каждого элемента none.Это позволит получить фоновые изображения как встроенными, так и в CSS.

var images = [];
var elements = document.body.getElementsByTagName("*");
Array.prototype.forEach.call( elements, function ( el ) {
    var style = window.getComputedStyle( el, false );
    if ( style.backgroundImage != "none" ) {
        images.push( style.backgroundImage.slice( 4, -1 ).replace(/['"]/g, "")
    }
}

Получение фонового изображения из window.getComputedStyle вернет полное свойство CSS background-image в форме url(...), поэтому вам потребуетсяудалите url( и ).Вам также нужно удалить все " или ', окружающие URL.Вы можете сделать это, используя backgroundImage.slice( 4, -1 ).replace(/['"]/g, "")

Начните проверку только после того, как DOM будет готов, в противном случае при первом сканировании могут отсутствовать элементы.

Динамически добавленные фоновые изображения

Это не будетпредоставьте оперативный список, так что вам потребуется MutationObserver, чтобы просмотреть документ, и проверить все измененные элементы на наличие backgroundImage.

. При настройке обозревателя убедитесь, что в конфигурации MutationObserver естьchildList и subtree установлены в true.Это означает, что он может просматривать все дочерние элементы указанного элемента (в вашем случае body).

var body = document.body;
var callback = function( mutationsList, observer ){
    for( var mutation of mutationsList ) {
        if ( mutation.type == 'childList' ) {
            // all changed children are in mutation.target.children
            // so iterate over them as in the code sample above
        }
    }
}
var observer = new MutationObserver( callback );
var config = { characterData: true,
            attributes: false,
            childList: true,
            subtree: true };
observer.observe( body, config );

Поскольку для поиска фоновых изображений требуется проверить каждый элемент в DOM, вы также можете проверитьдля <img> с одновременно, вместо использования document.images.

код

Вы хотели бы изменить приведенный выше код, чтобы в дополнение к проверке наличия фонаизображение, вы бы проверили, если его имя тега IMG.Вы также должны поместить его в функцию, которая запускается, когда DOM готов.

ОБНОВЛЕНИЕ: чтобы различать изображения и фоновые изображения, вы можете поместить их в разные массивы, например, в images и bg_images,Чтобы также определить родителей изображений, вы должны поместить image.parentNode в третий массив, например, image_parents.

var images = [],
    bg_images = [],
    image_parents = [];
document.addEventListener('DOMContentLoaded', function () {
    var body = document.body;
    var elements = document.body.getElementsByTagName("*");

    /* When the DOM is ready find all the images and background images
        initially loaded */
    Array.prototype.forEach.call( elements, function ( el ) {
        var style = window.getComputedStyle( el, false );
        if ( el.tagName === "IMG" ) {
            images.push( el.src ); // save image src
            image_parents.push( el.parentNode ); // save image parent

        } else if ( style.backgroundImage != "none" ) {
            bg_images.push( style.backgroundImage.slice( 4, -1 ).replace(/['"]/g, "") // save background image url
        }
    }

    /* MutationObserver callback to add images when the body changes */
    var callback = function( mutationsList, observer ){
        for( var mutation of mutationsList ) {
            if ( mutation.type == 'childList' ) {
                Array.prototype.forEach.call( mutation.target.children, function ( child ) {
                    var style = child.currentStyle || window.getComputedStyle(child, false);
                    if ( child.tagName === "IMG" ) {
                        images.push( child.src ); // save image src
                        image_parents.push( child.parentNode ); // save image parent
                    } else if ( style.backgroundImage != "none" ) {
                        bg_images.push( style.backgroundImage.slice( 4, -1 ).replace(/['"]/g, "") // save background image url
                    }
                } );
            }
        }
    }
    var observer = new MutationObserver( callback );
    var config = { characterData: true,
                attributes: false,
                childList: true,
                subtree: true };

    observer.observe( body, config );
});
0 голосов
/ 21 сентября 2018

Это должно решить вашу 3. проблему.Я использовал MutationObserver.

. Я проверяю targetNode на наличие изменений и добавляю обратный вызов в случае изменения.

В вашем случае targetNode должен быть корневым элементом дляпроверить изменения в документе целом .

В обратном вызове я спрашиваю, добавила ли мутация узел или нет с тегом "IMG".

    const targetNode = document.getElementById("root");

    // Options for the observer (which mutations to observe)
    let config = { attributes: true, childList: true, subtree: true };

    // Callback function to execute when mutations are observed
    const callback = function(mutationsList, observer) {
        for(let mutation of mutationsList) {
            if (mutation.addedNodes[0].tagName==="IMG") {
                console.log("New Image added in DOM!");
            }   
        }
    };

    // Create an observer instance linked to the callback function
    const observer = new MutationObserver(callback);

    // Start observing the target node for configured mutations
    observer.observe(targetNode, config);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...