2009-05-19 19 views
21

DOMエレメントのclickイベントとdblclickイベントの両方を処理しています。それぞれが別のコマンドを実行しますが、要素をダブルクリックすると、ダブルクリックイベントが発生するだけでなく、クリックイベントも2回発生します。この動作を防ぐための最良の方法は何ですか?dblclickイベントが発生したときにクリックイベントが発生しないようにする

答えて

11

、あなたが言った、

私は300ミリ秒(目立つと迷惑な遅延)でクリックハンドラを遅らせ、でも...

だから、それはあなたが望むように聞こえますあなたがクリックすると、クリックがダブルクリックの最初のクリックであるかどうかを除いて、DOMはクリックイベントをすぐに生成しなければなりません。

この機能を実装するには、クリックするとDOMが最終クリックかどうか、またはダブルクリックの最初のものかどうかを予測できる必要があります(ただし、一般的にユーザーがもう一度クリックしようとしているかどうかを予測するDOM)。


クリックしてダブルクリックすると、2つの異なるアクションが実行されますか? IMO、通常のアプリケーションでは、両方のイベントが必要な場合があります。要素をクリックしてダブルクリックしてアクティブにします。

イベントを区切る必要がある場合、アプリケーションによっては、ダブルクリック以外のものが使用されます。たとえば、右クリックまたはControlキーを押しながらクリックします。

+0

更新された回答ありがとうございます。私はこれが本当に私のUIを再考する必要があるという事実になると思う。私が実際に成し遂げたいのは可能ではないでしょう。 2つのアクションに2つのコントロールを使用するか、ダブルクリックの代わりに修飾キーを使用するだけです。ありがとう! – David

5

この場合、シングルクリックイベントの実行をわずかに遅らせることをお勧めします。ダブルクリックハンドラに、シングルクリックイベントがチェックする変数を設定させます。その変数の値がboolDoubleClick == trueの場合は、fire/handleをクリックしないでください。コメントで

+0

実際、これは私が今やっていることですが、かなりクールな解決策のようです。私はクリックハンドラーを300ミリ秒(顕著で迷惑な遅延)だけ遅らせ、さらにそれを使用しても、両方を起動させるのに十分遅い(例えば350ミリ秒)ダブルクリックすることができます。興味深いもの: – David

+0

2回目のクリックに時間がかかり過ぎると、希望の効果が2回のクリックとなると仮定することは理にかなっていません。 –

+0

残念ながら、ダブルクリック時間はエンドユーザーが設定することができます(たとえば、コントロールパネル/マウスを使用)。ブラウザのJavaScriptは、その遅延がどのように設定されているかを判断できません。 – ChrisW

3

AFAIK DOMレベル2イベントでは、ダブルクリックの指定がありません。 IE7上では動作しませんが(ショックがあります)、FFとOperaには、すべてのアクションをクリックイベントにアタッチすることはできますが、ダブルクリックするだけで "詳細"属性は2です。ドキュメントから: "同じスクリーン位置で複数のクリックが発生した場合、シーケンスは各繰り返しで増分するdetail属性で繰り返されます。"

+0

これは、実際問題の非常にエレガントな解決策です。最初のクリックに対してはまだsetTimout/clearTimeoutのコンボが必要ですが、2つの間の調整を簡素化し、トリプルクリックなどのためのドアを開くことさえあります。ありがとうございます! – mckamey

2

ここにすべての他の回答に感謝の相互作用が、両方を必要としますが、相互に排他的なときにそれらの組み合わせが私のための合理的な解決策を提供しているようだとして:

var pendingClick = 0; 

function xorClick(e) { 
    // kill any pending single clicks 
    if (pendingClick) { 
     clearTimeout(pendingClick); 
     pendingClick = 0; 
    } 

    switch (e.detail) { 
     case 1: 
      pendingClick = setTimeout(function() { 
       console.log('single click action here'); 
      }, 500);// should match OS multi-click speed 
      break; 
     case 2: 
      console.log('double click action here'); 
      break; 
     default: 
      console.log('higher multi-click actions can be added as needed'); 
      break; 
    } 
} 

myElem.addEventListener('click', xorClick, false); 

アップデート:私は一般的なバージョンを追加しました例でこのGithubのレポへのタッチデバイスのクリックポリフィルと一緒にこのアプローチの:ここで

https://github.com/mckamey/doubleTap.js

2

は、私がdistingに何をしたかでありますモジュール内uish答えを探して(私が行ったように)この上ケースの他の誰つまずくで

 node.on('click', function(e) { 

      //Prepare for double click, continue to clickHandler doesn't come soon enough 
      console.log("cleared timeout in click",_this.clickTimeout); 
      clearTimeout(_this.clickTimeout); 
      _this.clickTimeout = setTimeout(function(){ 
       console.log("handling click"); 
       _this.onClick(e); 
      },200); 
      console.log(_this.clickTimeout); 
     }); 

     node.on('dblclick', function (e) { 

      console.log("cleared timeout in dblclick",_this.clickTimeout); 
      clearTimeout(_this.clickTimeout); 
      // Rest of the handler function 
11

、私が思い付くことができ、絶対最善の解決策は次のとおりです。

$node.on('click',function(e){ 
     if(e.originalEvent.detail > 1){ 
     return; 
     /* if you are returning a value from this 
     function then return false or cancel 
     the event some other way */ 
     } 
    }); 

完了しました。背中合わせに複数のクリックがある場合、2番目、3番目など。発火しません。私は間違いなくタイマーを使用することを好む。

私はこの方向に、thisと読むことで指摘しました。


ちなみに:私は誤って二重のページ分割のリンクをクリックすると、イベントが発生し、コールバックが起こることができる前に二度終えたので、私は最初にこの問題を研究していました。

上記のコードを考え出す前に、私はしかし、「私がリンクを3倍(トリプルクリック)をクリックすることができた、と第二のクリックがdidnのけれども

if e.originalEvent.detail === 2 //return 

を持っていたが火災、3番目はした

+0

これは、2回目のクリックが発射されないようにし、1回目のクリックを発射させます。私が正しく理解していれば、2回目のクリックがあった場合、OPは1回目のクリックを無効にしたかったのです。私は最善の策は、(私は200msを使用していますが、私はちょうど見ることができなかったより良い解決策が望んでいた)小さな遅延を使用していると思います。 – ClarkeyBoy

+0

@ClarkeyBoy - 間違っています。秒がある場合、これは最初のクリックを無効にします。それを試してみてください。 – user1167442

+5

IE 11 x64(Win8.1)では動作しません:event.detail = 0常に1回のクリックまたはダブル – robert4

0

私はこれが知っているように古いですが、私はちょうど同じ問題に遭遇したので、私はとにかく投稿すると思った。ここで私はそれを解決した方法です。

$('#alerts-display, #object-display').on('click', ['.item-data-summary', '.item-marker'], function(e) { 
    e.preventDefault(); 

    var id; 

    id = setTimeout(() => { 
     // code to run here 
     return false; 
    }, 150); 

    timeoutIDForDoubleClick.push(id); 
}); 


$('.panel-items-set-marker-view').on('dblclick', ['.summary', '.marker'], function(e) { 
    for (let i = 0; i < timeoutIDForDoubleClick.length; i++) { 
     clearTimeout(timeoutIDForDoubleClick[i]); 
    } 

    // code to run on double click 

    e.preventDefault(); 
}); 
関連する問題