jQuery事件触发行动时,div是可见的

我在我的网站中使用jQuery,我想触发某些特定的行动时,可见。

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

我想像下面的伪代码:

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

警报(“做某事”)代码不应该触发,直到contentDiv实际上可见。

谢谢。

您始终可以添加到原始的.show()方法,因此您不必在每次显示内容时触发事件,也不必在遗留代码中使用它。

jquery扩展:

 jQuery(function($) { var _oldShow = $.fn.show; $.fn.show = function(speed, oldCallback) { return $(this).each(function() { var obj = $(this), newCallback = function() { if ($.isFunction(oldCallback)) { oldCallback.apply(obj); } obj.trigger('afterShow'); }; // you can trigger a before show if you want obj.trigger('beforeShow'); // now use the old function to show the element passing the new callback _oldShow.apply(obj, [speed, newCallback]); }); } }); 

用法示例:

 jQuery(function($) { $('#test') .bind('beforeShow', function() { alert('beforeShow'); }) .bind('afterShow', function() { alert('afterShow'); }) .show(1000, function() { alert('in show callback'); }) .show(); }); 

这可以让你在执行原始的.show()方法的正常行为的同时,在ShowShow和AfterShow之前做一些事情。

你也可以创建另一个方法,所以你不必重写原始的.show()方法。

没有本身的事件,你可以为此插入,但是你可以从你的脚本触发一个事件后,你可以使用。 触发功能

例如

 //declare event to run when div is visible function isVisible(){ //do something } //hookup the event $('#someDivId').bind('isVisible', isVisible); //show div and trigger custom event in callback when div is visible $('#someDivId').show('slow', function(){ $(this).trigger('isVisible'); }); 

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

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

示例代码如下:

 $(function() { $('#show').click(function() { $('#testdiv').show(); }); var observer = new MutationObserver(function(mutations) { alert('Attributes changed!'); }); var target = document.querySelector('#testdiv'); observer.observe(target, { attributes: true }); }); 
 <div id="testdiv" style="display:none;">hidden</div> <button id="show">Show hidden div</button> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 

你可以使用jQuery的livequery插件。 并编写代码如下:

 $('#contentDiv:visible').livequery(function() { alert("do something"); }); 

然后,每当contentDiv可见时,“做某事”将会被提醒!

redsquare的解决方案是正确的/逻辑的答案。

但作为IN-THEORY解决方案,您可以编写一个功能,选择由.visibilityCheck类( 不是所有可见元素 )分类的元素并检查其visibility属性值; 如果true那么做点什么。 好?
之后,应该使用setInterval()函数定期执行函数。 如您所知,可以使用clearInterval()和函数成功调出时的计时器ID来停止计时器。

 function foo(){ $('.visibilityCheck').each(function(){ if($(this).is(':visible')){ //do something } }); } //foo() window.setInterval(foo, 100); 

你也可以在这方面做一些性能上的改进,但是我想这个解决方案基本上被忽略了。

如果您想触发实际可见的所有元素(和子元素)上的事件,请按$ .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); }); 

您可以通过将其添加到顶部数组(如“attr”)来将其他jQuery函数的覆盖

基于Glenns ideea的隐藏/显示事件触发器:删除切换,因为它触发显示/隐藏,并且我们不希望双事件发生在一个事件

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

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

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

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

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

下面是你将如何使用它的基础上你的例子:

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

使用jQuery Waypoints:

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

jQuery Waypoint网站上的其他例子。

您也可以尝试jQuery出现插件提到的并行线程https://stackoverflow.com/a/3535028/741782

这个动画完成后支持缓动和触发事件! [在jQuery 2.2.4上测试]

 (function ($) { $.each(['show', 'hide', 'fadeOut', 'fadeIn'], function (i, ev) { var el = $.fn[ev]; $.fn[ev] = function () { var result = el.apply(this, arguments); var _self=this; result.promise().done(function () { _self.triggerHandler(ev, [result]); //console.log(_self); }); return result; }; }); })(jQuery); 

启发由http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/

有一个jQuery插件可用于观看DOM属性的变化,

https://github.com/darcyclarke/jQuery-Watch-Plugin

插件包装所有你需要做的就是绑定MutationObserver

您可以使用它来观看div使用:

 $("#selector").watch('css', function() { console.log("Visibility: " + this.style.display == 'none'?'hidden':'shown')); //or any random events }); 

基于Glenns的想法,我改变了Catalint的hide / show事件触发器。 我的问题是,我有一个模块化的应用程序。 我改变模块显示和隐藏divs父母。 然后,当我隐藏一个模块,并显示另一个,用他的方法,我有一个明显的延迟,当我改变模块之间。 我只是有时候需要把这个事件和一些特殊的孩子扔掉。 所以我决定只通知班级“displayObserver”的孩子

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

那么当一个孩子想要听“show”或“hide”事件时,我不得不为他添加“displayObserver”类,而当它不想继续听时,我把他移除

 bindDisplayEvent: function () { $("#child1").addClass("displayObserver"); $("#child1").off("show", this.onParentShow); $("#child1").on("show", this.onParentShow); }, bindDisplayEvent: function () { $("#child1").removeClass("displayObserver"); $("#child1").off("show", this.onParentShow); }, 

我希望能帮到你

一种方法来做到这一点。
仅适用于由css类更改所做的可见性更改,但也可以扩展以监视属性更改。

 var observer = new MutationObserver(function(mutations) { var clone = $(mutations[0].target).clone(); clone.removeClass(); for(var i = 0; i < mutations.length; i++){ clone.addClass(mutations[i].oldValue); } $(document.body).append(clone); var cloneVisibility = $(clone).is(":visible"); $(clone).remove(); if (cloneVisibility != $(mutations[0].target).is(":visible")){ var visibilityChangedEvent = document.createEvent('Event'); visibilityChangedEvent.initEvent('visibilityChanged', true, true); mutations[0].target.dispatchEvent(visibilityChangedEvent); } }); var targets = $('.ui-collapsible-content'); $.each(targets, function(i,target){ target.addEventListener('visibilityChanged',VisbilityChanedEventHandler}); target.addEventListener('DOMNodeRemovedFromDocument',VisbilityChanedEventHandler }); observer.observe(target, { attributes: true, attributeFilter : ['class'], childList: false, attributeOldValue: true }); }); function VisbilityChanedEventHandler(e){console.log('Kaboom babe'); console.log(e.target); } 

我的解决方案

 ; (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 } 
 $( window ).scroll(function(e,i) { win_top = $( window ).scrollTop(); win_bottom = $( window ).height() + win_top; //console.log( win_top,win_bottom ); $('.onvisible').each(function() { t = $(this).offset().top; b = t + $(this).height(); if( t > win_top && b < win_bottom ) alert("do something"); }); }); 

希望这会以最简单的方式完成工作:

 $("#myID").on('show').trigger('displayShow'); $('#myID').off('displayShow').on('displayShow', function(e) { console.log('This event will be triggered when myID will be visible'); }); 

这里帮助我的是最近的ResizeObserver spec polyfill :

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

请注意,它是交叉浏览器和高性能(无轮询)。

 <div id="welcometo">Özhan</div> <input type="button" name="ooo" onclick="JavaScript: if(document.all.welcometo.style.display=='none') { document.all.welcometo.style.display=''; } else { document.all.welcometo.style.display='none'; }"> 

这个代码自动控制不需要查询可见或不可见的控制