自定义jQuery事件只触发一次

时间:2012-10-18 15:51:56

标签: jquery

我正在使用此代码创建一个onshow事件:

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

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

任何想法为什么?

1 个答案:

答案 0 :(得分:1)

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

因此,如果有问题的元素开始隐藏,它将在{click keyup和keydown'上以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'被触发(“触发”)时重新运行。