Как я могу запустить событие, если CSS-класс добавлен или изменен с помощью jQuery? Запускает ли изменение класса CSS change()
событие jQuery ?
Как я могу запустить событие, если CSS-класс добавлен или изменен с помощью jQuery? Запускает ли изменение класса CSS change()
событие jQuery ?
Ответы:
Всякий раз, когда вы изменяете класс в вашем скрипте, вы можете использовать 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>
changeColor
событие, и все те объекты, которые подписываются на это событие, могут реагировать соответствующим образом.
ИМХО, лучшее решение - объединить два ответа @ 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
});
});
$()
, когда вы добираетесь , когда начинается настоящее действие.
cssClassChanged
событие с элементом, вы должны знать, что оно будет запущено, даже когда его ребенок изменит свой класс. Поэтому, если, например, вы не хотите запускать это событие для них, просто добавьте что-то вроде $("#YourExampleElementID *").on('cssClassChanged', function(e) { e.stopPropagation(); });
после привязки. В любом случае, действительно хорошее решение, спасибо!
Если вы хотите обнаружить изменение класса, лучше всего использовать 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" к элементу, который вы хотите наблюдать.
DOMMutationObserver
.
Я бы предложил вам переопределить функцию 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
});
Просто подтверждение концепции:
Посмотрите на суть, чтобы увидеть некоторые аннотации и оставаться в курсе:
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');
this[0]
неопределен ... просто заменить конец строки с var oldClass
и var newClass
со следующим назначением:= (this[0] ? this[0].className : "");
используя последнюю мутацию 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');
change()
не срабатывает при добавлении или удалении класса CSS или изменении определения. Он срабатывает в обстоятельствах, например, когда выбрано или не выбрано значение поля выбора.
Я не уверен, имеете ли вы в виду, что определение класса CSS изменено (что может быть сделано программно, но утомительно и обычно не рекомендуется) или класс добавлен или удален в элемент. Нет способа надежно зафиксировать это в любом случае.
Конечно, вы можете создать собственное мероприятие для этого, но это можно назвать только рекомендательным . Он не будет захватывать код, который не принадлежит вам.
В качестве альтернативы вы можете переопределить / заменить addClass()
(и т. Д.) Методы в jQuery, но это не будет зафиксировано, когда это будет сделано через ванильный Javascript (хотя я думаю, вы могли бы также заменить эти методы).
Есть еще один способ, не вызывая пользовательское событие
Плагин jQuery для отслеживания изменений CSS в HTML-элементах. Автор Rick Strahl
Цитирование сверху
Плагин наблюдения работает путем подключения к DOMAttrModified в FireFox, к onPropertyChanged в Internet Explorer или с помощью таймера с setInterval для обработки обнаружения изменений для других браузеров. К сожалению, в настоящее время WebKit не поддерживает DOMAttrModified последовательно, поэтому Safari и Chrome в настоящее время вынуждены использовать более медленный механизм setInterval.
Хороший вопрос. Я использую выпадающее меню 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, найдут это полезным. Как и я, они могут сначала пойти по пути простой попытки обнаружить изменение класса элемента (что, очевидно, не так просто). Спасибо.
Если вам нужно вызвать определенное событие, вы можете переопределить метод addClass (), чтобы запустить пользовательское событие с именем «classadded».
Вот как:
(function() {
var ev = new $.Event('classadded'),
orig = $.fn.addClass;
$.fn.addClass = function() {
$(this).trigger(ev, arguments);
return orig.apply(this, arguments);
}
})();
$('#myElement').on('classadded', function(ev, newClasses) {
console.log(newClasses + ' added!');
console.log(this);
// Do stuff
// ...
});
Вы можете связать событие 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');
});
});
если вы знаете, какое событие изменило класс, в первую очередь вы можете использовать небольшую задержку для того же события и установить флажок для класса. пример
//this is not the code you control
$('input').on('blur', function(){
$(this).addClass('error');
$(this).before("<div class='someClass'>Warning Error</div>");
});
//this is your code
$('input').on('blur', function(){
var el= $(this);
setTimeout(function(){
if ($(el).hasClass('error')){
$(el).removeClass('error');
$(el).prev('.someClass').hide();
}
},1000);
});
var timeout_check_change_class;
function check_change_class( selector )
{
$(selector).each(function(index, el) {
var data_old_class = $(el).attr('data-old-class');
if (typeof data_old_class !== typeof undefined && data_old_class !== false)
{
if( data_old_class != $(el).attr('class') )
{
$(el).trigger('change_class');
}
}
$(el).attr('data-old-class', $(el).attr('class') );
});
clearTimeout( timeout_check_change_class );
timeout_check_change_class = setTimeout(check_change_class, 10, selector);
}
check_change_class( '.breakpoint' );
$('.breakpoint').on('change_class', function(event) {
console.log('haschange');
});