2012-10-18 46 views
2

我使用此代码创建一个OnShow中事件:自定义jQuery的事件仅触发一次

(function($){ 
    $.fn.extend({ 
    onShow: function(callback, unbind){ 
     return this.each(function(){ 
     var obj = this; 
     var bindopt = (unbind==undefined)?true:unbind; 
     if($.isFunction(callback)){ 
      if($(this).is(':hidden')){ 
      var checkVis = function(){ 
       if($(obj).is(':visible')){ 
       callback.call(); 
       if(bindopt){ 
        $('body').unbind('click keyup keydown', checkVis); 
       } 
       }       
      } 
      $('body').bind('click keyup keydown', checkVis); 
      } 
      else{ 
      callback.call(); 
      } 
     } 
     }); 
    } 
    }); 
})(jQuery); 

然后我打电话吧:

$(document).ready(function(){ 

    $('.mydiv').onShow(function(){ 
     alert('myDiv is now showing'); 

    }); 

}); 

我也拨动链接,触发div来显示和隐藏:

$('.myLink').click(function(){ 
     $(".mydiv").slideToggle(); 
}); 

终于下面是HTML:

<a href="#" class="myLink">Step 1</a> 
     <div class="myDiv">content here</div> 

问题是,当我在加载页面后单击链接时,警报仅显示一次。如果我再次点击它,我不会显示。

任何想法为什么?

+0

HTML与此一起去哪里? – Sparky

+0

什么给:$('。mydiv')。onShow(function(null,false){alert('myDiv is now showing'); }); –

+0

我已经添加了上面的html,谢谢 – Satch3000

回答

1

我认为这是对JavaScript中事件如何工作的误解。您的自定义扩展程序正在执行一次。 $('body').bind('click keyup keydown', checkVis);行监听点击密钥和keydown事件,但是此侦听器仅适用于隐藏且已通过if($(this).is(':hidden')){检查的元素。

因此,如果有问题的元素开始隐藏,它将以'点击键盘和按键'回复checkVis,但这是在onShow扩展完成后第一次运行的唯一实例。

.slideToggle();默认情况下不触发任何事件,因此您的扩展程序无法侦听此类事件触发。

最接近你可以听一个元素改变其可见性将是使用像dom突变事件,但已被弃用,并没有跨浏览器支持。

如果你确实需要运行扩展的能力,每当一个元素被jQuery“显示”时,我能想到的最好方法就是扩展你想用来激发自定义事件的jQuery函数,是这样的:

var existingSlideToggle = $.fn.slideToggle; 

    $.fn.slideToggle = function(){ 
     var returner = existingSlideToggle(this, arguments); 
     $(this).trigger('customOnShowEvent'); 
     return returner; 
    } 

然后,你可以这样做:

$('#foo').on('customOnShowEvent', function(){ 
     // do stuff 
    }); 

还是继续你的扩展战略:

(function($){ 
    $.fn.extend({ 
    onShow: function(callback, unbind){ 
     return this.each(function(){ 
     var obj = this; 
     var bindopt = (unbind==undefined)?true:unbind; 

     var localRun = function(){ 
      if($(obj).is(':hidden')){ 
      var checkVis = function(){ 
       if($(obj).is(':visible')){ 
       callback.call(); 
       if(bindopt){ 
        $('body').unbind('click keyup keydown', checkVis); 
       } 
       }       
      } 
      $('body').bind('click keyup keydown', checkVis); 
      } 
      else{ 
      callback.call(); 
      } 
     } 

     if($.isFunction(callback)){ 
      localRun(); 
      $(obj).on('customOnShowEvent', localRun); 
     } 

     }); 
    } 
    }); 
})(jQuery); 

这样它将首次运行,然后在新的'customOnShowEvent'被触发(“触发”)时重新运行。