Я хотів би мати щось на зразок:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
Відповіді:
При зміні класу не відбувається жодної події. Альтернатива - вручну викликати подію, коли ви програмно змінюєте клас:
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
// in another js file, far, far away
$('#myDiv').on('classChange', function() {
// do stuff
});
ОНОВЛЕННЯ
Здається, це питання збирає деяких відвідувачів, тому ось оновлення з підходом, яке можна використовувати без необхідності модифікувати існуючий код, використовуючи новий MutationObserver
:
var $div = $("#foo");
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === "class") {
var attributeValue = $(mutation.target).prop(mutation.attributeName);
console.log("Class attribute changed to:", attributeValue);
}
});
});
observer.observe($div[0], {
attributes: true
});
$div.addClass('red');
.red { color: #C00; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo" class="bar">#foo.bar</div>
Майте на увазі, що MutationObserver
він доступний лише для нових браузерів, зокрема Chrome 26, FF 14, IE 11, Opera 15 та Safari 6. Детальніше див. MDN . Якщо вам потрібно підтримати застарілі браузери, то вам доведеться скористатися методом, який я описав у своєму першому прикладі.
trigger()
), хоча зауважте, що вона дуже застаріла через використання bind()
. Я не впевнений, як це щось "завершує",
MutationObserver
працює для мене
Ви можете замінити оригінальну функцію jQuery addClass та removeClass на власну, яка викликала б вихідні функції, а потім ініціювала власну подію. (Використання анонімної функції, що викликається самостійно, щоб містити вихідне посилання на функцію)
(function( func ) {
$.fn.addClass = function() { // replace the existing function on $.fn
func.apply( this, arguments ); // invoke the original function
this.trigger('classChanged'); // trigger the custom event
return this; // retain jQuery chainability
}
})($.fn.addClass); // pass the original function as an argument
(function( func ) {
$.fn.removeClass = function() {
func.apply( this, arguments );
this.trigger('classChanged');
return this;
}
})($.fn.removeClass);
Тоді решта вашого коду буде настільки простою, як ви очікували.
$(selector).on('classChanged', function(){ /*...*/ });
Оновлення:
Цей підхід робить припущення, що класи будуть змінені лише за допомогою методів jQuery addClass та removeClass. Якщо класи модифікуються іншими способами (наприклад, безпосередня маніпуляція атрибутом класу через елемент DOM), MutationObserver
буде потрібно щось на зразок s, як пояснюється у прийнятій відповіді.
Також як пара вдосконалення цих методів:
classAdded
) або видаляється ( classRemoved
) із зазначеним класом, переданим як аргумент функції зворотного виклику, і запускається, лише якщо конкретний клас був фактично доданий (раніше не був присутній) або видалений (був раніше)Спрацьовувати лише в тому classChanged
випадку, якщо якісь класи насправді змінено
(function( func ) {
$.fn.addClass = function(n) { // replace the existing function on $.fn
this.each(function(i) { // for each element in the collection
var $this = $(this); // 'this' is DOM element in this context
var prevClasses = this.getAttribute('class'); // note its original classes
var classNames = $.isFunction(n) ? n(i, prevClasses) : n.toString(); // retain function-type argument support
$.each(classNames.split(/\s+/), function(index, className) { // allow for multiple classes being added
if( !$this.hasClass(className) ) { // only when the class is not already present
func.call( $this, className ); // invoke the original function to add the class
$this.trigger('classAdded', className); // trigger a classAdded event
}
});
prevClasses != this.getAttribute('class') && $this.trigger('classChanged'); // trigger the classChanged event
});
return this; // retain jQuery chainability
}
})($.fn.addClass); // pass the original function as an argument
(function( func ) {
$.fn.removeClass = function(n) {
this.each(function(i) {
var $this = $(this);
var prevClasses = this.getAttribute('class');
var classNames = $.isFunction(n) ? n(i, prevClasses) : n.toString();
$.each(classNames.split(/\s+/), function(index, className) {
if( $this.hasClass(className) ) {
func.call( $this, className );
$this.trigger('classRemoved', className);
}
});
prevClasses != this.getAttribute('class') && $this.trigger('classChanged');
});
return this;
}
})($.fn.removeClass);
За допомогою цих функцій заміни ви можете обробляти будь-який клас, змінений через classChanged, або додавати або видаляти конкретні класи, перевіряючи аргумент функції зворотного виклику:
$(document).on('classAdded', '#myElement', function(event, className) {
if(className == "something") { /* do something */ }
});
$(parent_selector).on('classChanged', target_selector, function(){ /*...*/ });
. Мені знадобився час, щоб зрозуміти, чому мої динамічно створені елементи не запускали обробник. Див. Learn.jquery.com/events/event-delegation
Використовуйте trigger
для запуску власної події. Коли ви коли-небудь змінюєте клас, додайте тригер з іменем
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
Вивчайте jQuery: Простий та легкий блог з підручників з jQuery
Ви можете використовувати щось на зразок цього:
$(this).addClass('someClass');
$(Selector).trigger('ClassChanged')
$(otherSelector).bind('ClassChanged', data, function(){//stuff });
але в іншому випадку ні, немає жодної заздалегідь визначеної функції, яка запускає подію при зміні класу.
Детальніше про тригери читайте тут