2

このコードを使用して 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 回しか表示されないことです。もう一度クリックしても表示されません。

理由はありますか?

4

1 に答える 1

1

これは、イベントが JavaScript でどのように機能するかについての誤解だと思います。カスタム拡張機能が行っていることは、1 回実行されていることです。行$('body').bind('click keyup keydown', checkVis);はクリックのキーアップおよびキーダウン イベントをリッスンしますが、このリスナーは非表示で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' が発生する (「トリガーされる」) たびに再実行されます。

于 2012-10-18T16:53:20.053 に答える