0

そこで、オブジェクトにバインドされたすべてのイベント ハンドラーを表示する、 Visual Event という非常に優れたツールを使用しました。オブジェクトをクリックしたり、いじったりして、オブジェクトにバインドされたイベント ハンドラーのリストを確認するたびに、毎回もっと。私の問題はこれです: javascript のバグの原因を突き止めるための console.trace またはスタック トレース? Visual Event と他の誰かの提案を使用した後、私の問題は、おそらく同じハンドラーを同じイベントに何度もバインドしていることだと思います。定期的にバインドを解除する方法はありますか?

私のアプリケーションには、動的に作成された に接続するプラグインがたくさんありますdiv。これらdivsは、サイズを変更したり、場所を移動したりできます。このアプリケーションは一種のエディターなので、ユーザーはこれらの div (画像またはテキストのいずれかを含む) を好きなデザインで配置します。ユーザーが div をクリックすると、その div は「アクティブ化」され、ページ上の他のすべての div は「非アクティブ化」されます。、、、、などactivateTextBoxの関連プラグインがたくさんあります。div が最初に作成されるときはいつでも、次のように、プラグインは作成後の最初の 1 回だけ呼び出されます。initTextBoxdeactivateTextBoxreadyTextBoxinit

$(mydiv).initTextBox();

ただしreadyTextBox、 andactivateTextBoxdeactivateTextBoxは、他のユーザー イベントに応じて頻繁に呼び出されます。

では、最初にや などのinitbind を使用し、次にボックスを使用できる状態にします。resizable()draggable()

    $.fn.extend({
        initTextBox: function(){
        return this.each(function() {
               // lots of code that's irrelevant to this question
               $this.mouseenter(function(){ 
        if(!$this.hasClass('activated'))
            $this.readyTextBox();
         }
         $this.mouseleave(function(){ 
        if($this.hasClass('ready')){
            $this.deactivateTextBox(); 
                    $this.click(function(e){
                 e.preventDefault();
                 });
                }
             });
     }); 
  });

readyTextBoxプラグインの簡略化された要約バージョンは次のとおりです。

(function($){
    $.fn.extend({
        readyTextBox: function(){
        return this.each(function() {
               // lots of code that's irrelevant to this question
               $this.resizable({ handles: 'all', alsoResize: img_id});
               $this.draggable('enable');
               $this.on( "dragstop", function( event, ui )
               {/* some function */ });
               $this.on("resizestop", function( event, ui ){ /* another function */ });
               // and so on
});

次に、次のactivateTextBox()とおりです。

    $.fn.extend({
        activateTextBox: function(){
        return this.each(function() {
               // lots of code that's irrelevant to this question
               $this.resizable('option','disabled',true); //switch of resize & drag
               $this.draggable('option', 'disabled', true);
});

次にdeactivate、コードを使用して、ドラッグ可能およびサイズ変更可能を再度オンにします。

$this.draggable('enable'); $this.resizable('option','disabled',false);

これらの div、または「テキスト ボックス」はcontent、 と呼ばれるより大きな div 内に含まれています。これは、私が持っているクリック コードですcontent

$content.click(function(e){
    //some irrelevant code
     if( /* condition to decide if a textbox is clicked */) 
     {  $(".textbox").each(function(){ //deactivate all except this
        if($(this).attr('id') != $eparent.attr('id')) 
            $(this).deactivateTextBox();
        });
        // now activate this particular textbox
        $eparent.activateTextBox();
             }
          });

これは、テキスト ボックスに関連するほとんどのコードです。何かをドラッグしてビジュアル イベントを確認すると、以前よりもクリック数、ドラッグストップ数、マウスオーバー数が増えるのはなぜですか? また、ユーザーがページを操作するほど、イベントが完了するまでの時間が長くなります。たとえば、div からマウスアウトすると、カーソルmoveがデフォルトに戻るのに非常に時間がかかります。ドラッグをやめましたが、ユーザーのクリックを増やす準備が整う前に、すべてがしばらく動かなくなります。そのため、問題は、同じイベントにあまりにも多くのものをバインドしていることにあると推測しています。いくつかでバインドを解除する必要があります点?ドラッガブルは最終的にある時点で機能しなくなるほどひどくなります。テキストボックスが動かなくなります - サイズを変更することはできますが、ドラッグは機能しなくなります。

4

1 に答える 1

1

イベントを何度もバインドしていますか

はい。あなたのコードを見てください:

$this.mouseenter(function(){ 
    …
    $this.mouseleave(function(){ 
        …
        $this.click(function(e){
            …
        });
    });
});

つまり、要素にマウスオーバーするたびに、別の leave ハンドラーが追加されます。要素を離れると、これらのハンドラーのすべてが別のクリック イベントを追加します。

何をしたいのかわかりませんが、いくつかのオプションがあります。

  • イベント ハンドラーを 1 回だけバインドし、ブール変数などを使用して現在の状態を追跡します。
  • バインドする前に、既にバインドされている他のすべてのイベント ハンドラーを削除します。jQuery のイベント名前空間は、独自のプラグインが追加したものだけを削除するのに役立ちます。
  • 起動後にリスナーを自動的にバインド解除するone()メソッドを使用します。
于 2013-02-19T13:26:17.053 に答える