JQuery - не назначать обработчик повторно

12
Dreammaker
На сайте с 20.04.2006
Offline
569
3137

 
$(document).ready(function(){

handleDeleteImage2();
}

function handleDeleteImage2() {
$("a.ajaxtest").click(function(){
alert('123');

});
}

 
<a href="#" class="ajaxtest" onClick="alert('123');return false;">1</a>
<a href="#" class="ajaxtest">2</a>
<a href="#" class="ajaxtest">3</a>

В итоге мы по клику на первую из ссылок имеем 2 алерта.

Вопрос: как сделать так чтобы JQuery не назначал обработчик на OnClick элемента класса, если он там уже есть?

Dreammaker добавил 29.03.2009 в 19:56

update: Для конкретно своей задачи решил появившимся в 1.3.x методом live() .

У меня часть элементов уже существует при генерации страницы, а часть подгружается через ajax и вот, на при подгрузке обработчик вешался не только на последний элемент, но и на всё предыдущие, а они уже имели такой же.

Использование live вешает такой обработчик только на новосозданный элемент. Хотя субъективное ощущение, навешенная функция отработчик немного тормознее в этом случае работает.

О live можно прочитать вот здесь (собсно я, по этому блогу и разобрался): http://www.jstoolbox.com/2009/02/13/dinamicheskoe-naznachenie-obrabotchikov-sobytij-v-jquery-13/

Но всё же хотелось бы и знать решение задачи в чистом виде описанной в начале.

DA
На сайте с 04.02.2005
Offline
165
#1

как-то слишком извращенно....

может вот это Вам поможет: http://docs.jquery.com/Events/unbind#typefn

тыщ-пыщ
Dreammaker
На сайте с 20.04.2006
Offline
569
#2

DJ_AlieN, спасибо, на досуге попробую (сейчас сходу завести не получилось, а вот с live() вроде работает :) ).

DA
На сайте с 04.02.2005
Offline
165
#3

Вот еще более красивый вариант:

http://docs.jquery.com/Selectors/attributeNotEqual#attributevalue


$("a.ajaxtest").click(function(){

нужно всего лишь заменить на

$("a.ajaxtest[onclick!='123']").click(function(){

т.е. эвент пропишется только тому, где нету onClick

Dreammaker
На сайте с 20.04.2006
Offline
569
#4

DJ_AlieN, хм, по-моему этот вариант касается только аттрибутов, а не эвентов.. :)

DA
На сайте с 04.02.2005
Offline
165
#5

Нууу, все правильно!

Если аттрибут onclick не равен 123 или он отсуствует, то вешаем событие на эвент click

Добавлено

Быть может Вы внесете больше деталей в смысл этих манипуляций? :)

Добавлено2

Может быть эта ссылка первая появляется позже генерации страницы? Тогда можно снять онклики после события "появление ссылки":

$("a.ajaxtest").attr('onclick','');

Dreammaker
На сайте с 20.04.2006
Offline
569
#6

DJ_AlieN, в базе хранятся данные о картинках привязанных к странице. Они выводятся в виде списка ul - li . В li там hidden поле с id картинки, картинка-ссылка зацепляя которую можно двигать картинки и менять их порядок + ссылка Delete. На onClick Delete висит запрос на удаление картинки. То есть, кликаем на Delete выскакивает запрос Да/Нет. Удалили.

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

эвент onclick путям запуска handleDeleteImage2()

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

Насколько я понял наиболее кошерным в моём случае будет использование именно live() ибо для этого он и создавался...

[Удален]
#7
DA
На сайте с 04.02.2005
Offline
165
#8

Давайте по порядку:

1) Функция, которую надо исполнить при клике на ссылку


<script type='text/javascript'>
function aClick(){
if(confirm("Точно удалить")){
/// удаление
}else{
return false;
}
}
</script>

2) Функция, которая присвоит onclick всем <a> класса ajaxtest без аттрибута onclick


<script type='text/javascript'>
function BindOnClick(){
$("a.ajaxtest[onclick!='aClick']").attr('onclick','aClick');
}
</script>

3) HTML-код:

<a href="#" class="ajaxtest">1</a>
<a href="#" class="ajaxtest">2</a>
<a href="#" class="ajaxtest">3</a>

после каждого обновления ссылок нужно запускать BindOnClick

Обратите внимание, у первого элемента в коде нету onClick т.к. он пропишется автоматом.

В данном случае примочка НЕ НУЖНА ибо вариантов исполнения того что Вам нужно втроенными средствами в jQuery предостаточно

JTRTA
На сайте с 06.07.2008
Offline
25
#9

По моему стоит пересмотреть организацию самого процесса загрузки изображения.

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

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

Дальше если используете Jquery может изящней будет сделать так:

$.fn.handleDeleteImage2 = function(){

this.each(function(){
this.click(function(){
alert('123');
});
});
};

и затем в программе вызывать только для нужных элементов что то вроде:

$(document).ready(function(){

$("a.ajaxtest").handleDeleteImage2();
}

или когда добавляете новый узел

$(someNewNode).handleDeleteImage2();
Дизайн /ru/forum/493415 (/ru/forum/493415) Верстка от 15$ /ru/forum/509339 (/ru/forum/509339) Сайты под ключ aiogino.studio@gmail.com icq: 460146806
Dreammaker
На сайте с 20.04.2006
Offline
569
#10
DJ_AlieN:
Обратите внимание, у первого элемента в коде нету onClick т.к. он пропишется автоматом.

тьфу, я уже сам себя запутал - сейчас гляну л первоначальный код, который ко мне попал и там был, как раз описанный вами случай. Первоначально у сcылки не было события, но после каждого "навешивания" на ссылки, он дублировался, и чем больше раз цеплялся новый узел, тем больше обработчиков висело на одной отдельно взятой ссылке.

DJ_AlieN:
2) Функция, которая присвоит onclick всем <a> класса ajaxtest без аттрибута onclick

Так-с, только теперь начинаю понимать, что вы имели в виду (надеюсь это для меня простительно, ибо JQeury я первый раз, как разработчик увидел вчера или позавчера :) ).

DJ_AlieN:
Вам нужно втроенными средствами в jQuery предостаточно

собсно live насколько я понимаю это как раз и есть встроенное средство, правда, начиная с версий 1.3.x

Я не буду трогать, что уже сделал с точки зрения "работает - не трогай" :), но ваш вариант буду иметь в виду на будущее.

neolord:
http://docs.jquery.com/Namespaced_Events

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

JTRTA:
$(document).ready(function(){ $("a.ajaxtest").handleDeleteImage2(); }

где-то из-за такого и навешивались по нескольку раз события. Или я же что-то не понимаю.

JTRTA:
$(someNewNode).handleDeleteImage2();

Вот этот вариант довольно интересен я о нём не подумал, точнее думал, но сходу не мог придумать как получать id новодобавленного элемента. Уставший моск не мог придумать, что его можно генерировать. :)

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий