jQuery - событие Fire, если класс CSS изменился - PullRequest
233 голосов
/ 23 декабря 2009

как я могу запустить событие, если класс css был добавлен или изменен с помощью jQuery? Запускает ли изменение класса CSS событие jQuery change ()?

Ответы [ 13 ]

220 голосов
/ 23 декабря 2009

Всякий раз, когда вы изменяете класс в вашем скрипте, вы можете использовать trigger, чтобы вызвать собственное событие.

$(this).addClass('someClass');
$(mySelector).trigger('cssClassChanged')
....
$(otherSelector).bind('cssClassChanged', data, function(){ do stuff });

но в противном случае, нет, нет никакого запутанного способа вызвать событие, когда класс меняется. change() срабатывает только после того, как фокус покидает вход, чей вход был изменен.

$(function() {
  var button = $('.clickme')
      , box = $('.box')
  ;
  
  button.on('click', function() { 
    box.removeClass('box');
    $(document).trigger('buttonClick');
  });
            
  $(document).on('buttonClick', function() {
    box.text('Clicked!');
  });
});
.box { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="box">Hi</div>
<button class="clickme">Click me</button>

Подробнее о триггерах jQuery

134 голосов
/ 29 декабря 2012

ИМХО, лучшее решение - объединить два ответа @ RamboNo5 и @ Jason

Я имею в виду переопределение функции addClass и добавление пользовательского события с именем cssClassChanged

// Create a closure
(function(){
    // Your base, I'm in it!
    var originalAddClassMethod = jQuery.fn.addClass;

    jQuery.fn.addClass = function(){
        // Execute the original method.
        var result = originalAddClassMethod.apply( this, arguments );

        // trigger a custom event
        jQuery(this).trigger('cssClassChanged');

        // return the original result
        return result;
    }
})();

// document ready function
$(function(){
    $("#YourExampleElementID").bind('cssClassChanged', function(){ 
        //do stuff here
    });
});
53 голосов
/ 18 июня 2014

Если вы хотите обнаружить изменение класса, лучше всего использовать Mutation Observers, который дает вам полный контроль над любым изменением атрибута. Однако вам нужно определить слушателя самостоятельно и добавить его к элементу, который вы слушаете. Хорошо, что вам не нужно ничего запускать вручную после добавления слушателя.

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

    $.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);
            });

        }
    }
})(jQuery);

//Now you need to append event listener
$('body *').attrchange(function(attrName) {

    if(attrName=='class'){
            alert('class changed');
    }else if(attrName=='id'){
            alert('id changed');
    }else{
        //OTHER ATTR CHANGED
    }

});
});

В этом примере прослушиватель событий добавляется к каждому элементу, но в большинстве случаев этого не требуется (экономьте память). Добавьте этот слушатель "attrchange" к элементу, который вы хотите наблюдать.

52 голосов
/ 23 декабря 2009

Я бы предложил переопределить функцию addClass. Вы можете сделать это так:

// Create a closure
(function(){
    // Your base, I'm in it!
    var originalAddClassMethod = jQuery.fn.addClass;

    jQuery.fn.addClass = function(){
        // Execute the original method.
        var result = originalAddClassMethod.apply( this, arguments );

        // call your function
        // this gets called everytime you use the addClass method
        myfunction();

        // return the original result
        return result;
    }
})();

// document ready function
$(function(){
    // do stuff
});
20 голосов
/ 22 марта 2013

Просто подтверждение концепции:

Посмотрите на суть, чтобы увидеть некоторые аннотации и оставаться в курсе:

https://gist.github.com/yckart/c893d7db0f49b1ea4dfb

(function ($) {
  var methods = ['addClass', 'toggleClass', 'removeClass'];

  $.each(methods, function (index, method) {
    var originalMethod = $.fn[method];

    $.fn[method] = function () {
      var oldClass = this[0].className;
      var result = originalMethod.apply(this, arguments);
      var newClass = this[0].className;

      this.trigger(method, [oldClass, newClass]);

      return result;
    };
  });
}(window.jQuery || window.Zepto));

Использование довольно просто, просто добавьте новый слушатель на узел, который вы хотите наблюдать, и управляйте классами, как обычно:

var $node = $('div')

// listen to class-manipulation
.on('addClass toggleClass removeClass', function (e, oldClass, newClass) {
  console.log('Changed from %s to %s due %s', oldClass, newClass, e.type);
})

// make some changes
.addClass('foo')
.removeClass('foo')
.toggleClass('foo');
7 голосов
/ 22 августа 2016

с использованием последней мутации jquery

var $target = jQuery(".required-entry");
            var observer = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    if (mutation.attributeName === "class") {
                        var attributeValue = jQuery(mutation.target).prop(mutation.attributeName);
                        if (attributeValue.indexOf("search-class") >= 0){
                            // do what you want
                        }
                    }
                });
            });
            observer.observe($target[0],  {
                attributes: true
            });

// любой код, который обновляет div, имеющий класс required-entry , который находится в $ target как $ target.addClass ('search-class');

7 голосов
/ 08 мая 2013

Существует еще один способ без вызова пользовательского события

Плагин jQuery для отслеживания изменений CSS HTML-элемента Риком Стрэлом

Цитирование сверху

Плагин для часов работает путем подключения к DOMAttrModified в FireFox, на onPropertyChanged в Internet Explorer или с помощью таймера с setInterval для обработки обнаружения изменений в других браузерах. К сожалению, WebKit не поддерживает DOMAttrModified последовательно в момент, поэтому Safari и Chrome в настоящее время должны использовать медленнее Механизм setInterval.

7 голосов
/ 23 декабря 2009

change() не срабатывает при добавлении или удалении класса CSS или изменении определения. Он срабатывает в обстоятельствах, например, когда значение поля выбора выбрано или не выбрано.

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

Конечно, вы можете создать собственное событие для этого, но это можно описать только как рекомендация . Он не будет захватывать код, который не принадлежит вам.

В качестве альтернативы вы можете переопределить / заменить addClass() (и т. Д.) Методы в jQuery, но это не будет зафиксировано, когда это делается с помощью ванильного Javascript (хотя, я думаю, вы могли бы также заменить эти методы).

5 голосов
/ 22 сентября 2015

Хороший вопрос. Я использую выпадающее меню Bootstrap, и мне нужно было выполнить событие, когда выпадающий список Bootstrap был скрыт. Когда раскрывающийся список открыт, содержащий div с именем класса «button-group» добавляет класс «open»; и сама кнопка имеет расширенный атрибут aria, установленный в true. Когда раскрывающийся список закрыт, этот класс «open» удаляется из содержащего div, и aria-extended переключается с true на false.

Это привело меня к вопросу о том, как обнаружить изменение класса.

С помощью Bootstrap существуют «выпадающие события», которые можно обнаружить. Посмотрите на «Dropdown Events» по этой ссылке. http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp

Вот краткий пример использования этого события в выпадающем меню Bootstrap.

$(document).on('hidden.bs.dropdown', function(event) {
    console.log('closed');
});

Теперь я понимаю, что это более конкретно, чем общий вопрос, который задают. Но я думаю, что другие разработчики, пытающиеся обнаружить открытое или закрытое событие с помощью Bootstrap Dropdown, найдут это полезным. Как и я, они могут сначала пойти по пути простой попытки обнаружить изменение класса элемента (что, очевидно, не так просто). Спасибо.

4 голосов
/ 15 августа 2016

Вы можете связать событие DOMSubtreeModified. Я добавляю пример здесь:

HTML

<div id="mutable" style="width:50px;height:50px;">sjdfhksfh<div>
<div>
  <button id="changeClass">Change Class</button>
</div>

JavaScript

$(document).ready(function() {
  $('#changeClass').click(function() {
    $('#mutable').addClass("red");
  });

  $('#mutable').bind('DOMSubtreeModified', function(e) {
      alert('class changed');
  });
});

http://jsfiddle.net/hnCxK/13/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...