Question jQuery quand l'élément devient visible


Fondamentalement, je me demande s'il existe un moyen d'exécuter automatiquement une fonction lorsqu'un élément devient caché ou visible, pas sur un clic d'utilisateur mais automatiquement dans un autre script.

Je ne veux pas que cela se produise une seule fois, car les éléments (comme un curseur) changent constamment de visible à caché.

Serait-ce quelque chose que jQuery peut faire avec bind? Tels que lier la visibilité de l'élément à une fonction (je ne sais pas comment écrire ceci)

Si vous avez besoin de plus de détails sur ce que j'essaie de faire, faites-le moi savoir. Merci

Pseudocode:

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

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

40
2017-12-10 06:15


origine


Réponses:


Il n'y a aucun événement dans JQuery pour détecter les modifications CSS.
Reportez-vous ici: événement de type onHide () dans jQuery

C'est possible:

Le module d'événements DOM L2 définit les événements de mutation; l'un d'eux - DOMAttrModified est celui dont vous avez besoin. Certes, ceux-ci ne sont pas largement mis en œuvre, mais sont pris en charge au moins dans Gecko et Opera navigateurs.
  La source: Un événement détecte la modification de la propriété css à l'aide de Jquery 

Sans événements, vous pouvez utiliser setInterval fonction, comme ceci:

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

Notez qu'en utilisant setInterval De cette façon, pour garder une montre, cela peut affecter les performances de votre page.

7 juillet 2018:
Étant donné que cette réponse est en train d’obtenir de la visibilité et des votes positifs récemment, voici une mise à jour supplémentaire sur la détection des modifications CSS:

Les événements de mutation ont été remplacés par l'observateur de mutation plus convivial.

L'interface MutationObserver permet de surveiller les modifications apportées à l'arborescence DOM. Il est conçu pour remplacer l'ancienne fonctionnalité Mutation Events qui faisait partie de la spécification DOM3 Events.

Référer: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver


26
2017-12-10 06:23



(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/

les modifications seront alertées.


16
2017-12-10 06:22



Essayé cela sur Firefox, fonctionne 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");});

METTRE À JOUR

Actuellement le Événements de mutation (comme DOMAttrModified utilisé dans le   solution) sont remplacés par MutationObserver, Vous pouvez l'utiliser pour   détecter les modifications du noeud DOM comme dans le cas ci-dessus.


4
2017-12-10 06:48



Je viens d'améliorer ProllyGeek`réponse

Quelqu'un peut le trouver utile. vous pouvez accéder displayChanged(event, state) événement quand .show(), .hide() ou .toggle() est appelé sur l'élément

(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
2018-03-04 09:32



J'aime le plugin https://github.com/hazzik/livequery Cela fonctionne sans timers!

Usage simple

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

Mais vous devez corriger une erreur. Remplacer la ligne

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

à

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

0
2017-09-06 13:10



Un fourre-tout événement personnalisé jQuery basé sur une extension de ses méthodes de base comme il a été proposé par différentes personnes dans ce fil de discussion:

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

Une bibliothèque externe utilise alors sth comme $('selector').css('property', value).

Comme nous ne voulons pas modifier le code de la bibliothèque mais nous FAIRE veux étendre le comportement que nous faisons sth comme:

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

Exemple: l'utilisateur clique sur un panneau créé par une bibliothèque. La bibliothèque affiche / masque les éléments en fonction de l'interaction de l'utilisateur. Nous voulons ajouter un capteur qui montre que sth a été caché / montré à cause de cette interaction et devrait être appelé après la fonction de la bibliothèque.

Un autre exemple: jsfiddle.


0
2018-03-07 14:30