2012-10-18 47 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'被觸發(「觸發」)時重新運行。