как предотвратить многократную регистрацию одного обработчика событий в jquery - PullRequest
2 голосов
/ 22 ноября 2011

У меня есть поле <div>, отображающее поисковое сообщение и некоторую кнопку-переключатель для недавнего сообщения. Есть опция ссылки для переключения слайдов.

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

Когда я обновляю всю страницу, она работает должным образом, но когда эта специфическая коробка или часть обновляется, тогда коробка скрывается и немедленно скрывается. Если вы обновите эту часть n количество раз, когда окно будет непрерывно переключаться. Я думаю, что проблема заключается в регистрации обработчика событий. Поэтому, пожалуйста, дайте мне какое-нибудь решение.

КОД:

$(document).ready(function() {
  $(".SideBar-blockheader1").click(function() {
    e.preventDefault();
    $(".SideBar-blockcontent1").slideToggle("fast");
  });

  $(".SideBar-optionheader").click(function() {
    $(".SideBar-optioncontent").slideToggle("fast");
    $(this).text($(this).text() == $("#hideopt").attr('value') ?  $("#showopt").attr('value') : $("#hideopt").attr('value'));
  });

  $(".SideBar-optionheader").text($("#showopt").attr('value'));
  $(".SideBar-optioncontent").hide();
});

Ответы [ 2 ]

0 голосов
/ 22 ноября 2011

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

if(typeof $('#id').data('events').click == 'object')
{
    // A click handler is already attached
}
else
{
    // No click handler; Attach one;
}
0 голосов
/ 22 ноября 2011

Хотя вы не предоставили код, я подозреваю, что вы используете .click (). Для jQuery 1.7+ вы должны использовать .on() в режиме делегата (элемент, с которым вы связываетесь, является предком, а не сам кликабельный элемент) или .delegate(), если до jQ 1.7.

Например:

$('someAncestor').on('click', 'a.specialLink', function(event) {
  event.preventDefault();
  // the rest of your code for the click handler
})

"someAncestor" - это любой действительный селектор, являющийся предком вашей ссылки, который не будет уничтожен, перестроен или каким-либо другим образом изменен после создания DOM. Это не обязательно должен быть прямой предок.

[обновлено ниже после просмотра примера кода и комментариев]

Есть несколько вещей, происходящих. Во-первых, .on() будет работать, только если вы используете jQuery 1.7+. Затем, .on() может быть вызван несколькими различными способами (я написал об этом здесь: http://gregpettit.ca/2011/jquery-events-its-on/), и вам нужно вызывать его при делегировании слушателя-предка, а не просто в качестве замены для щелчка. Далее, у вас есть не предоставил код для вашей попытки обновления, только для исходного кода, трудно сказать, что «не сработало» при попытке использовать .on(). Двигаясь дальше, я не совсем уверен, для чего предназначена эта строка :

$(this).text($(this).text() == $("#hideopt")...etc...

Я не могу понять, почему вы хотите попробовать обработать объект jQuery как переменную. Я не говорю, что код неправильный, я просто говорю, что не понимаю. Кроме того, я ненавижу троичных операторов ... что является одной из причин, почему я не понимаю. Я предпочитаю удобочитаемые условные выражения. ; -)

Далее, вы вызываете protectDefault () для «e», но вы не передаете «e» в свои функции. Возможно, вы просто получаете ошибку JavaScript, точка. (е не определено)

Тогда есть attr("value"), который, я считаю, на самом деле должен работать. Но почему бы не использовать .val(), если это действительно узел, который имеет атрибут значения?

Наконец, есть тонны пространства для кэширования ваших объектов. Каждый раз, когда вы видите, что объект используется более одного раза, вы можете извлечь выгоду (с разной степенью производительности и разборчивости) из его кэширования. Я не обновлял код с помощью какого-либо кэширования, хотя - это действительно что-то для целого другого "Как я могу лучше всего кэшировать свои объекты?" вопрос.

Во всяком случае ... чтобы решить проблему, сначала нужно выбрать действительного предка. Это может быть любой предок, который не был уничтожен в процессе загрузки новых данных. Это может быть что угодно, но самый близкий предок - лучший. Это может быть оболочка раздела, но если вы действительно отчаялись, это может быть оболочка страницы или даже тег body. Если вы привязываетесь к документу, вы воспроизводите устаревшую функцию .live(), против которой я определенно рекомендую. Я использовал селектор-заполнитель ".section", но вам необходимо выяснить, какой соответствующий предок находится на вашей странице.

$(document).ready(function()
{
  $(".section").on("click", ".SideBar-blockheader1", function(e)
  {
    e.preventDefault(); // probably not necessary if there's no default click behaviour
    $(".SideBar-blockcontent1").slideToggle("fast");
  });

  $(".section").on("click", ".SideBar-optionheader", function(e)
  {
    e.preventDefault(); // probably not necessary if there's no default click behaviour
    $(".SideBar-optioncontent").slideToggle("fast");
    $(this).text($(this).text() == $("#hideopt").val() ?$("#showopt").val() : $("#hideopt").val());
  });

  $(".SideBar-optionheader").text($("#showopt").val());
  $(".SideBar-optioncontent").hide();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...