Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 08.06.2010, 21:44
Новичок на форуме
Отправить личное сообщение для hara Посмотреть профиль Найти все сообщения от hara
 
Регистрация: 08.06.2010
Сообщений: 5

live click выполняется несколько раз
Здравствуйте,
в общем то уже задал данный вопрос на одном форуме, но не думаю что это является проблемой.

Итак:

При подгрузке контента в котором есть скрытые элементы, на которые вешаются события click (функцией live),
эти события срабатывают столько раз, сколько этот самый контент и загрузили.

То есть, другими словами:

Нажимаем на ссылку -> загружается Html внутри которого есть скрытый элемент и jquery код который вешает событие на этот элемент.
Так вот если этот элемент после загрузки сделать видимым - то на него вешается событие onClick и всё в порядке, - но если опять нажать на
первую ссылку - событие отработает дважды.
Причём такая проблема только если грузится html со скрытым элементом, который показывается только после загрузки.

Для того что бы можно было лучше понять что я имею ввиду привожу код:

Код файла index.html (ненужные теги удалены)
<script type="text/javascript">
            $(document).ready(function(){
                $('a.upload').bind('click',function(){
                    $('div#uploadContainer').load('./upload.html');
                });
                $('a.uploadedLink').live('click',function(){
                    $('a.hiddenLink').show();
                })
            });
        </script>
        <a href="#" class="upload">Upload content</a>&nbsp;&nbsp;
        <br><br><br>
        <div id="uploadContainer">
            Click above to load here some html
        </div>

Весь код файла upload.html
<script type="text/javascript">
    $(document).ready(function(){
        $('a.hiddenLink').live('click',function(){
            alert('Hello from hidden link');
        });
    });
</script>
<a href="#" class="uploadedLink">Click me to show hidden content</a><br><br>
<a href="#" class="hiddenLink" style="display:none;">Click me to trigger live event one or multiple times</a>


Возможно кто то уже сталкивался с данной проблемой?

Если будет нужно, - файлы приложил.
test.zip - только файлы index.html и upload.html (799Б)
и test-with-jquery.zip - три файла index.html, upload.html и jquery-1.4.2.min.js (24.2Кб) (что бы можно было просто распаковать и проверить результат)
Вложения:
Тип файла: zip test.zip (799 байт, 0 просмотров)
Тип файла: zip test-with-jquery.zip (24.2 Кб, 1 просмотров)
Ответить с цитированием
  #2 (permalink)  
Старый 08.06.2010, 21:54
Аватар для Gvozd
Матрос
Отправить личное сообщение для Gvozd Посмотреть профиль Найти все сообщения от Gvozd
 
Регистрация: 04.04.2008
Сообщений: 6,246

вы вообще представляете себе как работает метод live, и в чем его отличие от обычного назначения обработчика?

прочитайте внимательно документацию, а затем по шагам, подумайте, что будет происходить при очередном щелчке по div#uploadContainer
Ответить с цитированием
  #3 (permalink)  
Старый 08.06.2010, 22:14
Новичок на форуме
Отправить личное сообщение для hara Посмотреть профиль Найти все сообщения от hara
 
Регистрация: 08.06.2010
Сообщений: 5

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

При щелчке по div#uploadContainer происходит ничего не будет, видимо опечатка.

При щелчке на a.upload файл upload.html подгружается в div#uploadContainer затем там выполняется $('a.hiddenLink').live('click' и назначается(реально ещё не назначается) обработчик пока ещё скрытой ссылке.
При щелчке на a.uploadedLink cкрытая ссылка появляется и обработчик назначается(вот теперь точно назначается) скрытой ссылке. При нажатии на которую видим alert.

Теперь если нажать опять на ссылку a.upload произойдёт всё тоже самое, но уже при нажатии на скрытую ранее ссылку мы увидим alert дважды. - т.е. при удалении html метод live сохраняет его событие и когда он появляется вновь он добавляет его (а так помойму быть не должно).

Вот если бы ссылка hiddenLink - в подгружаемом коде не была скрыта изначально, то такой проблемы бы не наблюдалось.

По поводу опять же отличий live от bind - покажите мне где тут можно заменить Live на Bind без потери функционала, - если вообще вопрос конечно был к этому.

И в принципе если вынести js код из подгружаемого файла в index.html - то будет работать корректно, но этог сделать сложно - т.к. сайт полностью на ajax и не хотелось бы всегда подгружать все события на элементы, которые возможно и не загрузят. - хотя в общем то если нет решения проблемы, то прийдётся как то изворачиваться.

А теперь, судя по тону вашего ответа, - скажите мне где же я сильно затупил, потому как сам я пока этого не понимаю.
Ответить с цитированием
  #4 (permalink)  
Старый 08.06.2010, 22:21
Новичок на форуме
Отправить личное сообщение для hara Посмотреть профиль Найти все сообщения от hara
 
Регистрация: 08.06.2010
Сообщений: 5

Пардон, до меня дошло. Каюсь. Остаётся вопрос, - можно ли определить не назначен ли какой нибудь обработчик уже данному элеменету. Буду разбираться, спасибо.
Ответить с цитированием
  #5 (permalink)  
Старый 08.06.2010, 22:32
Аватар для sysya
Профессор
Отправить личное сообщение для sysya Посмотреть профиль Найти все сообщения от sysya
 
Регистрация: 27.12.2009
Сообщений: 292

А зачем в коде upload.html live? отсюда и повторяется навешивание click
__________________
Нет предела совершенству...
Ответить с цитированием
  #6 (permalink)  
Старый 08.06.2010, 22:34
Новичок на форуме
Отправить личное сообщение для hara Посмотреть профиль Найти все сообщения от hara
 
Регистрация: 08.06.2010
Сообщений: 5

Ну почему повторяется я уже понял.
А почему именно там, - потому что вообще сайт весь на ajax и там достаточно много обработчиков, не очень хорошо их кучковать в одном месте. Буду видимо подгружать js по мере необходимости один раз.
Ответить с цитированием
  #7 (permalink)  
Старый 08.06.2010, 22:36
Аватар для Gvozd
Матрос
Отправить личное сообщение для Gvozd Посмотреть профиль Найти все сообщения от Gvozd
 
Регистрация: 04.04.2008
Сообщений: 6,246

Сообщение от hara
При щелчке по div#uploadContainer происходит ничего не будет, видимо опечатка.
имел ввиду подгрузку в div#uploadContainer по щелчку на a.upload
Сообщение от hara
По поводу опять же отличий live от bind - покажите мне где тут можно заменить Live на Bind без потери функционала, - если вообще вопрос конечно был к этому.
.load() - как в загруженном содержимом использовать jquery?
djn rjulf yflj tuj cbgjkmpdjfnm/
но вопрос, был вообще-то не к этому.
Сообщение от hara
И в принципе если вынести js код из подгружаемого файла в index.html - то будет работать корректно
Именно!)
Сообщение от hara
не хотелось бы всегда подгружать все события на элементы, которые возможно и не загрузят
вы это уже сделали:
$('a.uploadedLink').live('click',function(){
                    $('a.hiddenLink').show();
                })


теперь же поясню вам:
к сожалению, напрямую в справке об этом нигде не говорится, но, насколько я знаю, при назначении live, на самом деле вешается событие на window.document и при возникновении любого клика по документу, проверяется "а кликнули не по нужному ли нам типу элемента"
когда, ты вызываешь второй и так далее разы код
$('a.hiddenLink').live('click',function(){ 
	            alert('Hello from hidden link'); 
	        });

из подгружаемого документа, то вешаются ДОПОЛНИТЕЛЬНЫЕ обработчики события на window.document
и каждый из них выполняется при щелчке, один за другим.
То есть, ты не снимаешь старые обработчики.

Именно, из-за такого непонимания базовых вещей, все адекватные разработчики JS советуют вначале досконально изучить чистый JS, а лишь затем учить и использовать jQuery.

PS отвлекался, и поэтому долго писал.
но в моем посте остались еще вещи, на которые вам надо обратить внимаиние
Ответить с цитированием
  #8 (permalink)  
Старый 08.06.2010, 22:42
Новичок на форуме
Отправить личное сообщение для hara Посмотреть профиль Найти все сообщения от hara
 
Регистрация: 08.06.2010
Сообщений: 5

Вообще то уже достаточно хорошо понял как сильно затупил.
Да в общем и получаются вот такие вопросы, от незнания основ, - согласен. Надо бы подучить при случае.
Ответить с цитированием
  #9 (permalink)  
Старый 08.06.2010, 22:44
Аватар для sysya
Профессор
Отправить личное сообщение для sysya Посмотреть профиль Найти все сообщения от sysya
 
Регистрация: 27.12.2009
Сообщений: 292

можно вот так сделать:
<script type="text/javascript"> 
            $(document).ready(function(){ 
                $('a.upload').bind('click',function(){ 
                    $('div#uploadContainer').load('./upload.html'); 
                }); 
            }); 
        </script> 
        <a href="#" class="upload">Upload content</a>&nbsp;&nbsp; 
        <br><br><br> 
        <div id="uploadContainer"> 
            Click above to load here some html 
        </div>
Вот мясцо $('a.uploadedLink').live('click',function(){ $('a.hiddenLink').show();}) вырезать и всё

Или наоборот, тоесть навешивать гдето в одном месте. У меня за подключением следит PHP, по настройкам к каждой странице сам определяет где что вставлять...
__________________
Нет предела совершенству...

Последний раз редактировалось sysya, 08.06.2010 в 22:46.
Ответить с цитированием
  #10 (permalink)  
Старый 09.06.2010, 10:58
Аватар для e1f
e1f e1f вне форума
Профессор
Отправить личное сообщение для e1f Посмотреть профиль Найти все сообщения от e1f
 
Регистрация: 03.04.2009
Сообщений: 1,263

Сообщение от Gvozd Посмотреть сообщение
к сожалению, напрямую в справке об этом нигде не говорится, но, насколько я знаю, при назначении live, на самом деле вешается событие на window.document и при возникновении любого клика по документу, проверяется "а кликнули не по нужному ли нам типу элемента"
Gvozd, не совсем. Можно указать контекст, на который навешивается обработчик.
Лишь тогда, когда в jquery это реализоали, появился смысл использовать live.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск