trigger remove evento disparar change javascript jquery

javascript - remove - jquery trigger change



Evento jQuery para activar la acción cuando se hace visible un div (21)

¡Este soporte facilita y desencadena el evento después de la animación! [probado en jQuery 2.2.4]

(function ($) { $.each([''show'', ''hide'', ''fadeOut'', ''fadeIn''], function (i, ev) { var el = $.fn[ev]; $.fn[ev] = function () { var result = el.apply(this, arguments); var _self=this; result.promise().done(function () { _self.triggerHandler(ev, [result]); //console.log(_self); }); return result; }; }); })(jQuery);

Inspirado por http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/

Estoy usando jQuery en mi sitio y me gustaría desencadenar ciertas acciones cuando se hace visible un div determinado.

¿Es posible adjuntar algún tipo de controlador de eventos "invisible" a divs arbitrarios y ejecutar cierto código cuando se hace visible el div?

Me gustaría algo así como el siguiente pseudocódigo:

$(function() { $(''#contentDiv'').isvisible(function() { alert("do something"); }); });

El código de alerta ("hacer algo") no debe activarse hasta que el contentDiv se haga visible.

Gracias.


Cambié el evento de ocultar / mostrar evento de Catalint basado en la idea de Glenns. Mi problema fue que tengo una aplicación modular. Cambio entre módulos que muestran y esconden a los padres. Luego, cuando oculto un módulo y muestro otro, con su método tengo un retraso visible cuando cambio de módulo. Solo necesito a veces organizar este evento, y en algunos niños especiales. Así que decidí notificar solo a los niños con la clase "displayObserver"

$.each(["show", "hide", "toggleClass", "addClass", "removeClass"], function () { var _oldFn = $.fn[this]; $.fn[this] = function () { var hidden = this.find(".displayObserver:hidden").add(this.filter(":hidden")); var visible = this.find(".displayObserver:visible").add(this.filter(":visible")); var result = _oldFn.apply(this, arguments); hidden.filter(":visible").each(function () { $(this).triggerHandler("show"); }); visible.filter(":hidden").each(function () { $(this).triggerHandler("hide"); }); return result; } });

Luego, cuando un niño quiere escuchar el evento "show" u "hide", tengo que agregarle la clase "displayObserver", y cuando no quiere continuar escuchándolo, le quito la clase

bindDisplayEvent: function () { $("#child1").addClass("displayObserver"); $("#child1").off("show", this.onParentShow); $("#child1").on("show", this.onParentShow); }, bindDisplayEvent: function () { $("#child1").removeClass("displayObserver"); $("#child1").off("show", this.onParentShow); },

Deseo ayuda


El problema está siendo abordado por los observadores de mutación DOM . Le permiten vincular un observador (una función) a eventos de contenido cambiante, texto o atributos de elementos dom.

Con el lanzamiento de IE11, todos los principales navegadores son compatibles con esta función, visite http://caniuse.com/mutationobserver

El código de ejemplo es el siguiente:

$(function() { $(''#show'').click(function() { $(''#testdiv'').show(); }); var observer = new MutationObserver(function(mutations) { alert(''Attributes changed!''); }); var target = document.querySelector(''#testdiv''); observer.observe(target, { attributes: true }); });

<div id="testdiv" style="display:none;">hidden</div> <button id="show">Show hidden div</button> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>



Espero que esto haga el trabajo de la manera más simple:

$("#myID").on(''show'').trigger(''displayShow''); $(''#myID'').off(''displayShow'').on(''displayShow'', function(e) { console.log(''This event will be triggered when myID will be visible''); });


Hay un complemento de jQuery disponible para ver el cambio en los atributos de DOM,

https://github.com/darcyclarke/jQuery-Watch-Plugin

El complemento envuelve Todo lo que necesitas hacer es enlazar MutationObserver

Luego puedes usarlo para ver el div usando:

$("#selector").watch(''css'', function() { console.log("Visibility: " + this.style.display == ''none''?''hidden'':''shown'')); //or any random events });


Hice una simple función setinterval para lograr esto. Si el elemento con la clase div1 es visible, establece que div2 sea visible. No conozco un buen método, sino una solución simple.

setInterval(function(){ if($(''.div1'').is('':visible'')){ $(''.div2'').show(); } else { $(''.div2'').hide(); } }, 100);


Lo que me ayudó aquí es la nueva especificación de ResizeObserver polyfill :

const divEl = $(''#section60''); const ro = new ResizeObserver(() => { if (divEl.is('':visible'')) { console.log("it''s visible now!"); } }); ro.observe(divEl[0]);

Tenga en cuenta que es crossbrowser y performant (no polling).


No hay ningún evento nativo al que puedas enganchar para esto, sin embargo, puedes activar un evento desde tu script una vez que hayas hecho visible el div usando el. función de trigger

p.ej

//declare event to run when div is visible function isVisible(){ //do something } //hookup the event $(''#someDivId'').bind(''isVisible'', isVisible); //show div and trigger custom event in callback when div is visible $(''#someDivId'').show(''slow'', function(){ $(this).trigger(''isVisible''); });


Puedes usar el plugin Live Query de jQuery. Y escriba el código de la siguiente manera:

$(''#contentDiv:visible'').livequery(function() { alert("do something"); });

Luego, cada vez que se visualice el contentDiv, se alertará a "hacer algo".


Si desea activar el evento en todos los elementos (y elementos secundarios) que se hacen visibles, mediante $ .show, toggle, toggleClass, addClass o removeClass:

$.each(["show", "toggle", "toggleClass", "addClass", "removeClass"], function(){ var _oldFn = $.fn[this]; $.fn[this] = function(){ var hidden = this.find(":hidden").add(this.filter(":hidden")); var result = _oldFn.apply(this, arguments); hidden.filter(":visible").each(function(){ $(this).triggerHandler("show"); //No bubbling }); return result; } });

Y ahora tu elemento:

$("#myLazyUl").bind("show", function(){ alert(this); });

Puede agregar anulaciones a funciones jQuery adicionales agregándolas a la matriz en la parte superior (como "attr")


Siempre se puede agregar al método .show() original para que no tenga que desencadenar eventos cada vez que muestre algo o si lo necesita para trabajar con código heredado:

Extensión de jquery:

jQuery(function($) { var _oldShow = $.fn.show; $.fn.show = function(speed, oldCallback) { return $(this).each(function() { var obj = $(this), newCallback = function() { if ($.isFunction(oldCallback)) { oldCallback.apply(obj); } obj.trigger(''afterShow''); }; // you can trigger a before show if you want obj.trigger(''beforeShow''); // now use the old function to show the element passing the new callback _oldShow.apply(obj, [speed, newCallback]); }); } });

Ejemplo de uso:

jQuery(function($) { $(''#test'') .bind(''beforeShow'', function() { alert(''beforeShow''); }) .bind(''afterShow'', function() { alert(''afterShow''); }) .show(1000, function() { alert(''in show callback''); }) .show(); });

Esto le permite efectivamente hacer algo antes de Show y después Show mientras sigue ejecutando el comportamiento normal del método .show () original.

También puede crear otro método para no tener que anular el método original .show ().



Tuve el mismo problema y creé un complemento jQuery para resolverlo en nuestro sitio.

https://github.com/shaunbowe/jquery.visibilityChanged

Aquí es cómo lo usarías basado en tu ejemplo:

$(''#contentDiv'').visibilityChanged(function(element, visible) { alert("do something"); });


Una forma de hacer esto.
Funciona solo en los cambios de visibilidad que se realizan mediante el cambio de clase css, pero también se puede extender para observar los cambios de atributos.

var observer = new MutationObserver(function(mutations) { var clone = $(mutations[0].target).clone(); clone.removeClass(); for(var i = 0; i < mutations.length; i++){ clone.addClass(mutations[i].oldValue); } $(document.body).append(clone); var cloneVisibility = $(clone).is(":visible"); $(clone).remove(); if (cloneVisibility != $(mutations[0].target).is(":visible")){ var visibilityChangedEvent = document.createEvent(''Event''); visibilityChangedEvent.initEvent(''visibilityChanged'', true, true); mutations[0].target.dispatchEvent(visibilityChangedEvent); } }); var targets = $(''.ui-collapsible-content''); $.each(targets, function(i,target){ target.addEventListener(''visibilityChanged'',VisbilityChanedEventHandler}); target.addEventListener(''DOMNodeRemovedFromDocument'',VisbilityChanedEventHandler }); observer.observe(target, { attributes: true, attributeFilter : [''class''], childList: false, attributeOldValue: true }); }); function VisbilityChanedEventHandler(e){console.log(''Kaboom babe''); console.log(e.target); }


Use jQuery Waypoints:

$(''#contentDiv'').waypoint(function() { alert(''do something''); });

Otros ejemplos en el sitio de jQuery Waypoints .


un desencadenador de eventos de ocultar / mostrar basado en la idea de Glenns: se ha eliminado el conmutador porque se activa mostrar / ocultar y no queremos 2fires para un evento

$(function(){ $.each(["show","hide", "toggleClass", "addClass", "removeClass"], function(){ var _oldFn = $.fn[this]; $.fn[this] = function(){ var hidden = this.find(":hidden").add(this.filter(":hidden")); var visible = this.find(":visible").add(this.filter(":visible")); var result = _oldFn.apply(this, arguments); hidden.filter(":visible").each(function(){ $(this).triggerHandler("show"); }); visible.filter(":hidden").each(function(){ $(this).triggerHandler("hide"); }); return result; } }); });


La solución de redsquare es la respuesta correcta.

Pero como solución IN-THEORY, puede escribir una función que seleccione los elementos clasificados por .visibilityCheck ( no todos los elementos visibles ) y verifique su valor de propiedad de visibility ; Si es true entonces haz algo.

Después, la función debe realizarse periódicamente utilizando la función setInterval() . Puede detener el temporizador utilizando el clearInterval() después de una llamada exitosa.

Aquí hay un ejemplo:

function foo() { $(''.visibilityCheck'').each(function() { if ($(this).is('':visible'')){ // do something } }); } window.setInterval(foo, 100);

También puede realizar algunas mejoras de rendimiento, sin embargo, la solución es básicamente absurda para ser utilizada en acción. Asi que...


mi solución:

; (function ($) { $.each([ "toggle", "show", "hide" ], function( i, name ) { var cssFn = $.fn[ name ]; $.fn[ name ] = function( speed, easing, callback ) { if(speed == null || typeof speed === "boolean"){ var ret=cssFn.apply( this, arguments ) $.fn.triggerVisibleEvent.apply(this,arguments) return ret }else{ var that=this var new_callback=function(){ callback.call(this) $.fn.triggerVisibleEvent.apply(that,arguments) } var ret=this.animate( genFx( name, true ), speed, easing, new_callback ) return ret } }; }); $.fn.triggerVisibleEvent=function(){ this.each(function(){ if($(this).is('':visible'')){ $(this).trigger(''visible'') $(this).find(''[data-trigger-visible-event]'').triggerVisibleEvent() } }) } })(jQuery);

ejemplo de uso:

if(!$info_center.is('':visible'')){ $info_center.attr(''data-trigger-visible-event'',''true'').one(''visible'',processMoreLessButton) }else{ processMoreLessButton() } function processMoreLessButton(){ //some logic }


$( window ).scroll(function(e,i) { win_top = $( window ).scrollTop(); win_bottom = $( window ).height() + win_top; //console.log( win_top,win_bottom ); $(''.onvisible'').each(function() { t = $(this).offset().top; b = t + $(this).height(); if( t > win_top && b < win_bottom ) alert("do something"); }); });


<div id="welcometo">Özhan</div> <input type="button" name="ooo" onclick="JavaScript: if(document.all.welcometo.style.display==''none'') { document.all.welcometo.style.display=''''; } else { document.all.welcometo.style.display=''none''; }">

Este código de control automático no requiere consulta visible o control invisible.