Як я можу запустити подію, якщо клас CSS додано чи змінено за допомогою jQuery? Чи зміна класу CSS запускає change()
подію jQuery ?
Як я можу запустити подію, якщо клас CSS додано чи змінено за допомогою jQuery? Чи зміна класу CSS запускає change()
подію jQuery ?
Відповіді:
Щоразу, коли ви змінюєте клас у своєму сценарії, ви можете використовувати a, 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
}
});
});
У цьому прикладі слухач подій додається до кожного елемента, але в більшості випадків цього не потрібно (зберегти пам'ять). Додайте цього слухача до "заміни" до елемента, який ви хочете спостерігати.
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, що має клас обов'язковий запис, який знаходиться в $ target, як $ target.addClass ('пошуковий клас');
change()
не спрацьовує, коли додається або видаляється клас CSS або змінюється визначення. Він спрацьовує за таких обставин, як, наприклад, коли вибране значення або поле не вибрано.
Я не впевнений, якщо ви маєте на увазі, чи змінюється визначення класу CSS (що може бути виконано програмно, але є втомливим і, як правило, не рекомендується) або якщо клас додано чи видалено до елемента. Ні в якому разі не можна надійно зафіксувати це, що відбувається.
Звичайно, ви можете створити власну подію для цього, але це може бути описано лише як дорадчий . Він не буде захоплювати код, який не є вашим.
Крім того, ви можете змінити / замінити addClass()
(і т. Д.) Методи в jQuery, але це не зафіксує, коли це буде зроблено через ванільний Javascript (хоча, мабуть, ви могли б замінити і ці методи).
Є ще один спосіб без ініціювання користувацької події
Плагін jQuery для моніторингу змін CSS Html Elements від Ріка Штраля
Цитуючи зверху
Плагін годинника працює за допомогою підключення до DOMAttrModified у FireFox, до onPropertyChanged в Internet Explorer або за допомогою таймера з setInterval для обробки виявлення змін для інших браузерів. На жаль, на даний момент WebKit не підтримує DOMAttrModified послідовно, тому в даний час Safari і Chrome мають використовувати більш повільний механізм setInterval.
Гарне питання. Я використовую спадне меню Bootstrap і мені потрібно було виконати подію, коли спадне завантаження було приховано. Коли відкривається спадне меню, що містить div з назвою класу "кнопка-група" додає клас "відкрито"; а сама кнопка має атрибут "розширена арія", встановлений на "true". Коли спадне меню закрите, цей клас "відкрито" видаляється з містить div, а розширений арією перемикається з істинного в хибне.
Це підштовхнуло мене до цього питання, як виявити зміну класу.
З Bootstrap є "події випадаючих", які можна виявити. Шукайте "Події, що випадають" за цим посиланням. http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp
Ось швидкий і брудний приклад використання цієї події у спадному меню Bootstrap.
$(document).on('hidden.bs.dropdown', function(event) {
console.log('closed');
});
Тепер я розумію, що це більш конкретно, ніж загальне питання, яке задають. Але я думаю, що інші розробники, які намагаються виявити відкриту або закриту подію за допомогою спадного завантаження Bootstrap, вважають це корисним. Як і я, вони можуть спочатку піти шляхом просто намагатися виявити зміну класу елементів (що, мабуть, не так просто). Дякую.
Якщо вам потрібно запустити певну подію, ви можете замінити метод 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');
});