evento jQuery per triggersre l’azione quando un div è reso visibile

Sto usando jQuery nel mio sito e vorrei triggersre determinate azioni quando viene reso visibile un certo div.

È ansible colbind un qualche tipo di gestore di eventi “isvisibile” a div arbitrari e fare in modo che il codice venga eseguito quando il div è reso visibile?

Vorrei qualcosa come il seguente pseudocodice:

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

Il codice di avviso (“fai qualcosa”) non deve essere triggersto finché ContentDiv non viene effettivamente reso visibile.

Grazie.

Puoi sempre aggiungere al metodo originale .show () in modo da non dover triggersre eventi ogni volta che mostri qualcosa o se ne hai bisogno per lavorare con il codice legacy:

Estensione 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]); }); } }); 

Esempio di utilizzo:

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

In questo modo è ansible fare qualcosa prima di Show e After Show mentre si esegue ancora il normale comportamento del metodo originale .show ().

È anche ansible creare un altro metodo in modo da non dover sovrascrivere il metodo originale .show ().

Non c’è nessun evento nativo a cui puoi partecipare per questo, ma puoi triggersre un evento dal tuo script dopo aver reso il div visibile usando il. funzione di trigger

per esempio

 //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'); }); 

Il problema viene affrontato dagli osservatori di mutazione DOM . Ti consentono di associare un osservatore (una funzione) agli eventi di modifica del contenuto, del testo o degli attributi degli elementi dom.

Con il rilascio di IE11, tutti i principali browser supportano questa funzione, controlla http://caniuse.com/mutationobserver

Il codice di esempio è il seguente:

 $(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 }); }); 
    

È ansible utilizzare il plug-in Live Query di jQuery. E scrivi il codice come segue:

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

Quindi ogni volta che ContentDiv è visibile, “fai qualcosa” sarà avvisato!

La soluzione di redsquare è la risposta giusta.

Ma come soluzione IN-THEORY puoi scrivere una funzione che seleziona gli elementi classificati da .visibilityCheck ( non tutti gli elementi visibili ) e controlla il loro valore di visibility ; se è true allora fai qualcosa.

Successivamente, la funzione dovrebbe essere eseguita periodicamente utilizzando la funzione setInterval() . È ansible interrompere il timer utilizzando clearInterval() caso di chiamata riuscita.

Ecco un esempio:

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

È inoltre ansible eseguire alcuni miglioramenti delle prestazioni su di esso, tuttavia, la soluzione è fondamentalmente assurda da utilizzare in azione. Così…

Il seguente codice (tratto da http://maximeparmentier.com/2012/11/06/bind-show-hide-events-with-jquery/ ) ti permetterà di usare $('#someDiv').on('show', someFunc); .

 (function ($) { $.each(['show', 'hide'], function (i, ev) { var el = $.fn[ev]; $.fn[ev] = function () { this.trigger(ev); return el.apply(this, arguments); }; }); })(jQuery); 

Se vuoi triggersre l’evento su tutti gli elementi (e gli elementi figlio) effettivamente resi visibili, da $ .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; } }); 

E ora il tuo elemento:

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

Puoi aggiungere modifiche ad altre funzioni jQuery aggiungendole alla matrice in alto (come “attr”)

un triggerstore di hide / show basato sull’ideea di Glenns: rimosso toggle perché spara show / hide e non vogliamo 2fires per 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; } }); }); 

Ho avuto questo stesso problema e ho creato un plugin jQuery per risolverlo per il nostro sito.

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

Ecco come lo useresti in base al tuo esempio:

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

Usa jQuery Waypoint:

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

Altri esempi sul sito di jQuery Waypoints .

Puoi anche provare il plugin jQuery come indicato nel thread parallelo https://stackoverflow.com/a/3535028/741782

Questo supporto facilita e triggers l’evento dopo l’animazione! [testato su 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); 

Ispirato da http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/

È disponibile un plug-in jQuery per osservare i cambiamenti negli attributi DOM,

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

Il plugin si avvolge Tutto ciò che serve è associare MutationObserver

Puoi quindi usarlo per guardare il div usando:

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

Quello che mi ha aiutato qui è il polyfill delle specifiche ResizeObserver recente:

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

Si noti che è crossbrowser e performante (nessun polling).

Ho fatto una semplice funzione setinterval per raggiungere questo objective. Se l’elemento con class div1 è visibile, imposta div2 in modo che sia visibile. Non conosco un buon metodo, ma una soluzione semplice.

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

Ho modificato il trigger di evento hide / show da Catalint basato sull’idea di Glenns. Il mio problema era che ho un’applicazione modulare. Cambio tra i moduli mostrando e nascondendo i genitori di div. Quindi quando nascondo un modulo e ne mostro un altro, con il suo metodo ho un ritardo visibile quando cambio tra i moduli. A volte ho bisogno solo di accendere questo evento e in alcuni bambini speciali. Così ho deciso di notificare solo i bambini con la class “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; } }); 

Poi, quando un bambino vuole ascoltare l’evento “mostra” o “nascondi”, devo aggiungerlo alla class “displayObserver”, e quando non vuole continuare ad ascoltarlo, gli rimuovo la class

 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); }, 

Vorrei aiuto

Un modo per farlo.
Funziona solo con le modifiche alla visibilità apportate dalla modifica della class css, ma può essere esteso per controllare anche le modifiche agli attributi.

 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); } 

la mia soluzione:

 ; (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); 

esempio di utilizzo:

 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"); }); }); 

Spero che questo faccia il lavoro nel modo più semplice:

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

Questo controllo automatico del codice non richiede controllo visibile o invisibile