2009-09-22 6 views
53

Ich baue eine Symbolleiste, die in einer Seite enthalten sein wird. das Div, in dem es enthalten sein wird, wird standardmäßig auf angezeigt: keine. Gibt es eine Möglichkeit, einen Ereignis-Listener auf meine Symbolleiste zu legen, auf den ich achten muss, wenn er sichtbar wird, damit er initialisiert werden kann? Oder muss ich eine Variable von der enthaltenden Seite übergeben?JS: Ereignis-Listener für wann Element sichtbar wird?

Dank

+0

Hilft diese Antwort? http://stackoverflow.com/questions/1397251/event-detect-when-css-property-changed-using-jquery#answer-1397500 – kangax

+0

@ Kangax, danke. Aber da es nicht weit verbreitet ist, denke ich, dass ich die ganze Event-Hörer-Idee zerkratzen werde und einen anderen Weg gehen werde. –

+0

Finden Sie diese Antwort für eine Implementierung eines "onVisible" -Ereignisses in JavaScript: http://Stackoverflow.com/a/3807340/975097 –

Antwort

9

JavaScript-Ereignisse befassen sich mit Benutzerinteraktion, wenn Ihr Code ausreichend organisiert ist, sollten Sie in der Lage sein, die Initialisierungsfunktion an derselben Stelle aufzurufen, an der sich die Sichtbarkeit ändert (dh Sie sollten myElement.style.display an vielen Stellen nicht ändern, rufen Sie stattdessen eine Funktion/Methode, die dies und nichts anderes tut Sie vielleicht)

+8

Aber wie würden Sie in der Lage sein, die Änderung in der Sichtbarkeit zu erkennen (d. H. Eine Funktion aufrufen, sobald ein Element sichtbar wird)? –

+0

Ich weiß das du das nicht kannst. Was Sie tun würden, anstatt zu versuchen, die Veränderung zu erkennen, ist es, genau zu wissen, wo es provoziert wird, und Ihren Anruf dorthin zu bringen. Wenn die Änderung in der Sichtbarkeit nicht etwas ist, für das der eigene Code direkt verantwortlich ist (z. B. einige Lib), und die Logik, mit der das geschieht, ist sehr künstlich, denke ich, dass du kein Glück hast? :) – figha

+2

Ich habe diese Frage abgelehnt, weil es trotz all dem Sinn, den es macht, für das eigentliche Problem irrelevant ist. (Wenn ich keine auf einem Rahmen zeige, werden alle Kinderelemente unsichtbar) – Sebas

11

Es gibt mindestens eine Art und Weise, aber es ist nicht sehr gut. Sie könnten nur das Element für Änderungen wie diese Umfrage:

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

Der DOM-Standard spezifiziert auch mutation events, aber ich hatte nie die Chance, sie zu benutzen, und ich bin nicht sicher, wie gut sie unterstützt sind. Sie würden sie wie folgt verwenden:

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

Dieser Code aus der Spitze von meinem Kopf, so dass ich bin mir nicht sicher, ob es funktionieren würde.

Die beste und einfachste Lösung wäre, einen Rückruf in der Funktion zur Anzeige Ihres Ziels zu haben.

+0

Interessant, danke. Ein paar Jahre später hat sich der Status von DOMAttrModified geändert: "Veraltet. Dieses Feature wurde aus den Webstandards entfernt. Obwohl einige Browser es möglicherweise weiterhin unterstützen, wird es gerade gelöscht." (Mozilla) – BurninLeo

-1

meine Lösung:

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

zum Beispiel:

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

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

Sie sollten jedem sagen, dass Sie den ursprünglichen jQuery-Code verwendet haben, es würde mehr Vertrauen wecken;) – aemonge

3

Wie @figha sagt, Wenn dies Ihre eigene Webseite ist, sollten Sie einfach ausführen, was Sie brauchen, um zu starten, nachdem Sie das Element sichtbar gemacht haben.

jedoch für die Zwecke der Beantwortung der Frage (und jemand machen Chrome oder Firefox Extensions, wo dies ist ein häufiger Anwendungsfall), Mutation Summary und Mutation Observer ermöglichen DOM ändert Ereignisse auszulösen.

Zum Beispiel Auslösen eines Ereignisses für ein Element mit data-widget Attribut, das dem DOM hinzugefügt wird. this excellent example from David Walsh's blog Ausleihe:

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

Antworten umfassen added, removed, valueChanged and more. valueChanged enthält alle Attribute, einschließlich display usw.

+1

Äh, kümmert sich der Downvoter darum, warum? – mikemaccana

+0

Wahrscheinlich, weil er wissen will, wann es tatsächlich auf dem Bildschirm ist. Ich kann, ich kann nur annehmen, dass der Downvoter den gleichen Grund hat. –

+0

Beantwortet die Frage nicht und es wird nicht empfohlen, nur Links zu veröffentlichen. –

2

einfach auf der Ereignis-Listener-Browser-Unterstützung DOMAttrModified Kommentar zu:

Unterstützung Kreuz Browser

Diese Ereignisse nicht konsistent über verschiedene umgesetzt werden Browser, zum Beispiel:

  • IE vor Version 9 hat die Mutationsereignisse überhaupt nicht unterstützen und hat einige von ihnen richtig in Version 9 (zum Beispiel DOMNodeInserted)

  • WebKit unterstützt keine DOMAttrModified nicht implementieren (siehe 8191 webkit Fehler und die Abhilfe)

  • "Mutation Name Ereignisse", dh DOMElementNameChanged und DOMAttributeNameChanged nicht in Firefox unterstützt (ab Version 11) und wahrscheinlich auch in anderen Browsern als auch.

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

13

Ich hatte das gleiche Problem und schuf ein jQuery-Plugin für unsere Website zu lösen.

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

Hier ist, wie Sie es basierend auf Ihrem Beispiel verwenden würde:

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

Kann nicht auf AJAX getriggerter Sichtbarkeit funktionieren – JackTheKnife

5

Auch in Zukunft die neue HTML-Überschneidung Observer API die Sache ist, die Sie suchen. Sie können einen Rückruf konfigurieren, der immer dann aufgerufen wird, wenn ein Element, das Ziel genannt wird, entweder das Gerätefenster oder ein bestimmtes Element schneidet. Es ist in den neuesten Versionen von Chrome, Firefox und Edge verfügbar. Weitere Informationen finden Sie unter https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API.

Einfaches Codebeispiel für die Beobachtung display: none Schalt:

// 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 Aktion: https://jsfiddle.net/elmarj/u35tez5n/5/

+1

> Die Intersection Observer API ermöglicht es Ihnen, einen Callback zu konfigurieren, der aufgerufen wird, wenn ein Element, das Ziel genannt, entweder das Geräte-Viewport oder ein bestimmtes Element schneidet; – 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 }); 

ich vielleicht ein wenig spät, aber man kann nur die MutationObserver verwenden, um alle Änderungen zu beobachten auf das gewünschte Element. Wenn Änderungen auftreten, müssen Sie nur prüfen, ob das Element angezeigt wird.

+0

Die einzige Antwort gibt mir 2018 ein gutes Gefühl – userlond

Verwandte Themen