2010-08-12 3 views
23

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

Я использую jQuery для привязки событий кликов к кнопкам (jQuery UI) и ссылок на изображения (<a><img /></a>).

Есть ли способ сделать-раз и навсегда предотвратить другие события от обстрела после щелчка?

Или мне нужно поддерживать глобальную переменную с именем _isProcessing и установить ее для true для каждого обработчика событий?

Благодаря

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

+1

Что вы подразумеваете под «другими событиями» *? Другие обработчики событий на одном элементе? Или на его предках? Или на всей странице? Не могли бы вы прояснить свою конкретную потребность? – user113716

+0

Итак, если у меня есть ссылка на изображение, называемая «Добавить службу», которая добавляет строку в таблицу на моей странице. Если я нажимаю больше одного раза, он добавляет два. Никакие другие строки не должны добавляться в течение времени после того, как клик был сделан, и до того, как строка была создана. – Russell

+0

@ Russell - Да, я добавил ответ ниже, чтобы обратиться к этому. – user113716

ответ

29

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

Один из способов: unbind('click') на элементе, затем .bind() он снова, когда вы будете готовы.

Я бы предпочел использовать какой-то флаг. Это может быть переменная, но я предпочел бы присвоить класс элементу, например .processing, и удалить его, когда это будет сделано. Таким образом, вы должны проверить обработчик на наличие этого класса для определения кода, который должен выполняться.

$('someElement').click(function() { 
    var $th = $(this); 
    if($th.hasClass('processing')) 
      return; 
    $th.addClass('processing'); 
    // normal code to run 
    // then when done remove the class 
    $th.removeClass('processing'); 
}); 

Другой вариант заключается в использовании элементов .data() установить подобный флаг, как $(this).data('processing', true); Затем установите его в ложное, когда сделано.

+0

@ elo80ka - Спасибо. Я хочу, чтобы jQuery имел что-то вроде '.disableHandler ('click')' и '.enableHandler ('click')' в качестве альтернативы '.bind()/unbind()' и несколько захламленных/хакерских решений, таких как использование классов или переменных как флаги. : o) – user113716

+0

Вы должны использовать функцию .data(), а не добавлять класс, который может случайно повлиять на отображение элемента. – bcherry

+0

@bcherry - Хорошая вещь об использовании класса заключается в том, что это (я уверен) операция более легкого веса, чем использование '.data()'. Если вы осторожны с присвоением имени своему классу, не должно быть никаких последствий для отображения. – user113716

7

Вы проверили preventDefault?

$("a").click(function(e) { 
    e.preventDefault(); 
} 

вы также можете попробовать stopImmediatePropagation() или stopPropagation()


Вы также можете посмотреть в one() события.

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

+0

Метод 'e.preventDefault()' действительно не останавливает обработчики. Это предотвращает активацию элемента по умолчанию (например, '' приводит вас к его местоположению 'href'). – user113716

+1

используется e.stopImmediatePropagation(); работал. Благодаря! Также используется unbind. – techdude

+0

one() помог моему случаю, когда событие запускалось для каждого щелчка. Благодаря! – planetregin

3

false От вашего обработчика событий или позвоните по номеру ev.stopPropagation() в каждом обработчике.

+0

Используйте .stopPropagation() – Mark

+0

@Mark - Перечитайте вопрос. * «Моя проблема не мешает пузырению события». * – user113716

+0

Я разъяснил вопрос после того, как он опубликовал свой ответ. – Russell

19

Существует event.preventDefault, event.stopPropagation и возвращает false как уже указано.

$("a").click(function(e) { 
    e.preventDefault(); 
    e.stopPropagation(); 
    return false; 
} 
+0

:-) для хорошей меры ... (хотя вопрос другой, я думаю ...) –

+0

yep, когда я ответил, вопрос еще не выяснен. – TehOne

+0

Да, извините, @TehOne, я не высказал свой вопрос правильно в первый раз. – Russell

2

У вас есть несколько вариантов:

  1. Если кнопки/ссылки перезагрузит страницы вы можете просто отвязать клик обработчик события:

    $('input:submit').click(fumction() { 
        $(this).unbind('click'); 
        // Handle event here 
    }) 
    
  2. Вы может отключить кнопки и снова включить их, как только вы закончите (я думаю, это также должно работать с <input type="image">):

    $('input:submit').click(function() { 
        $(this).attr('disabled', 'disabled'); 
        // It also helps to let the user know what's going on: 
        $(this).val('Processing...'); 
        // Handle event here 
        $(this).removeAttr('disabled'); 
    }) 
    

    Я не думаю, что это работает на ссылках.

+0

Знаете ли вы, есть ли способ отключить события (не отменить, просто отключить)? – Russell

+0

@ Russell: вы можете отключить элементы ввода. Насколько я знаю, отключенные элементы не создают события. – elo80ka

+0

Да, но ссылка на изображение (якорь), например, может вызвать событие щелчка, но не поле ввода (как вы сказали, отключение элементов привязки не работает). – Russell

2

Другой способ заключается в использовании event.stopPropagation() и event.isPropagationStopped() для сигнализации:

Пример:

$(button).click(function(e){ 
    if(e.isPropagationStopped()) 
     return; // propagation was stopped, so stop further execution 

    // if you got this far - this event handler was called first 
    // custom logic goes here 

    // stop event propagation to signal other handlers 
    e.stopPropagation(); 

    // if you need, call e.preventDefault() to prevent default behaviour 
}); 

Повторите же логика для других обработчиков событий.