Флажок внутри поведения щелчка якоря - PullRequest
6 голосов
/ 11 ноября 2011

Рассмотрим следующий фрагмент:

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
    </head>
    <body>
        <form>
            <a id="a" href="http://google.com">Goooooogle</a>
        </form>
        <script>
            $(function() {
                var checkbox = $('<input type="checkbox"></input>');
                checkbox.prependTo($('#a'));
                checkbox.click(function(e) {
                    e.stopPropagation();
                    // do something useful
                });
            });
        </script>
    </body>
</html>

Я хочу установить флажок внутри <a> и получить следующее поведение при нажатии:

  1. Как обычно, отметьте галочкой
  2. Сделайте что-нибудь полезное, например, AJAX-запрос
  3. Оставайтесь на этой странице, т.е. не будете перенаправлены на a href

Также я не хочу отменять поведение по умолчанию, если я нажимаю в любом месте в a, но не на флажок. То есть Я хочу разрешить выполнение всех обработчиков событий, связанных с a само нажатие.

Я думал, что это должно быть довольно легко, но я не могу получить желаемое поведение. Или:

  • Я буду перенаправлен в Google, если введу указанный код.
  • Если я использую e.preventDefault() из return false;, флажок не помечается. Кроме того, в этом случае флажок игнорирует явный checkbox.attr('checked', 'checked') и все другие возможные способы установить флажок.

Где подвох?

UPD: Это работает, как и ожидалось в Chrome, например Я не перенаправлен на клик, но не работает в Firefox Есть ли кросс-браузерный способ?

Ответы [ 4 ]

4 голосов
/ 12 ноября 2011

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

var checkbox = $('<input type="checkbox"></input>');
checkbox.prependTo($('#a'));
checkbox.click(function(e) {
    setTimeout(function() { checkbox.prop('checked', !checkbox.prop('checked')); }, 10);       
    // do something useful on clicking checkbox and but not surrounding link
    return false;
});
3 голосов
/ 22 июня 2014

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

Итак, используя ваш пример ( jsfiddle ):

// Don't change pages if the user is just changing the checkbox
$("#a").click(function(e) {
    //e.preventDefault(); // Optional if you want to to keep the link from working normally

    alert("Click came from: " + e.target.tagName);
    if (e.target.tagName != "INPUT") {
        // do link
        alert("Doing link functionality");
    } else {
        // do something useful
        alert("Doing checkbox functionality");
    }
});
2 голосов
/ 14 сентября 2016

Я знаю, что этому вопросу более 5 лет, но у меня недавно была такая же проблема, и я нашел обходной путь, чтобы добавить функцию onclick к флажку и в этом вызове функции event.stopImmediatePropagation ().

из w3schools: «Метод stopImmediatePropagation () предотвращает вызов других слушателей того же события»

то есть ... якорь.

function checkbox_onclick(event){
event.stopImmediatePropagation(); 
}
0 голосов
/ 11 ноября 2011

вот модифицированный скрипт

var checkbox = $('<input type="checkbox"></input>');
var a = $('#a');
a.unbind("click").click(function(e) {
    e.preventDefault();
    checkbox.attr('checked', !checkbox.attr('checked'));
});
checkbox.prependTo(a);
checkbox.click(function(e) {
    e.stopPropagation();
    // do something useful 
});

я отменяю событие click на <a> и связываю его с событием, чтобы установить / снять флажок, а также предотвратить использование по умолчанию.

...