我在我的网站上使用jQuery,我想在某个div可见时触发某些操作。

是否有可能附加某种“isvisible”事件处理程序到任意div,并有一定的代码运行时,他们的div是可见的?

我想要如下伪代码:

$(function() {
  $('#contentDiv').isvisible(function() {
    alert("do something");
  });
});

警报(“do something”)代码在contentDiv实际可见之前不应该触发。

谢谢。


当前回答

我有同样的问题,并创建了一个jQuery插件来解决我们的网站。

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

下面是基于你的例子你应该如何使用它:

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

其他回答

下面的代码(来自http://maximeparmentier.com/2012/11/06/bind-show-hide-events-with-jquery/)将使您能够使用$('#someDiv')。(“秀”,someFunc);。

(function ($) {
  $.each(['show', 'hide'], function (i, ev) {
    var el = $.fn[ev];
    $.fn[ev] = function () {
      this.trigger(ev);
      return el.apply(this, arguments);
    };
  });
})(jQuery);

我的解决方案:

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

使用示例:

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

function processMoreLessButton(){
//some logic
}

DOM突变观察者正在解决这个问题。它们允许你将观察者(一个函数)绑定到改变dom元素的内容、文本或属性的事件上。

随着IE11的发布,所有主流浏览器都支持此功能,请访问http://caniuse.com/mutationobserver

示例代码如下:

$(函数() { $('#show').click(function() { $('#testdiv').show(); }); var observer = new MutationObserver (function(mutations) { 警报(“属性已更改! }); var target = document.querySelector('#testdiv'); observer.observe(target, { 属性:真 }); }); <div id=“testdiv” style=“display:none;”>hidden</div> <按钮 id=“显示”>显示隐藏的 div</button> <script type=“text/javascript” src=“https://code.jquery.com/jquery-1.9.1.min.js”></script>

如果您想在所有实际可见的元素(和子元素)上触发事件,则使用$。show, toggle, toggleClass, addClass,或removeClass:

$.each(["show", "toggle", "toggleClass", "addClass", "removeClass"], function(){
    var _oldFn = $.fn[this];
    $.fn[this] = function(){
        var hidden = this.find(":hidden").add(this.filter(":hidden"));
        var result = _oldFn.apply(this, arguments);
        hidden.filter(":visible").each(function(){
            $(this).triggerHandler("show"); //No bubbling
        });
        return result;
    }
});

现在是元素:

$("#myLazyUl").bind("show", function(){
    alert(this);
});

你可以通过将额外的jQuery函数添加到顶部的数组(如“attr”)来添加覆盖。

在这里帮助我的是最近的ResizeObserver规格polyfill:

const divEl = $('#section60');

const ro = new ResizeObserver(() => {
    if (divEl.is(':visible')) {
        console.log("it's visible now!");
    }
});
ro.observe(divEl[0]);

注意,它是跨浏览器和性能的(没有轮询)。