Czy po zmianie obiektu stylu elementu DOM można uruchomić hak javascript?

Element posiada obiekt javascript style, który zawiera różne nazwy i wartości stylów css. Chciałbym wywołać funkcję za każdym razem, gdy obiekt zmieni się bez użycia polling . Czy jest jakiś sposób, aby to zrobić w sposób, który jest kompatybilny między przeglądarkami i działa niezawodnie z kodem stron trzecich (bo powiedzmy, że dostarczasz skrypt drop-in)? Powiązanie zdarzenia javascript, takiego jak DOMAttrModified lub DOMSubtreeModified, nie wystarczy, ponieważ nie działa ono w Chrome.

Author: user730569, 2012-06-03

6 answers

Edit 4: Live Demo

$(function() {
  $('#toggleColor').on('click', function() {
    $(this).toggleClass('darkblue');
  }).attrchange({
    trackValues: true,
    callback: function(event) {
      $(this).html("<ul><li><span>Attribute Name: </span>" + event.attributeName + "</li><li><span>Old Value: </span>" + event.oldValue + "</li><li><span>New Value: </span>" + event.newValue + "</li></ul>");
    }
  });
});
body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 12px;
}
#toggleColor {
  height: 70px;
  width: 300px;
  padding: 5px;
  border: 1px solid #c2c2c2;
  background-color: #DBEAF9;
}
#toggleColor span {
  font-weight: bold;
}
#toggleColor.darkblue {
  background-color: #1A9ADA;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://meetselva.github.io/attrchange/javascripts/attrchange.js"></script>
<p>Click below div to toggle class darkblue.</p>
<div id="toggleColor"></div>

Edit 3: umieściłem to wszystko razem jako plugin, który można pobrać z git attrchange A oto strona demo.

Edytuj 2:

  1. poprawka dla nazwy właściwości w IE7 i IE8

Edytuj 1:

  1. Obsługa wielu elementów
  2. uporządkował Warunki jako MutationObserver, DOMAttrModified i onpropertychange dla lepszej implementacji.
  3. Dodano zmodyfikowaną nazwę atrybutu do wywołania zwrotnego.

Dzięki @ benvie za jego opinię.

DEMO: http://jsfiddle.net/zFVyv/10 / (testowane w FF 12, Chrome 19 i IE 7.)

$(function() {
    (function($) {
        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;

        function isDOMAttrModifiedSupported() {
            var p = document.createElement('p');
            var flag = false;

            if (p.addEventListener) p.addEventListener('DOMAttrModified', function() {
                flag = true
            }, false);
            else if (p.attachEvent) p.attachEvent('onDOMAttrModified', function() {
                flag = true
            });
            else return false;

            p.setAttribute('id', 'target');

            return flag;
        }

        $.fn.attrchange = function(callback) {
            if (MutationObserver) {
                var options = {
                    subtree: false,
                    attributes: true
                };

                var observer = new MutationObserver(function(mutations) {
                    mutations.forEach(function(e) {
                        callback.call(e.target, e.attributeName);
                    });
                });

                return this.each(function() {
                    observer.observe(this, options);
                });

            } else if (isDOMAttrModifiedSupported()) {
                return this.on('DOMAttrModified', function(e) {
                    callback.call(this, e.attrName);
                });
            } else if ('onpropertychange' in document.body) {
                return this.on('propertychange', function(e) {
                    callback.call(this, window.event.propertyName);
                });
            }
        }
    })(jQuery);

    $('.test').attrchange(function(attrName) {
        alert('Attribute: ' + attrName + ' modified ');
    }).css('height', 100);

});

Ref:

  1. Detect if domattrmodified supported
  2. DOMAttrModified for chrome
  3. mutacja Obserwator
  4. Dlaczego powinniśmy unikać przypadków mutacji?
  5. onPropertyChange IE

Obserwatorzy mutacji jest proponowanym zamiennikiem zdarzeń mutacyjnych w DOM4. Oczekuje się, że będą one zawarte w Firefox 14 i Chrome 18

Obsługa Przeglądarki:

onpropertychange - jest obsługiwany w IE (testowany w IE 7)

DOMAttrModified - jest obsługiwany w IE 9, FF i operze

MutationObservers - jest bardzo nowy i działa fine in Chrome 18 . Nie wiem, jak daleko jest obsługiwany i jeszcze do przetestowania w Safari.

Thanks @benvie on adding info about WebkitMutationObserver

 56
Author: Selvakumar Arumugam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:16:57

EDIT2:

Jeśli nadal chcesz używać mutation observer, użyj tej biblioteki: mutation-summary


EDIT:

Jak powiedziałem w mojej Odpowiedzi poniżej i dzięki Vega za komentarz, korzystanie z rzeczy takich jak object.watch lub mutation observers nie są zalecane do korzystania w dużych aplikacjach. to jest prawdziwy cytat z MDN :

Generalnie należy unikać używania watch() i unwatch(), gdy możliwe. Te dwie metody są zaimplementowane tylko w Gecko i są przeznaczony przede wszystkim do debugowania. Ponadto, za pomocą punktów obserwacyjnych ma poważny negatywny wpływ na wydajność, co jest szczególnie prawdziwe gdy jest używany na obiektach globalnych , takich jak window. Zazwyczaj można użyć setery oraz getters lub proxy zamiast tego. Szczegółowe informacje na temat zgodności.

Ostrzeżenie

Więc jeśli kompatybilność między przeglądarkami jest na liście kontrolnej, ponownie, bardzo sugerują nadpisanie setters i getter S z style obiektu.


użycie object.watch i mieć to na uwadze w przypadku rozwiązania między przeglądarkami:

Możesz także nadpisać getter i setter Metody obiektu style elementu.

Jest do tego dostępna wtyczka jQuery, jQuery zegarek

 1
Author: Sepehr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:28:05

Znalazłem ten mały plugin, który robi dokładnie to i można go zmienić, aby dodać dowolną mutację chcesz... Nawet przewijanie zmienia słuchacza.

Plugin: http://www.jqui.net/jquery-projects/jquery-mutate-official/

Oto demo: http://www.jqui.net/demo/mutate/

 1
Author: Val,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-20 09:07:59

Nawet dla wszystkich najnowocześniejszych przeglądarek nie ma sposobu, aby to osiągnąć. Będziesz musiał kierować wszystkie zmiany stylu css za pomocą funkcji, która może wywołać detektory zdarzeń. To byłaby najczystsza metoda.

 0
Author: Steve Binder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-03 05:26:36

W odpowiedzi na podobne pytanie zasugerowano, że jeśli wiesz, że interakcje z ustawianiem stylów będą wykonywane przez standardowy interfejs (np. Zawsze używając jQuery itp.) zasugerowano, aby zdarzenia niestandardowe były wywoływane za każdym razem, gdy wywołana jest metoda biblioteczna.

Pozwoliłoby to na szerszą macierz wsparcia, ale pozostawi wszelkie zmiany właściwości ignorowane, jeśli zostaną wykonane bez użycia metody bibliotecznej. Wydaje się również, że takie podejście nie ma zastosowania do natywne setery ponieważ nie zawsze można na nich polegać.

 0
Author: o.v.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:50:30

Możesz użyć attrchange jQuery plugin. Główną funkcją wtyczki jest Wiązanie funkcji słuchacza przy zmianie atrybutów elementów HTML.

 0
Author: Muhammad Reda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-20 12:29:49