web-dev-qa-db-ja.com

jQueryを使用してダブルクリックを防ぐ方法は?

私はそのようなボタンを持っています:

<input type="submit" id="submit" value="Save" />

JQuery内では次を使用していますが、それでもダブルクリックは可能です。

<script type="text/javascript">

$(document).ready(function () {

    $("#submit").one('click', function (event) {  

ダブルクリックを防ぐ方法はありますか?

54
Nate Pet

jQueryの one() は、バインドされた要素ごとに添付イベントハンドラーを1回起動し、イベントハンドラーを削除します。

何らかの理由で要件を満たさない場合は、ボタンをクリックした後にボタンを完全に無効にすることもできます。

$(document).ready(function () {
     $("#submit").one('click', function (event) {  
           event.preventDefault();
           //do something
           $(this).prop('disabled', true);
     });
});

ID submitを使用すると、その要素への参照でform.submit関数が上書きされるため、問題が発生する可能性があることに注意してください。

70
adeneo

もう1つのソリューション:

$('a').on('click', function(e){
    var $link = $(e.target);
    e.preventDefault();
    if(!$link.data('lockedAt') || +new Date() - $link.data('lockedAt') > 300) {
        doSomething();
    }
    $link.data('lockedAt', +new Date());
});

ここでは、ラストクリックの時間をデータ属性として保存し、前回のクリックが0.3秒以上前かどうかを確認します。 falseの場合(0.3秒未満)、最後のクリック時間を更新し、trueの場合、何かを実行します。

jsbin

26
Kichrum

ほとんどのソリューションは、ラベルやDIVなどの要素のクリックでは機能しないことがわかりました(たとえば、Kendoコントロールを使用している場合)。そこで、この簡単な解決策を作成しました。

function isDoubleClicked(element) {
    //if already clicked return TRUE to indicate this click is not allowed
    if (element.data("isclicked")) return true;

    //mark as clicked for 1 second
    element.data("isclicked", true);
    setTimeout(function () {
        element.removeData("isclicked");
    }, 1000);

    //return FALSE to indicate this click was allowed
    return false;
}

イベントを開始するかどうかを決定する必要がある場所で使用します。

$('#button').on("click", function () {
    if (isDoubleClicked($(this))) return;

    ..continue...
});
16
roberth

私の解決策: https://Gist.github.com/pangui/86b5e0610b53ddf28f94 ダブルクリックを防ぎますが、1秒後にはより多くのクリックを受け入れます。それが役に立てば幸い。

コードは次のとおりです。

jQuery.fn.preventDoubleClick = function() {
  $(this).on('click', function(e){
    var $el = $(this);
    if($el.data('clicked')){
      // Previously clicked, stop actions
      e.preventDefault();
      e.stopPropagation();
    }else{
      // Mark to ignore next click
      $el.data('clicked', true);
      // Unmark after 1 second
      window.setTimeout(function(){
        $el.removeData('clicked');
      }, 1000)
    }
  });
  return this;
}; 
12
Pangui

私の場合、jQuery 1にはいくつかの副作用があり(IE8で)、次のようになりました:

$(document).ready(function(){
  $("*").dblclick(function(e){
    e.preventDefault();
  });
});

これは非常にうまく機能し、よりシンプルに見えます。そこで見つけた: http://www.jquerybyexample.net/2013/01/disable-mouse-double-click-using-javascript-or-jquery.html

11
Etienne

このメソッドをフォームに配置するだけで、ダブルクリックまたはそれ以上のクリックを一度に処理できます。一度リクエストを送信すると、何度もリクエストを送信することはできません。

<script type="text/javascript">
    $(document).ready(function(){
            $("form").submit(function() {
                $(this).submit(function() {
                    return false;
                });
                return true;
            }); 
    }); 
</script>

確かに役立ちます。

4
Bachas

"Easy Peasy"

$(function() {
     $('.targetClass').dblclick(false);
});
3
Kabindas

私が見つけたのは、古いが最新のブラウザで機能するソリューションでした。ダブルクリックでクラスを切り替えないように機能します。

$('*').click(function(event) {
    if(!event.detail || event.detail==1){//activate on first click only to avoid hiding again on double clicks
        // Toggle classes and do functions here
        $(this).slideToggle();
    }
});
2

同様の問題があります。 setTimeout()を使用して、ダブルクリックを回避できます。

//some codes here above after the click then disable it

//属性が無効になっているかどうかもここで確認します

// btnタグで無効になっている属性がある場合、//戻ります。それをjsに変換します。

$('#btn1').prop("disabled", true);

setTimeout(function(){
    $('#btn1').prop("disabled", false);
}, 300);
2
user3856437
/*
Double click behaves as one single click


"It is inadvisable to bind handlers to both the click and dblclick events for the same element. The sequence of events triggered varies from browser to browser, with some receiving two click events before the dblclick and others only one. Double-click sensitivity (maximum time between clicks that is detected as a double click) can vary by operating system and browser, and is often user-configurable."

That way we have to check what is the event that is being executed at any sequence. 

   */
       var totalClicks = 1;

 $('#elementId').on('click dblclick', function (e) {

 if (e.type == "dblclick") {
    console.log("e.type1: " + e.type);
    return;
 } else if (e.type == "click") {

    if (totalClicks > 1) {
        console.log("e.type2: " + e.type);
        totalClicks = 1;
        return;
    } else {
        console.log("e.type3: " + e.type);
        ++totalClicks;
    }

    //execute the code you want to execute
}

});

これは私の最初の投稿であり、私は非常に経験が浅いので簡単に行ってください。

繰り返しのクリックの間に非常に大きな時間枠が必要な場合があります(たとえば、メールアプリが開くのに数秒かかり、再トリガーされたくない場合のmailtoリンク)他の場所のユーザー。私の解決策は、他の場所でダブルクリック機能を保持しながら、イベントタイプに応じてリンクにクラス名を使用することです...

var controlspeed = 0;

$(document).on('click','a',function (event) {
    eventtype = this.className;
    controlspeed ++;
    if (eventtype == "eg-class01") {
        speedlimit = 3000;
    } else if (eventtype == "eg-class02") { 
        speedlimit = 500; 
    } else { 
        speedlimit = 0; 
    } 
    setTimeout(function() {
        controlspeed = 0;
    },speedlimit);
    if (controlspeed > 1) {
        event.preventDefault();
        return;
    } else {

        (usual onclick code goes here)

    }
});
1
ma5k

本当に必要なのが、ダブルクリックを防ぐだけでなく、複数のフォーム送信を避けることである場合、クライアント側の検証(必要に応じてマークされたテキストフィールドなど)がある場合、ボタンのクリックイベントでjQuery one()を使用すると問題が発生する可能性があります。これは、クリックがクライアント側の検証をトリガーし、検証が失敗した場合、ボタンを再び使用できないためです。これを回避するために、フォームの送信イベントでone()を直接使用できます。これは、私が見つけた最もクリーンなjQueryベースのソリューションです。

<script type="text/javascript">
$("#my-signup-form").one("submit", function() {
    // Just disable the button.
    // There will be only one form submission.
    $("#my-signup-btn").prop("disabled", true);
});
</script>
0
regiov

私も同様の問題を抱えていましたが、ボタンを無効にしても完全にはうまくいきませんでした。ボタンがクリックされたときに行われた他のアクションがいくつかあり、ボタンがすぐに無効にならない場合や、ユーザーがダブルクリックしたときに2つのイベントが発生しました。
Panguiのタイムアウトのアイデアを取り入れ、念のためボタンを無効にしてタイムアウトを含める両方の手法を組み合わせました。そして、簡単なjQueryプラグインを作成しました。

var SINGLECLICK_CLICKED = 'singleClickClicked';
$.fn.singleClick = function () {
    var fncHandler; 
    var eventData;
    var fncSingleClick = function (ev) {
        var $this = $(this);
        if (($this.data(SINGLECLICK_CLICKED)) || ($this.prop('disabled'))) {
            ev.preventDefault();
            ev.stopPropagation();
        }
        else {
            $this.data(SINGLECLICK_CLICKED, true);
            window.setTimeout(function () {
                $this.removeData(SINGLECLICK_CLICKED);
            }, 1500);
            if ($.isFunction(fncHandler)) {
                fncHandler.apply(this, arguments);
            }
        }
    }

    switch (arguments.length) {
        case 0:
            return this.click();
        case 1:
            fncHandler = arguments[0];
            this.click(fncSingleClick);
            break;
        case 2: 
            eventData = arguments[0];
            fncHandler = arguments[1];
            this.click(eventData, fncSingleClick);
            break;
    }
    return this;
}

そして、次のように使用します:

$("#button1").singleClick(function () {
   $(this).prop('disabled', true);
   //...
   $(this).prop('disabled', false);
})
0
Andrea

@Kichrumが提供するソリューションは、私にとってはほとんど機能しました。デフォルトのアクションを防ぐために、e.stopImmediatePropagation()も追加する必要がありました。ここに私のコードがあります:

$('a, button').on('click', function (e) {
    var $link = $(e.target);
    if (!$link.data('lockedAt')) {
        $link.data('lockedAt', +new Date());
    } else if (+new Date() - $link.data('lockedAt') > 500) {
        $link.data('lockedAt', +new Date());
    } else {
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
    }
});
0