2009-09-22 8 views
53

Sto costruendo una barra degli strumenti che verrà inclusa in una pagina. il div che verrà incluso in default sarà visualizzato sul display : nessuno. C'è un modo in cui posso mettere un listener di eventi sulla mia barra degli strumenti per ascoltare quando diventa visibile in modo che possa essere inizializzato? o dovrò passarlo una variabile dalla pagina contenente?JS: listener di eventi per quando l'elemento diventa visibile?

Grazie

+0

Questa risposta è utile? http://stackoverflow.com/questions/1397251/event-detect-when-css-property-changed-using-jquery#answer-1397500 – kangax

+0

@kangax, grazie. Ma dal momento che non è ampiamente implementato penso che avrò intenzione di scalfire l'intera idea dell'ascoltatore dell'evento e di seguire una strada diversa. –

+0

Vedere questa risposta per l'implementazione di un evento "onVisible" in JavaScript: http://stackoverflow.com/a/3807340/975097 –

risposta

9

gli eventi javascript interagiscono con l'interazione dell'utente, se il tuo codice è organizzato abbastanza dovresti essere in grado di chiamare la funzione di inizializzazione nello stesso posto in cui la visibilità cambia (cioè non dovresti cambiare myElement.style.display in molti posti, invece, richiamare una funzione/metodo che fa questo e qualsiasi altra cosa si potrebbe desiderare)

+8

Ma come si sarebbe in grado di rilevare il cambiamento di visibilità (ad esempio, chiamare una funzione non appena un elemento diventa visibile)? –

+0

Io penso che non puoi farlo. Quello che faresti invece di cercare di rilevare il cambiamento, è sapere esattamente dove è provocato e mettere la tua chiamata lì. Se il cambiamento di visibilità non è qualcosa di cui il proprio codice è direttamente responsabile (ad esempio un po 'di lib) e la logica con cui ciò accade è molto artificiosa, suppongo che tu non abbia fortuna? :) – figha

+2

Ho downvoted questa domanda perché nonostante tutto il senso che ha, è irrilevante per il problema reale. (se non visualizzo nessuno su una cornice, tutti gli elementi figli diventano invisibili) – Sebas

11

c'è almeno un modo, ma non è molto buona. Si può solo interrogare l'elemento di cambiamenti come questo:

var previous_style, 
    poll = window.setInterval(function() 
{ 
    var current_style = document.getElementById('target').style.display; 
    if (previous_style != current_style) { 
     alert('style changed'); 
     window.clearInterval(poll); 
    } else { 
     previous_style = current_style; 
    } 
}, 100); 

Lo standard DOM specifica anche mutation events, ma non ho mai avuto la possibilità di utilizzarli, e non sono sicuro di come stanno supportati. Tu li usereste in questo modo:

target.addEventListener('DOMAttrModified', function() 
{ 
    if (e.attrName == 'style') { 
     alert('style changed'); 
    } 
}, false); 

Questo codice è la parte superiore della mia testa, quindi non sono sicuro se avesse funzionato.

Il migliore e la soluzione più semplice sarebbe quella di avere una richiamata nella funzione di visualizzazione del target.

+0

Interessante, grazie. Qualche anno dopo, lo stato di DOMAttrModified è cambiato: "Deprecato, questa funzionalità è stata rimossa dagli standard Web. Sebbene alcuni browser possano ancora supportarlo, è in fase di rilascio". (Mozilla) – BurninLeo

-1

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

ad esempio:

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

function processMoreLessButton(){ 
//some logic 
} 
+3

Dovresti dire a tutti che hai usato il codice jQuery originale, che ispirerebbe maggiore sicurezza;) – aemonge

3

Come dice @figha, se questa è la tua pagina web, dovresti eseguire tutto ciò che è necessario eseguire dopo aver reso visibile l'elemento.

Tuttavia, ai fini della soluzione della questione (e nessuno rendendo Chrome o Firefox estensioni, dove questo è un caso di uso comune), Mutation Summary e Mutation Observer permetterà DOM cambia per innescare eventi.

Ad esempio, attivazione di un evento per elementi con attributo data-widget aggiunto al DOM. Prendendo in prestito this excellent example from David Walsh's blog:

var observer = new MutationObserver(function(mutations) { 
    // For the sake of...observation...let's output the mutation to console to see how this all works 
    mutations.forEach(function(mutation) { 
     console.log(mutation.type); 
    });  
}); 

// Notify me of everything! 
var observerConfig = { 
    attributes: true, 
    childList: true, 
    characterData: true 
}; 

// Node, config 
// In this case we'll listen to all changes to body and child nodes 
var targetNode = document.body; 
observer.observe(targetNode, observerConfig); 

Risposte includono added, removed, valueChanged and more. valueChanged include tutti gli attributi, incluso display ecc.

+1

Er, il downvoter si preoccupa di spiegare perché? – mikemaccana

+0

Probabilmente perché vuole sapere quando è effettivamente sullo schermo. Lo so, posso solo supporre che il downfer ha la stessa ragione. –

+0

Non risponde alla domanda e la pubblicazione di soli collegamenti non è consigliata. –

2

Giusto per commentare il supporto del browser listener di eventi DOMAttrModified:

Cross-Browser supporto

Questi eventi non sono applicate in modo coerente tra i diversi browser, ad esempio:

  • IE prima della versione 9 non supportano gli eventi di mutazione a tutti e non implementa alcuni di loro correttamente nella versione 9 (per esempio, DOMNodeInserted)

  • WebKit non supporta DOMAttrModified (vedi WebKit bug 8191 e il soluzione)

  • "nome mutazione eventi", vale a dire DOMElementNameChanged e DOMAttributeNameChanged non sono supportati in Firefox (dalla versione 11), e probabilmente anche in altri browser come bene.

Fonte: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events

13

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

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

Ecco come si dovrebbe utilizzare in base a tuo esempio:

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

Impossibile far funzionare la visibilità attivata AJAX – JackTheKnife

5

Andando avanti, la nuova API HTML Intersezione Observer è la cosa che stai cercando. Ti consente di configurare un callback che viene chiamato ogni volta che un elemento, chiamato target, interseca la vista del dispositivo o un elemento specificato. È disponibile nelle ultime versioni di Chrome, Firefox e Edge. Vedi https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API per maggiori informazioni.

esempio di codice semplice per l'osservazione di display: none commutazione:

// Start observing visbility of element. On change, the 
// the callback is called with Boolean visibility as 
// argument: 

respondToVisibility(element, callback) { 
    var options = { 
    root: document.documentElement 
    } 

    var observer = new IntersectionObserver((entries, observer) => { 
    entries.forEach(entry => { 
     callback(entry.intersectionRatio > 0); 
    }); 
    }, options); 

    observer.observe(element); 
} 

In azione: https://jsfiddle.net/elmarj/u35tez5n/5/

+1

> L'API Intersection Observer consente di configurare una richiamata che viene richiamata ogni volta che un elemento, denominato target, interseca la vista del dispositivo o un elemento specificato; – stil

1
var targetNode = document.getElementById('elementId'); 
var observer = new MutationObserver(function(){ 
    if(targetNode.style.display !='none'){//doSomething } 
}); 
observer.observe(targetNode, { attributes: true, childList: true }); 

mi potrebbe essere un po 'in ritardo, ma si potrebbe utilizzare il MutationObserver per osservare eventuali modifiche sull'elemento desiderato Se si verifica qualche cambiamento, devi solo controllare se l'elemento è visualizzato.

+0

L'unica risposta mi fa sentire bene nel 2018 – userlond

Problemi correlati