web-dev-qa-db-de.com

jQuery, wenn das Element sichtbar wird

Grundsätzlich frage ich mich, ob es eine Möglichkeit gibt, eine Funktion automatisch auszuführen, wenn ein Element ausgeblendet oder sichtbar wird, nicht auf einen Benutzer-Klick, sondern automatisch in ein anderes Skript.

Ich möchte nicht, dass dies nur einmal ausgeführt wird, da die Elemente (z. B. ein Schieberegler) ständig von sichtbar zu verborgen werden.

Könnte jQuery dies mit bind tun? So binden Sie die Sichtbarkeit des Elements an eine Funktion (ich weiß nicht, wie ich das schreiben soll)

Wenn Sie mehr darüber erfahren wollen, was ich versuche, lassen Sie es mich wissen. Vielen Dank

Pseudocode: 

$('#element').bind('display:none', function);
function(){
    //do something when element is display:none
}

$('#element').bind('display:block', function2);
function2(){
    //do opposite of function
}
43
sl133

Es gibt keine Ereignisse in JQuery, um CSS-Änderungen zu erkennen.
Siehe hier: onHide () Typereignis in jQuery

Es ist möglich:

DOM L2 Events-Modul definiert Mutationsereignisse; einer davon - DOMAttrModified ist der, den Sie brauchen. Zugegeben, diese sind nicht weit verbreitet, aber zumindest in Gecko und Opera unterstützt Browser.
Quelle: Ereigniserkennung, wenn die css-Eigenschaft mit Jquery geändert wurde

Ohne Ereignisse können Sie die setInterval-Funktion wie folgt verwenden:

var maxTime = 5000, // 5 seconds
    startTime = Date.now();

var interval = setInterval(function () {
        if ($('#element').is(':visible')) {
            // visible, do something
            clearInterval(interval);
        } else {
            // still hidden
            if (Date.now() - startTime > maxTime) {
                // hidden even after 'maxTime'. stop checking.
                clearInterval(interval);
            }
        }
    },
    100 // 0.1 second (wait time between checks)
);

Beachten Sie, dass die Verwendung von setInterval zum Behalten einer Uhr die Leistung Ihrer Seite beeinträchtigen kann.

7. Juli 2018:
Da diese Antwort in letzter Zeit einige Sichtbarkeit und Up-Votes hat, finden Sie hier weitere Informationen zum Erkennen von CSS-Änderungen: 

Mutationsereignisse wurden jetzt durch den leistungsstärkeren Mutation Observer ersetzt.

Die MutationObserver-Schnittstelle bietet die Möglichkeit, Änderungen an der DOM-Struktur zu überwachen. Es wurde als Ersatz für die ältere Mutationsereignisfunktion entwickelt, die Teil der DOM3-Ereignisspezifikation war. 

Siehe: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

26
P5Coder
(function() {
    var ev = new $.Event('display'),
        orig = $.fn.css;
    $.fn.css = function() {
        orig.apply(this, arguments);
        $(this).trigger(ev);
    }
})();

$('#element').bind('display', function(e) {
    alert("display has changed to :" + $(this).attr('style') );
});

$('#element').css("display", "none")// i change the style in this line !!
$('#element').css("display", "block")// i change the style in this line !!

http://fiddle.jshell.net/prollygeek/gM8J2/3/

Änderungen werden gemeldet.

17
ProllyGeek

Versuchte dies auf Firefox, funktioniert http://jsfiddle.net/Tm26Q/1/

$(function(){
 /** Just to mimic a blinking box on the page**/
  setInterval(function(){$("div#box").hide();},2001);
  setInterval(function(){$("div#box").show();},1000);
 /**/
});

$("div#box").on("DOMAttrModified",
function(){if($(this).is(":visible"))console.log("visible");});

AKTUALISIEREN

Derzeit werden die Mutation Events (wie DOMAttrModified in der -Lösung) durch MutationObserver ersetzt. Sie können dies für .__ verwenden. Erkennen von DOM-Knotenänderungen wie im obigen Fall.

4
user2587132

Ich habe gerade die ProllyGeek `s Antwort verbessert 

Jemand kann es nützlich finden. Sie können auf das Ereignis displayChanged(event, state) zugreifen, wenn für das Element .show(), .hide() oder .toggle() aufgerufen wird

(function() {
  var eventDisplay = new $.Event('displayChanged'),
    origShow = $.fn.show,
    origHide = $.fn.hide;
  //
  $.fn.show = function() {
    origShow.apply(this, arguments);
    $(this).trigger(eventDisplay,['show']);
  };
  //
  $.fn.hide = function() {
    origHide.apply(this, arguments);
    $(this).trigger(eventDisplay,['hide']);
  };
  //
})();

$('#header').on('displayChanged', function(e,state) {
      console.log(state);
});

$('#header').toggle(); // .show() .hide() supported
2
django

Ein catch-all jQuery-benutzerdefiniertes Ereignis, das auf einer Erweiterung seiner Kernmethoden basiert, wie es von verschiedenen Personen in diesem Thread vorgeschlagen wurde:

(function() {
    var ev = new $.Event('event.css.jquery'),
        css = $.fn.css,
        show = $.fn.show,
        hide = $.fn.hide;

    // extends css()
    $.fn.css = function() {
        css.apply(this, arguments);
        $(this).trigger(ev);
    };

    // extends show()
    $.fn.show = function() {
        show.apply(this, arguments);
        $(this).trigger(ev);
    };

    // extends hide()
    $.fn.hide = function() {
        hide.apply(this, arguments);
        $(this).trigger(ev);
    };
})();

Eine externe Bibliothek verwendet dann etw wie $('selector').css('property', value).

Da wir den Code der Bibliothek nicht ändern wollen, aber DO das Verhalten der Bibliothek erweitern möchten, tun wir dies wie folgt:

$('#element').on('event.css.jquery', function(e) {
    // ...more code here...
});

Beispiel: Der Benutzer klickt auf ein Panel, das aus einer Bibliothek besteht. Die Bibliothek zeigt/versteckt Elemente basierend auf der Benutzerinteraktion. Wir möchten einen Sensor hinzufügen, der anzeigt, dass etw aufgrund dieser Interaktion verborgen/angezeigt wurde und after der Bibliotheksfunktion genannt werden sollte.

Ein anderes Beispiel: jsfiddle .

0
centurian

Ich mag Plugin https://github.com/hazzik/livequery Es funktioniert ohne Timer!

Einfache Benutzung

$('.some:visible').livequery( function(){ ... } );

Aber Sie müssen einen Fehler beheben. Zeile ersetzen

$jQlq.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove', 'html', 'prop', 'removeProp');

zu

$jQlq.registerPlugin('show', 'append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove', 'html', 'prop', 'removeProp');
0
Rabotyahoff