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

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

они прикреплены к кнопкам для размещения ставки, и он отлично работает для размещения ставки на первой руке во время игры( стреляя только один раз); но в ставках для второй руки он запускает событие click дважды каждый раз, когда нажата кнопка ставки или ставки (так что дважды правильно сумма ставки для каждого пресса). В целом, он следует этому шаблону для количества раз, когда событие click запускается при нажатии кнопки bet один раз-где ith термин последовательности для ставки ith рука с самого начала игры: 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 
            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's 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
        }
    });
}

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

19 ответов


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

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

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

это удалит все обработчики событий:

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

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

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

.one ()

лучшим вариантом было бы .one() :

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

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

в случае нескольких классов, и каждый класс должен быть раз нажал,

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

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

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

делает трюк!


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

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


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

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

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

в правильной логической последовательности функция "выкл" должна использоваться только тогда, когда вы действительно намерены развязать события. использовать его для сокрытия логических ошибок, вызванных двойной загрузкой функции "on", не очень хороший подход, даже если он может показаться работающим.


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

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, поэтому он вызывает click для каждого экземпляра div.


все вещи о .on () and .один () велик, и 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>

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

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

убить все события, прикрепленные с помощью .die() метод.

а затем прикрепите прослушиватель метода.

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

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

должно быть:

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

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

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

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

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

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


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

<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>

в моем случае я использовал "делегат", поэтому ни одно из этих решений не сработало. Я считаю, что это была кнопка, появляющаяся несколько раз через 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)
})

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

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

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

<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();

.за всю жизнь страницы стреляют только один раз!--2-->

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

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

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

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

в моем случае событие 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;
    });`

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


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

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

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