remove - jquery selector
jQuery-evento de fuego si la clase CSS cambiĆ³ (13)
Buena pregunta. Estoy usando el menú desplegable de Bootstrap y necesité ejecutar un evento cuando se ocultó un menú desplegable de Bootstrap. Cuando se abre el menú desplegable, el div que contiene un nombre de clase de "button-group" agrega una clase de "abierto"; y el botón en sí tiene un atributo "aria expandido" establecido en verdadero. Cuando se cierra el menú desplegable, esa clase de "abierto" se elimina del div que lo contiene, y aria-expandido cambia de verdadero a falso.
Eso me llevó a esta pregunta, de cómo detectar el cambio de clase.
Con Bootstrap, hay "Eventos desplegables" que pueden ser detectados. Busque "Eventos desplegables" en este enlace. http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp
Aquí hay un ejemplo rápido y sucio de usar este evento en un menú desplegable de Bootstrap.
$(document).on(''hidden.bs.dropdown'', function(event) {
console.log(''closed'');
});
Ahora me doy cuenta de que esto es más específico que la pregunta general que se está haciendo. Pero me imagino que otros desarrolladores que intentan detectar un evento abierto o cerrado con un menú desplegable de Bootstrap lo encontrarán útil. Al igual que yo, inicialmente pueden ir por el camino de simplemente intentar detectar un cambio de clase de elemento (que aparentemente no es tan simple). Gracias.
¿Cómo podría activar un evento si la clase css se agregó o cambió con jQuery? ¿El cambio de la clase CSS dispara el evento jQuery change ()?
En mi humilde opinión, la mejor solución es combinar dos respuestas de @ RamboNo5 y @Jason
Me refiero a anular la función addClass y agregar un evento personalizado llamado 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
});
});
Hay una manera más sin activar un evento personalizado
Un complemento de jQuery para monitorear los cambios de CSS del elemento HTML por Rick Strahl
Citando desde arriba
El complemento del reloj funciona al conectarse a DOMAttrModified en FireFox, a OnPropertyChanged en Internet Explorer, o al usar un temporizador con setInterval para manejar la detección de cambios para otros navegadores. Desafortunadamente, WebKit no admite DOMAttrModified de forma consistente en este momento, por lo que Safari y Chrome actualmente tienen que usar el mecanismo más lento de setInterval.
Le sugiero que anule la función addClass. Puedes hacerlo de esta manera:
// 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
});
Puede enlazar el evento DOMSubtreeModified. Añado un ejemplo aquí:
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'');
});
});
Si conoce un evento que cambió la clase en primer lugar, puede usar un ligero retraso en el mismo evento y la verificación de la clase. ejemplo
//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);
});
Si desea detectar un cambio de clase, la mejor manera es usar Mutation Observers, que le da un control completo sobre cualquier cambio de atributo. Sin embargo, debe definir usted mismo el oyente y adjuntarlo al elemento que está escuchando. Lo bueno es que no es necesario disparar nada manualmente una vez que se agrega el oyente.
$(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
}
});
});
En este ejemplo, el detector de eventos se anexa a todos los elementos, pero en la mayoría de los casos no se desea eso (guardar memoria). Agregue esta escucha "attrchange" al elemento que desea observar.
Si necesita desencadenar un evento específico, puede anular el método addClass () para desencadenar un evento personalizado llamado ''classadded''.
Aquí cómo:
(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
// ...
});
Solo una prueba de concepto:
Mire la esencia para ver algunas anotaciones y manténgase actualizado:
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));
El uso es bastante simple, solo agregue un nuevo oyente en el nodo que desea observar y manipule las clases como de costumbre:
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'');
utilizando la última mutación 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
});
// cualquier código que actualice el div que tenga clase , entrada obligatoria que esté en $ target como $ target.addClass (''clase de búsqueda'');
change()
no se activa cuando se agrega o elimina una clase CSS o cambia la definición. Se dispara en circunstancias como cuando se selecciona o no se selecciona un valor de cuadro de selección.
No estoy seguro de si te refieres a si la definición de la clase CSS se cambia (lo que se puede hacer mediante programación pero es tedioso y generalmente no se recomienda) o si se agrega o elimina una clase a un elemento. No hay forma de capturar de manera confiable este suceso en ninguno de los dos casos.
Por supuesto, podría crear su propio evento para esto, pero esto solo puede ser descrito como asesor . No capturará código que no sea tuyo haciéndolo.
Alternativamente, podría anular / reemplazar los addClass()
(etc.) en jQuery, pero esto no se capturará cuando se haga a través de Javascript de vainilla (aunque creo que también podría reemplazar esos métodos).
Cada vez que cambie una clase en su script, puede usar un trigger
para generar su propio evento.
$(this).addClass(''someClass'');
$(mySelector).trigger(''cssClassChanged'')
....
$(otherSelector).bind(''cssClassChanged'', data, function(){ do stuff });
pero de lo contrario, no, no hay una forma horneada de disparar un evento cuando una clase cambia. change()
solo se dispara después de que el foco deja una entrada cuya entrada se ha modificado.
$(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>
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'');
});