jQuery: как остановить распространение на тот же обработчик? - PullRequest
1 голос
/ 17 января 2012

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

$(document).click(function (event) {
  console.log("Ok");
});

$(document).add($('p')).click(function onceHandler(event) {
  console.log('Clicked.');
});

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

event.stopPropagation() сломает первый обработчик, поэтому я не могу его использовать.Я также попробовал:

$(document).add($('p')).click(function(event) {
  if (event.stopDoingThat) return;
  console.log('Clicked.');
  event.stopDoingThat = true;
});

, который не работал.Таким образом, в основном, ничего не меняя, я получаю 2 "нажал" и один "хорошо".С stopPropagation - 1 "нажал", мне нужно 1 "нажал" и 1 "хорошо"

Ответы [ 5 ]

2 голосов
/ 17 января 2012

Это идеальный вариант использования функции one из jQuery:

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

В вашем случае это будет выглядеть примерно так:

$(document).add($('p')).one('click', function onceHandler(event) {
    console.log('Clicked.');
});

Более подробную информацию можно найти в jQuery docs .

1 голос
/ 17 января 2012

Не уверен, что это будет работать во всех браузерах, но я протестировал его в chrome.

$(document).click(function (event) {
  console.log("ok");
});

$(document).add($('p')).click(function onceHandler(event) {
    if(!event.originalEvent.myClickDone){
        console.log("click");    
    }

    event.originalEvent.myClickDone = true;
});

По сути, оба event объекта имеют общий originalEvent.

1 голос
/ 17 января 2012

Вы пробовали:

var firstRun = true;

$(document).click(function (event) {
  console.log("Ok");
});

$(document).add($('p')).click(function onceHandler(event) {
  if(firstRun) {
    console.log('Clicked.');
    firstRun = false;
  }
});

Возможно, есть более элегантное решение.Что-то вроде:

$(document).click(function (event) {
  console.log("Ok");
});

$(document).add($('p')).on("click.runonce", function(event) {
    console.log('Clicked.');
    $(document).off("click.runonce");
  }
});

Ссылка на этот другой вопрос SO

0 голосов
/ 17 января 2012

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

$(document).click(function(event) {
    if(event.target.tagName.toLowerCase() === "p") {
       console.log("clicked");
    }
    console.log("ok");
});

Демо.

0 голосов
/ 17 января 2012

проблема в том, что вы используете функцию apply дважды для объекта документа, а не для объекта абзаца.Измените свою последнюю строку, чтобы она выглядела так:

$(document).click(function (event) {
  console.log("Ok");
});

$(document).add($('p').click(function onceHandler(event) {
    console.log('Clicked.');
    $('p').off('click');
  }
}));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...