JQuery клики события несколько раз

Я пытаюсь написать видео-покерную игру в Javascript как способ получить ее основы, и я столкнулся с проблемой, когда обработчики событий jQuery запускаются несколько раз.

Они прикреплены к кнопкам для размещения ставки, и он отлично подходит для размещения ставки с первых рук во время игры (стрельба только один раз); но в ставках для второй руки он дважды запускает событие клика каждый раз, когда нажимается кнопка ставки или ставки места (так что в два раза правильная сумма делается для каждого нажатия). В целом, он следует этой схеме за количество раз, когда событие клика запускается при нажатии кнопки ставки один раз - где i-й член последовательности предназначен для ставок i-й руки с начала игры: 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, который, как представляется, равен n (n + 1)/2 + 1 для того, что стоит - и я был недостаточно умен, чтобы понять это, я использовал OEIS.:)

Здесь функция с обработчиками событий щелчка, которые действуют; надеюсь, это легко понять (дайте мне знать, если нет, я тоже хочу поправиться):

/** The following function keeps track of bet buttons that are pressed, until place button is pressed to place bet. **/
function pushingBetButtons() {
    $("#money").text("Money left: $" + player.money); // displays money player has left

    $(".bet").click(function() {
        var amount = 0; // holds the amount of money the player bet on this click
        if($(this).attr("id") == "bet1") { // the player just bet $1
            amount = 1;
        } else if($(this).attr("id") == "bet5") { // etc.
            amount = 5;
        } else if($(this).attr("id") == "bet25") {
            amount = 25;
        } else if($(this).attr("id") == "bet100") {
            amount = 100;
        } else if($(this).attr("id") == "bet500") {
            amount = 500;
        } else if($(this).attr("id") == "bet1000") {
            amount = 1000;
        }
        if(player.money >= amount) { // check whether the player has this much to bet
            player.bet += amount; // add what was just bet by clicking that button to the total bet on this hand
            player.money -= amount; // and, of course, subtract it from player current pot
            $("#money").text("Money left: $" + player.money); // then redisplay what the player has left
        } else {
            alert("You don't have $" + amount + " to bet.");
        }
    });

    $("#place").click(function() {
        if(player.bet == 0) { // player didn't bet anything on this hand
            alert("Please place a bet first.");
        } else {
            $("#card_para").css("display", "block"); // now show the cards
            $(".card").bind("click", cardClicked); // and set up the event handler for the cards
            $("#bet_buttons_para").css("display", "none"); // hide the bet buttons and place bet button
            $("#redraw").css("display", "block"); // and reshow the button for redrawing the hand
            player.bet = 0; // reset the bet for betting on the next hand
            drawNewHand(); // draw the cards
        }
    });
}

Пожалуйста, дайте мне знать, если у вас есть какие-либо идеи или предложения, или если решение моей проблемы похоже на решение другой проблемы здесь (я просмотрел многие аналогично названные темы и не повезло найти решение это может сработать для меня).

Ответ 1

Чтобы убедиться, что действия с кликом только один раз используют это:

$(".bet").unbind().click(function() {
    //Stuff
});

Ответ 2

.unbind() устарел, и вместо этого вы должны использовать .off(). Просто позвоните .off() прямо перед вызовом .on().

Это приведет к удалению всех обработчиков событий:

$(element).off().on('click', function() {
    // function body
});

Чтобы удалить только зарегистрированные обработчики событий 'click':

$(element).off('click').on('click', function() {
    // function body
});

Ответ 3

. one()

Лучшим вариантом будет .one():

Обработчик выполняется не более одного раза для каждого элемента для типа события.

$(".bet").one('click',function() {
    //Your function
});

В случае нескольких классов и каждого класса нужно щелкнуть один раз,

$(".bet").on('click',function() {
    //Your function
    $(this).off('click');   //or $(this).unbind()
});

Ответ 4

Если вы обнаружите, что .off().unbind() или .stopPropagation() по-прежнему не исправляют вашу конкретную проблему, попробуйте использовать .stopImmediatePropagation() Работает велика в ситуациях, когда вы просто хотите, чтобы ваше мероприятие обрабатывалось без каких-либо пузырей и без каких-либо других событий, которые уже обрабатываются. Что-то вроде:

$(".bet").click(function(event) {
  event.stopImmediatePropagation();
  //Do Stuff
});

делает трюк!

Ответ 5

Если вы вызываете эту функцию на каждом "click", то она добавляет еще одну пару обработчиков при каждом вызове.

Добавление обработчиков с помощью jQuery просто не похоже на значение атрибута onclick. Можно добавить столько обработчиков, сколько пожелает.

Ответ 6

Событие будет срабатывать несколько раз, когда оно будет зарегистрировано несколько раз (даже если один и тот же обработчик).

например, $("ctrl").on('click', somefunction), если этот фрагмент кода выполняется каждый раз, когда страница частично обновляется, событие также регистрируется каждый раз. Следовательно, даже если щелкнуть Ctrl только один раз, он может выполнить "некоторую функцию" несколько раз - сколько раз он будет выполняться, будет зависеть от того, сколько раз он был зарегистрирован.

это верно для любого события, зарегистрированного в JavaScript.

Решение:

не забывайте звонить только один раз.

и по какой-то причине, если вы не можете контролировать архитектуру, сделайте это:

$("ctrl").off('click'); $("ctrl").on('click', somefunction);

Ответ 7

У меня возникла проблема из-за разметки.

HTML:

<div class="myclass">
 <div class="inner">

  <div class="myclass">
   <a href="#">Click Me</a>
  </div>

 </div>
</div>

JQuery

$('.myclass').on('click', 'a', function(event) { ... } );

Вы заметили, что у меня есть один класс myclass дважды в html, поэтому он вызывает щелчок для каждого экземпляра div.

Ответ 8

Лучшим вариантом будет использование off

<script>
function flash() {
  $("div").show().fadeOut("slow");
}
$("#bind").click(function() {
  $( "body" )
    .on("click", "#theone", flash)
    .find("#theone")
      .text("Can Click!");
});
$("#unbind").click(function() {
  $("body")
    .off("click", "#theone", flash)
    .find("#theone")
      .text("Does nothing...");
});
</script>

Ответ 9

Все, что связано с .on() и .one(), отлично, а jquery отлично.

Но иногда вы хотите, чтобы это было немного более очевидно, что пользователю не разрешено щелкнуть, и в этих случаях вы можете сделать что-то вроде этого:

function funName(){
    $("#orderButton").prop("disabled", true);
    //  do a bunch of stuff
    // and now that you're all done
    setTimeout(function(){
        $("#orderButton").prop("disabled",false);
        $("#orderButton").blur();
    }, 3000);
}

и ваша кнопка будет выглядеть так:

<button onclick='funName()'>Click here</button>

Ответ 10

Это происходит из-за того, что конкретное событие связано несколько раз с одним и тем же элементом.

Решение, которое сработало для меня, это:

Убейте все события, связанные с использованием метода .die().

И затем присоедините слушателя метода.

Таким образом,

$('.arrow').click(function() {
// FUNCTION BODY HERE
}

должен быть:

$('.arrow').die("click")
$('.arrow').click(function() {
// FUNCTION BODY HERE
}

Ответ 11

Мы должны stopPropagation() Чтобы избежать чрезмерного срабатывания триггеров Clicks.

$(this).find('#cameraImageView').on('click', function(evt) {
   evt.stopPropagation();
   console.log("Camera click event.");
});

Это предотвращает появление пузырьков в дереве DOM, предотвращая уведомление родительских обработчиков о событии. Этот метод не принимает никаких аргументов.

Мы можем использовать event.isPropagationStopped(), чтобы определить, был ли этот метод когда-либо вызван (в этом объекте события).

Этот метод работает для настраиваемых событий, запускаемых с помощью trigger(), а также. Обратите внимание, что это не предотвратит запуск других обработчиков одного и того же элемента.

Ответ 12

В моем случае я использовал делегат, поэтому ни одно из этих решений не работало. Я считаю, что это была кнопка, появляющаяся несколько раз через вызовы ajax, вызывающие проблему с несколькими щелчками. Решения использовали таймаут, поэтому распознается только последний щелчок:

var t;
$('body').delegate( '.mybutton', 'click', function(){
    // clear the timeout
    clearTimeout(t);
    // Delay the actionable script by 500ms
    t = setTimeout( function(){
        // do something here
    },500)
})

Ответ 14

$(element).click(function (e)
{
  if(e.timeStamp !== 0) // This will prevent event triggering more then once
   {
      //do your stuff
   }
}

Ответ 15

.one только один раз срабатывает на всю жизнь страницы

Поэтому, если вы хотите сделать валидацию, это неправильное решение, потому что, когда вы не покидаете страницу после проверки, вы никогда не вернетесь. Лучше использовать

$(".bet").on('click',function() 
{ //validation 
   if (validated) { 
      $(".bet").off('click'); //prevent to fire again when we are not yet off the page
      //go somewhere
    }
});

Ответ 16

Когда я занимаюсь этой проблемой, я всегда использую:

$(".bet").unbind("click").bind("click", function (e) {
  // code goes here
}

Таким образом я отвязываю и перепроверяю тот же ход.

Ответ 17

https://jsfiddle.net/0vgchj9n/1/

Чтобы убедиться, что событие всегда срабатывает только один раз, вы можете использовать JQuery.one(). JQuery гарантирует, что обработчик событий будет вызываться только один раз. Кроме того, вы можете подписаться на обработчик событий с одним, чтобы разрешить дальнейшие клики, когда вы закончили обработку текущей операции нажатия.

<div id="testDiv">
  <button class="testClass">Test Button</button>
</div>

...

var subscribeClickEvent = function() {$("#testDiv").one("click", ".testClass", clickHandler);};

function clickHandler() {
  //... perform the tasks  
  alert("you clicked the button");
  //... subscribe the click handler again when the processing of current click operation is complete  
  subscribeClickEvent();
}

subscribeClickEvent();

Ответ 18

Попробуй так:

<a href="javascript:void(0)" onclick="this.onclick = false; fireThisFunctionOnlyOnce()"> Fire function </a>

Ответ 19

В моем случае событие onclick срабатывало несколько раз, потому что я сделал общий обработчик событий относительно

  '$('div').on("click", 'a[data-toggle="tab"]',function () {
        console.log("dynamic bootstrap tab clicked");
        var href = $(this).attr('href');
        window.location.hash = href;
   });'

изменился на

    '$('div#mainData').on("click", 'a[data-toggle="tab"]',function () {
        console.log("dynamic bootstrap tab clicked");
        var href = $(this).attr('href');
        window.location.hash = href;
    });'

а также создавать отдельные обработчики для статических и динамических кликов, для статического щелчка вкладки

    '$('a[data-toggle="tab"]').on("click",function () {
        console.log("static bootstrap tab clicked");
        var href = $(this).attr('href');
        window.location.hash = href;
    });'

Ответ 20

В моем случае я дважды загрузил один и тот же файл *.js на странице дважды в <script>, поэтому оба файла привязывали обработчики событий к элементу. Я удалил дублирующее объявление и устранил проблему.

Ответ 21

Другое решение, которое я нашел, заключалось в следующем: если у вас несколько классов и вы работаете с переключателями при нажатии на ярлык.

$('.btn').on('click', function(e) {
    e.preventDefault();

    // Hack - Stop Double click on Radio Buttons
    if (e.target.tagName != 'INPUT') {
        // Not a input, check to see if we have a radio
        $(this).find('input').attr('checked', 'checked').change();
    }
});

Ответ 22

У меня была эта проблема с динамически сгенерированной ссылкой:

$(document).on('click', '#mylink', function({...do stuff...});

Я обнаружил, что замена document на 'body' устранила проблему для меня:

$('body').on('click', '#mylink', function({...do stuff...});

Ответ 23

Unbind() работает, но это может вызвать другие проблемы в будущем. Обработчик запускается несколько раз, когда он находится внутри другого обработчика, поэтому держите ваш обработчик снаружи, и, если вы хотите, чтобы значения обработчика были вложенными, присвойте их глобальной переменной, которая будет доступна вашему обработчику.

Ответ 24

Приведенный ниже код работал для меня в моем приложении чата для обработки нескольких событий, вызывающих щелчок мышью, более одного раза. if (!e.originalEvent.detail || e.originalEvent.detail == 1) {//Your code logic }