29

ページに、onclick および ondblclick イベント ハンドラーをアタッチする必要がある要素があります。シングル クリックが発生した場合、ダブルクリックとは異なる動作を行う必要があります。私が最初にこれを機能させようとしたとき、頭が回転し始めました。明らかに、ダブルクリックすると onclick が常に起動します。そこで、このようなタイムアウトベースの構造を使用してみました...

window.onload = function() {
  var timer;
  var el = document.getElementById('testButton');

  el.onclick = function() {
    timer = setTimeout(function() { alert('Single'); }, 150);        
  }

  el.ondblclick = function() {
    clearTimeout(timer);
    alert('Double');
  }
}

しかし、一貫性のない結果が得られました (IE8 を使用)。多くの場合、適切に機能しますが、「Single」アラートが 2 回表示されることがあります。

誰もこれをやったことがありますか?より効果的な方法はありますか?

4

6 に答える 6

33

Matt のように、タイムアウト値を少し増やしたところ、はるかに優れたエクスペリエンスが得られました。また、シングル クリックが 2 回発生する問題を軽減するために (いずれにしても、より高いタイマーでは再現できませんでした)、シングル クリック ハンドラーに次の行を追加しました。

el.onclick = function() {
    if (timer) clearTimeout(timer);
    timer = setTimeout(function() { alert('Single'); }, 250);        
}

このようにして、クリックがすでに発生するように設定されている場合、「単一」アラートの重複を避けるためにそれ自体がクリアされます。

于 2009-10-09T21:40:27.133 に答える
12

2 つのアラートを受け取っている場合は、ダブルクリックを検出するためのしきい値が小さすぎるようです。150 から 300ms に増やしてみてください。

また、クリックと dblclick が起動される順序が保証されているかどうかはわかりません。したがって、dblclick が発生すると、最初のクリック イベントがクリアされますが、2 番目の「クリック」イベントの前に発生した場合、この 2 番目のイベントは引き続き単独で発生し、両方のダブル クリック イベントが発生します。発射とシングルクリックイベントの発射。

この潜在的な問題に対する 2 つの解決策が考えられます。

1) ダブルクリック イベントを実際に発生させるための別のタイムアウトを設定します。ダブルクリック イベントが発生しようとしていることをコードでマークします。次に、2 番目の「シングル クリック」イベントが発生すると、この状態をチェックして、「おっと、dbl クリックが保留中なので、何もしません」と言うことができます。

2) 2 番目のオプションは、クリック イベントに基づいてターゲット関数を交換することです。次のようになります。

window.onload = function() {
  var timer;
  var el = document.getElementById('testButton');

  var firing = false;
  var singleClick = function(){
    alert('Single');
  };

  var doubleClick = function(){ 
    alert('Double');
  };

  var firingFunc = singleClick;

  el.onclick = function() {
    // Detect the 2nd single click event, so we can stop it
    if(firing) 
      return;

    firing = true;
    timer = setTimeout(function() { 
       firingFunc(); 

       // Always revert back to singleClick firing function
       firingFunc = singleClick;
       firing = false;
    }, 150);

  }

  el.ondblclick = function() {
    firingFunc = doubleClick; 
    // Now, when the original timeout of your single click finishes, 
    // firingFunc will be pointing to your doubleClick handler        
  }
}

基本的にここで起こっていることは、設定した元のタイムアウトを継続させることです。それは常に fireingFunc(); を呼び出します。唯一の変更点は、firefunc() が実際に指しているものです。ダブルクリックが検出されると、doubleClick に設定されます。そして、タイムアウトが切れると、常に singleClick に戻ります。

そこには「発火」変数もあるので、2 番目のシングル クリック イベントをインターセプトすることがわかっています。

もう 1 つの方法は、dblclick イベントを完全に無視し、シングル クリックとタイマーで検出することです。

window.onload = function() {
  var timer;
  var el = document.getElementById('testButton');

  var firing = false;
  var singleClick = function(){
    alert('Single');
  };

  var doubleClick = function(){ 
    alert('Double');
  };

  var firingFunc = singleClick;

  el.onclick = function() {
    // Detect the 2nd single click event, so we can set it to doubleClick
    if(firing){
      firingFunc = doubleClick; 
      return;
    }

    firing = true;
    timer = setTimeout(function() { 
       firingFunc(); 

       // Always revert back to singleClick firing function
       firingFunc = singleClick;
       firing = false;
    }, 150);

  }
}

これはテストされていません:)

于 2009-10-09T21:28:01.153 に答える
0
,   cellclick   :   
        function(){
            setTimeout(function(){
                if (this.dblclickchk) return;
                setTimeout(function(){
                    click event......                   
                },100);
            },500);
        }

,   celldblclick    :   
        function(){
            setTimeout(function(){
                this.dblclickchk    =   true;
                setTimeout(function(){
                                          dblclick event.....
                },100);
                setTimeout(function(){
                    this.dblclickchk = false;
                },3000);
            },1);
        }
于 2016-10-19T15:04:50.797 に答える