2013-12-04 2 views
5

Я использую MutationObserver для поиска добавленных изображений на веб-страницу. Поскольку многие изображения отображаются с помощью свойства CSS background-image, я проверяю текущий/вычислен стиль CSS в дополнение к поиску img тегов, например ...MutationObserver и текущие/рассчитанные стили CSS

var hasBackgroundImage = function(node) { 
    var nodeStyle = node.currentStyle || getComputedStyle(node, null); 
    return (
     nodeStyle && 
     nodeStyle.backgroundImage && 
     nodeStyle.backgroundImage != "none" 
     ); 
}; 

Тем не менее, кажется, есть задержка между узел, запускающий событие мутации и применяемые правила CSS, поэтому , по-видимому, не существует backgroundImage во время мутационного события, хотя в какой-то момент будет. Я заметил это, когда код работал во время отладки (пошагово с точками останова), но не работал во время выполнения. Задержка обработки мутаций с помощью setTimeout также работает, но чтобы быть уверенным, что задержка должна быть довольно большой и изменяется со страницы на страницу (я не уверен, что когда правила CSS будут применены). Возможной причиной может быть просто отложенная загрузка или вставка содержимого CSS.

Каков наилучший способ достижения этой функциональности? Я предполагаю, что после мутации с изменением стиля, но я сомневаюсь, что это существует.

+0

Это может помочь, если мы знаем, почему вы пытаетесь наблюдать мутации ... – prodigitalson

+0

@prodigitalson Я пытаюсь изменить все изображения на веб-странице как часть расширения браузера. Я бы хотел, чтобы он был максимально гладким и надежным. Я предполагаю, что наблюдатель мутации даст события для изображений, добавленных динамически, иначе я бы просто пропустил всю страницу один раз. – jozxyqk

ответ

3

Это работает для меня ...

  1. Использовать мутации наблюдателя, чтобы поймать изменения в атрибут стиля ...

    var observer = new MutationObserver(parseMutations); 
    observer.observe(document, { 
        ... 
        attributes: true, 
        attributeFilter: ["style"] 
    }); 
    
    ... 
    
        if (mutation.attributeName) //we'll assume it's "style" 
         parseNode(mutation.target); //check for style.backgroundImage and call filterNode() 
    

    Это работает для какsetAttribute("style", ...) и element.style.whatever = something.

  2. Поймать новые style и link элементы с мутацией наблюдателем, добавить событие onload и анализировать применяемые узлы ...

    var stylenodes = ["STYLE", "LINK"]; 
    
    ... 
    
    for (var i = 0; i < mutation.addedNodes.length; i++) 
    { 
        var node = mutation.addedNodes[i]; 
        var nodeName = node.nodeName.toUpperCase(); 
        if (stylenodes.indexOf(nodeName) !== -1) 
         node.addEventListener("load", styleLoaded); 
    
    ... 
    
    //catch loading of stylenodes and parse all new rules 
    var currentLoadedStyles = []; 
    var styleLoaded = function() { 
        //check all styles and look for one that has just added some rules 
        for (var i = 0; i < document.styleSheets.length; ++i) 
        { 
         if (document.styleSheets[i].rules && document.styleSheets[i].rules.length > 0 && currentLoadedStyles.indexOf(document.styleSheets[i]) == -1) 
         { 
          currentLoadedStyles.push(document.styleSheets[i]); 
          parseNewStyle(document.styleSheets[i].rules); 
         } 
        } 
    }; 
    
    //look for rules with background images and re-filter all nodes it applies to 
    var parseNewStyle = function(rules) { 
        for (var i = 0; i < rules.length; ++i) 
        { 
         //if any rule contains a background-image (could look for anything here really) 
         if (rules[i].style && rules[i].style.backgroundImage && rules[i].style.backgroundImage != "none") 
         { 
          //get all affected nodes and re-parse them 
          var nodes = document.querySelectorAll(rules[i].selectorText); 
          for (var j = 0; j < nodes.length; ++j) 
           filterNode(nodes[j]); 
         } 
        } 
    }; 
    
+0

Это похоже на работу только в том случае, если атрибут 'style' изменен специально, а не при изменении вычисленного стиля (т. Е. Из-за изменений в таблице стилей). – trusktr

+1

@trusktr это будет обрабатывать изменения из новых таблиц стилей. Чтобы обрабатывать изменения в стилях, вы можете использовать другой наблюдатель мутаций. Также проверьте изменения внешних ссылок по атрибуту src. Более полный пример: https://github.com/pknowles/ImageFilter/blob/master/imagefinder.js – jozxyqk

+0

Я понимаю, что вы имеете в виду. Таким образом, наблюдатель за мутацией находится в элементах 'style' или наблюдает за содержимым атрибутов style. Но я хотел бы наблюдать computedStyle без соблюдения стилей или атрибутов стиля. Я думаю, Object.observe было бы хорошо для этого, но это было удалено из спецификации. – trusktr

Смежные вопросы