Answers:
您总是可以添加到原始的.show()方法中,这样您就不必在每次显示某些东西或需要它与遗留代码一起使用时都触发事件:
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()方法的正常行为的同时执行beforeShow和afterShow操作。
您也可以创建另一个方法,这样就不必覆盖原始的.show()方法。
fadeTo
功能无法正常实现此功能后才能正常运行
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>
没有本地事件可以挂接到此事件,但是使用可以使div可见后,可以从脚本中触发事件。触发功能
例如
//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');
});
show()
从上述代码块之外的多个地方调用if,该怎么办?
onIsVisible
因为现在对“ isVisible”的使用有点模棱两可。
您可以使用jQuery的Live Query插件。并编写如下代码:
$('#contentDiv:visible').livequery(function() {
alert("do something");
});
然后,每当contentDiv可见时,都会提醒“做某事”!
redsquare的解决方案是正确的答案。
但是,作为一个IN-THEORY解决方案,您可以编写一个函数,该函数选择按分类的元素.visibilityCheck
(并非所有可见元素)并检查其visibility
属性值。如果true
那么做。
之后,应使用该setInterval()
功能定期执行该功能。您可以使用clearInterval()
成功调用来停止计时器。
这是一个例子:
function foo() {
$('.visibilityCheck').each(function() {
if ($(this).is(':visible')){
// do something
}
});
}
window.setInterval(foo, 100);
您还可以对其执行一些性能改进,但是,该解决方案基本上是荒谬的,无法在实际中使用。所以...
display:none
?
以下代码(从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);
el.apply(this, arguments)
即可解决此问题。
如果要在实际上变为可见的所有元素(和子元素)上触发事件,请通过$ .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”)
基于Glenns想法的隐藏/显示事件触发器:删除了切换,因为它触发了显示/隐藏,我们不希望一次触发2次
$(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;
}
});
});
我遇到了同样的问题,并创建了一个jQuery插件来解决我们网站的问题。
https://github.com/shaunbowe/jquery.visibilityChanged
根据示例,使用方法如下:
$('#contentDiv').visibilityChanged(function(element, visible) {
alert("do something");
});
使用jQuery Waypoints:
$('#contentDiv').waypoint(function() {
alert('do something');
});
jQuery Waypoints网站上的其他示例。
在这里帮助我的是最近的ResizeObserver规格polyfill:
const divEl = $('#section60');
const ro = new ResizeObserver(() => {
if (divEl.is(':visible')) {
console.log("it's visible now!");
}
});
ro.observe(divEl[0]);
请注意,它是跨浏览器和高性能(无轮询)。
动画完成后,此支持缓动和触发事件![在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(function() {
jQuery("#contentDiv:hidden").show().trigger('show');
jQuery('#contentDiv').on('show', function() {
console.log('#contentDiv is now visible');
// your code here
});
});
有一个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
});
希望这将以最简单的方式完成工作:
$("#myID").on('show').trigger('displayShow');
$('#myID').off('displayShow').on('displayShow', function(e) {
console.log('This event will be triggered when myID will be visible');
});
我根据Glenns的想法更改了Catalint的hide / show事件触发器。我的问题是我有一个模块化应用程序。我在显示和隐藏div父母的模块之间切换。然后,当我隐藏一个模块并显示另一个模块时,使用他的方法,当我在模块之间进行切换时,会有明显的延迟。有时候,在某些特殊的孩子中,我只需要轻抚一下这个活动。因此,我决定只通知具有“ 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;
}
});
然后,当孩子想要收听“显示”或“隐藏”事件时,我必须向他添加“ 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");
});
});