Event listener for when element becomes visible?

后端 未结 9 1712
感情败类
感情败类 2020-11-28 05:36

I am building a toolbar that is going to be included into a page. the div it is going to be included in will default to display:none. Is there a way i can p

相关标签:
9条回答
  • 2020-11-28 06:12

    Going forward, the new HTML Intersection Observer API is the thing you're looking for. It allows you to configure a callback that is called whenever one element, called the target, intersects either the device viewport or a specified element. It's available in latest versions of Chrome, Firefox and Edge. See https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API for more info.

    Simple code example for observing display:none switching:

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

    0 讨论(0)
  • 2020-11-28 06:13

    I had this same problem and created a jQuery plugin to solve it for our site.

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

    Here is how you would use it based on your example:

    $('#contentDiv').visibilityChanged(function(element, visible) {
        alert("do something");
    });
    
    0 讨论(0)
  • 2020-11-28 06:14

    Javascript events deal with User Interaction, if your code is organised enough you should be able to call the initialising function in the same place where the visibility changes (i.e. you shouldn't change myElement.style.display on many places, instead, call a function/method that does this and anything else you might want).

    0 讨论(0)
  • 2020-11-28 06:15

    There is at least one way, but it's not a very good one. You could just poll the element for changes like this:

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

    The DOM standard also specifies mutation events, but I've never had the chance to use them, and I'm not sure how well they're supported. You'd use them like this:

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

    This code is off the top of my head, so I'm not sure if it'd work.

    The best and easiest solution would be to have a callback in the function displaying your target.

    0 讨论(0)
  • 2020-11-28 06:16

    You may also try this jQuery plugin: https://github.com/morr/jquery.appear

    0 讨论(0)
  • 2020-11-28 06:16

    my solution:

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

    for example:

    if(!$info_center.is(':visible')){
        $info_center.attr('data-trigger-visible-event','true').one('visible',processMoreLessButton)
    }else{
        processMoreLessButton()
    }
    
    function processMoreLessButton(){
    //some logic
    }
    
    0 讨论(0)
提交回复
热议问题