2015-02-25 3 views
1

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

Вот мой код:

$(document).on("click", "a[data-confirm], button[data-confirm]", function(e) { 
    var confirmData = $(this).data("confirm"); 
    if (confirmData === "true") 
     confirmData = $(this).prop("title"); 
    if (confirmData && !confirm(confirmData)) { 
     e.stopImmediatePropagation(); 
     e.stopPropagation(); 
     e.preventDefault(); 
     return false; 
    } 
    return true; 
    }); 

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

ответ

1

Чтобы предотвратить использование других обработчиков, используйте stopImmediatePropagation() и для предотвращения использования по умолчанию используйте preventDefault().

Как так:

$("body").on("click", ".elementClass[attributeName]", function(event){ 
    event.stopImmediatePropagation(); 
    event.preventDefault(); 
}); 

Добавляя [attributeName] в селекторе, селектор будет применяться только к элементам с атрибутом «ATTRIBUTENAME»

В приведенном выше примере это будет выполняться до вашего $(document) обработчик, поскольку событие пузырится вверх по DOM и доходит до body, прежде чем он доберется до document. Для того, чтобы убедиться, что это событие прилагается рано, вы можете прикрепить обработчик элемента следующим образом:

$(".elementClass[attributeName]").on("click", function(event){ 
    event.stopImmediatePropagation(); 
    event.preventDefault(); 
}); 

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

Другая техника, которую вы можете использовать только с помощью ванильного JavaScript, однако, - это захват события: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener.

Если true, useCapture указывает, что пользователь желает начать захват. После начала захвата все события указанного типа будут отправлены зарегистрированному слушателю перед отправкой на любой EventTarget под ним в дереве DOM. События, которые кипящие вверх по дереву не будут вызывать слушатель обозначенного использовать Capture

Вы можете сделать что-то вроде этого:

document.addEventListener("click", function(event){ 
    if(event.target.hasAttribute("attributeName")){ // jQuery: if($(event.target).attr("attributeName")){... 
     event.stopPropagation(); 
     event.preventDefault(); 
     //Do stuff 
    } 
}, true); 

Добавляя true в конце события захватываются, то есть это будут выполняться перед другими обработчиками.

+0

Спасибо, первая часть ясна, и я знаю об этом, однако, это не устраивает, потому что я хотел бы, чтобы предотвратить самые низкие обработчик уровня, а не только те, прилагается к документу. Однако я собираюсь проверить вторую часть. –

+0

Мое предположение заключается в том, что третье решение - это то, что на самом деле будет работать, поскольку захват происходит до барботажа. – winhowes

+0

Является ли этот третий фрагмент кода безопасным для браузера? Я знаю о многих причудах о событиях и их proeprties и т. Д. –

0

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

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

W3C-Events-flow-basics

+0

Да, я знаю это, поэтому я задал вопрос :) –

Смежные вопросы