43

興味深い状況があります。現在、「展開」ボタンをクリックすると、対応する非表示のテーブル行が表示されます。展開ボタンを含む元の (非表示にされていない) 行の特定のセルには、クリックすると編集可能になるコンテンツもあります。展開ボタンを取り除き、クリックすると編集可能になるフィールドを含め、行自体のどこでもダブルクリックして行を展開できるようにしたいと思います。ここですでに問題の匂いがします。

行をダブルクリックすると、dblclick が発生する前に、最初に 2 つのクリック イベントが発生します。これは、フィールドをダブルクリックすると、編集可能なフィールドに変わり、行が展開されることを意味します。これを防ぎたいと思います。ダブルクリックでシングルクリックの発火を防ぎ、シングルクリックを通常どおり実行したい。

event.stopPropagation() の使用は、2 つの異なるイベントであるため、明らかに機能しません。

何か案は?

編集(いくつかの半疑似コード):

元のバージョン:

<table>
    <tbody>
        <tr>
            <td><a href="javascript:$('#row_to_expand').toggle();" title="Expand the hidden row">Expand Row</a></td>
            <td>Some kind of random data</td>
            <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[0]->value("First editable value") ?></td>
            <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[1]->value("Second editable value") ?></td>
            <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[2]->value("Third editable value") ?></td>
            <!-- ... -->
            <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[n]->value("Nth editable value") ?></td>
        </tr>
        <tr style="display: none" id="row_to_expand">
            <td colspan="n">Some hidden data</td>
        </tr>
    </tbody>
</table>

希望のバージョン:

<table>
    <tbody>
        <tr ondblclick="$('#row_to_expand').toggle()">
            <td>Some kind of random data</td>
            <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[0]->value("First editable value") ?></td>
            <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[1]->value("Second editable value") ?></td>
            <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[2]->value("Third editable value") ?></td>
            <!-- ... -->
            <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[n]->value("Nth editable value") ?></td>
        </tr>
        <tr style="display: none" id="row_to_expand">
            <td colspan="n">Some hidden data</td>
        </tr>
    </tbody>
</table>

乾杯

4

9 に答える 9

24

一般的な考え方:

  1. 最初のクリックでは、関連付けられた関数 (single_click_function() など) を呼び出さないでください。むしろ、タイマーを一定時間(たとえばx)設定します。その期間中に別のクリックが得られない場合は、single_click_function() に進みます。取得した場合は、 double_click_function() を呼び出します

  2. 2 回目のクリックを受信すると、タイマーはクリアされます。また、x ミリ秒経過するとクリアされます。

ところで、パオロの返信をチェックしてください:ダブルクリックイベントが検出されたときにクリック/マウスアップイベントをキャンセルする必要が あり、もちろんスレッド全体! :-)

より良い答え: https://stackoverflow.com/a/7845282/260610

于 2011-03-29T11:11:34.213 に答える
12

作業デモ

$('#alreadyclicked').val('no click');
$('td.dblclickable').on('click',function(){
    var $button=$(this);
    if ($button.data('alreadyclicked')){
        $button.data('alreadyclicked', false); // reset
        $('#alreadyclicked').val('no click');

        if ($button.data('alreadyclickedTimeout')){
            clearTimeout($button.data('alreadyclickedTimeout')); // prevent this from happening
        }
        // do what needs to happen on double click. 
        $('#action').val('Was double clicked');
    }else{
        $button.data('alreadyclicked', true);
        $('#alreadyclicked').val('clicked');
        var alreadyclickedTimeout=setTimeout(function(){
            $button.data('alreadyclicked', false); // reset when it happens
            $('#alreadyclicked').val('no click');
            $('#action').val('Was single clicked');
            // do what needs to happen on single click. 
            // use $button instead of $(this) because $(this) is 
            // no longer the element
        },300); // <-- dblclick tolerance here
        $button.data('alreadyclickedTimeout', alreadyclickedTimeout); // store this id to clear if necessary
    }
    return false;
});

明らかに使用 <td class="dblclickable">

于 2012-05-16T18:18:22.207 に答える
3

再利用のためにuser822711の答えを書き直してください:

  $.singleDoubleClick = function(singleClk, doubleClk) {
    return (function() {
      var alreadyclicked = false;
      var alreadyclickedTimeout;

      return function(e) {
        if (alreadyclicked) {
          // double
          alreadyclicked = false;
          alreadyclickedTimeout && clearTimeout(alreadyclickedTimeout);
          doubleClk && doubleClk(e);
        } else {
          // single
          alreadyclicked = true;
          alreadyclickedTimeout = setTimeout(function() {
            alreadyclicked = false;
            singleClk && singleClk(e);
          }, 300);
        }
      }
    })();
  }

関数を呼び出します。

$('td.dblclickable').bind('click', $.singleDoubleClick(function(e){
  //single click.
}, function(e){
  //double click.
}));
于 2012-07-19T04:52:05.970 に答える
2

この問題は、編集可能なフィールドがクリックされたときにのみ発生するため、通常のclickハンドラをその要素にアタッチして、イベントの伝播をキャンセルし (を参照stopPropagation)、タイムアウト ( setTimeout(...)) を 600 ミリ秒に設定します ( 2 回のクリック間のデフォルトの時間と見なされます)。 dbl-click は 500ms です[src] )。その時までにdblclick発生していない場合 (これを検出するためのフラグとして機能する両方のイベント ハンドラーで var にアクセスできるようにすることができます)、ユーザーが代わりに行を展開することを望んでいると想定して、そのアクションを続行することができます...

IMO、これを再考する必要があります。残念ながら、シングル クリック ハンドラーは、ユーザーがダブルクリックしようとしているかどうかを認識できません。

両方のアクションを 1 回のクリックで行うことをお勧めします。クリックしたときに編集可能なフィールドから伝播しないようにしてください。

于 2011-03-29T11:11:44.913 に答える
-2

backbonejs を使用している場合、この問題を処理するより洗練された方法があります。

    初期化: 関数(){
        this.addListener_openWidget();
    }

    addListener_openWidget: 関数(){
        this.listenToOnce( this, 'openWidgetView', function(e){this.openWidget(e)} );
    }、

    イベント: {
        '#o​​penWidgetLink をクリック' : function(e){this.trigger('openWidgetView',e)},
        '#closeWidgetLink をクリック': 'closeWidget'
    }、

    openWidget: 関数(e){
       //自分のことをする
    }、

    closeWidget: 関数(){
       this.addListener_openWidget();
    }

于 2014-12-31T08:57:27.433 に答える