|
|
|
| Всем привет! Сегодня я хотел бы поговорить о такой штуке как callback методов JQuery. Недавно верстая сайт и реализовывая графический эффект заметил одну не приятную вещь. Давайте рассмотрим пример кода.
<html>
<head>
//Подключение библиотеки Jquery
<script>
$(function(){
$('a').click(function(){
$(this).parent().fadeOut(500, function(){
$($(this).attr('href')).fadeIn(500);
});
});
});
</script>
<style>
article {display:none}
</style>
</head>
<body>
<nav>
<a href="#art_1">First</a>
<a href="#art_2">Second</a>
</nav>
<article id="art_1"> Текст текст</article>
<article id="art_2"> Текст текст</article>
</body>
</html>
|
В этом примере используются методы fadeIn(), fadeOut(). Принцип работы предельно ясен. При нажатие на ссылку, все меню полностью продает, и только после того как оно пропадет, плавно появляется соответствующий ссылке article.
/*
Дополнительно, не принимая в счет, давайте допустим, что где-то есть кнопка, которая точно таким же способом, скрывает article и проявляет nav. Вы потом поймете зачем это.
*/
Все работает отлично. Но, как я уже писал, нашел не приятную вещь. Callback стал выполнять в то время, когда до завершения метода остается еще примерно 95% времени. Это случается после того, когда я выполняю следующее:
1) Перехожу по первой ссылке (появляется article, пропадает nav)
2) Возвращаюсь обратно в меню (пропадает article появляется nav)
3) Перехожу по второй ссылке (появляется article, пропадает nav)
4) Возвращаюсь обратно в меню (пропадает article появляется nav)
Вот на шаге 4 (и в последующем на всех таких шагах) и появляется проблемы. И не важно в каком порядке я нажимаю на ссылки. Но, если я буду каждый раз переходить по одной и той же ссылке, таких проблем не замечается.
На скриншоте показано к чему это приводит шаг 4.
Вот такие вот дела. Прошу вашей помощи.
Jquery кстати версии 1.9* | |
|
|
|
|
|
|
|
для: Гавриленко Дмитрий
(02.10.2013 в 13:44)
| | А это что такое:
$($(this).attr('href')) ?
Выбрасываем этот каламбур и вместо него пишем:
alert(this.tagName)
Что получаем? | |
|
|
|
|
|
|
|
для: confirm
(03.10.2013 в 01:58)
| | Почему выбрасываем? Нажимая на ссылку, из href извлекается #id блока, который потом нужно будет показать. this.tagName выведет "A" | |
|
|
|
|
|
|
|
для: Гавриленко Дмитрий
(03.10.2013 в 15:09)
| | Почему? Потому, что в вашем коде тег А никак не получится, и "Jquery кстати версии 1.9*" даже хоть 9.1 все равно будет выполнять то, что от него требуют, а не то, что предполагают. Ваш код:
$('a').click(function(){
$(this).parent().fadeOut(500, function(){ //здесь this - это ссылка, а parent - это ее родитель, тег nav
//то есть вы скрываете меню
$($(this).attr('href')).fadeIn(500); //а тут this это то, к чему вы выше перешли, родителю
//а родитель ссылки, тег nav, не имеет атрибута href
});
});
|
И вообще, вы поместите между блоками article что либо, чтобы второй блок article был скрыт без прокрутки. и выполните более наглядный эффект, вызвав второй article:
$('a').click(function(){
$($(this).attr('href')).slideDown(500);
});
|
Вы наблюдаете эффект? Есть смысл во всем этом? | |
|
|
|
|
|
|
|
для: confirm
(03.10.2013 в 15:36)
| | Ну допустим я чуток ошибся в коде. Это не CopyPast. Где $($(this).attr('href')) на самом деле должно быть у меня $($(this).children().attr('href')). Но дело все равно не в том на что я нажимаю и что скрывается, дело в том, что $($(this).children().attr('href')).fadeIn(500) допустим, начинается быстрее, чем заканчивается $(this).parent().fadeOut(500), хотя первый у последнего в callback. | |
|
|
|
|
|
|
|
для: Гавриленко Дмитрий
(03.10.2013 в 17:17)
| | Нормально, пишите какой-то абсурд, и надо догадаться чего у вас на самом деле должно быть? | |
|
|
|
|
 453.8 Кб |
|
|
для: confirm
(03.10.2013 в 15:36)
| | Посмотрите сами. Код простейший. Перейдите сначала по одной, потом по другой ссылке. Изображение возвращает в меню. | |
|
|
|
|
|
|
|
для: Гавриленко Дмитрий
(03.10.2013 в 17:52)
| | В основе всех эффектов лежит таймер, а передача в пост-обработчик происходит только по завершению анимации, условие завершения которой и проверяется в таймере. То есть вызов callback функции ранее запланированного не произойдет.
$(function(){
$('a').click(function(){
$($(this).attr('href')).slideDown(500, function(){
$('#txt').text('END');
});
});
});
</script>
<nav>
<a href="#art_1">First</a>
</nav>
<article id="art_1"> Текст текст</article>
<div id="txt"></div>
|
Если в этом примере в DIV появится текст ранее окончания анимации, значит все не правы, а ваши утверждения истины.
Всякие ляпсусы происходят не потому, что таймер анимации плюнул на условие и прекратил работу, а потому, что пишут код не понимая того, что пишут.
Вы даже библиотеку подключаете не понятно откуда, взгляните на свой код. И попутно, взгляните на пример одностраничного сайта, например этот. Тут оправдано применения якорей, и анимация при выборе в меню вполне логична.
Где логика и смысл в том, что вы делаете? | |
|
|
|
|
|
|
|
для: confirm
(03.10.2013 в 18:10)
| | Вы сами попробовали переходить по ссылкам в примере, что я прикрепил? При всем Уважение к Вам, я не согласен с тем, что вы гоните на меня. Я показывал этот код не одному программисту, которые разбираются в JQuery. Все просто махали головой в стороны не понимая почему так происходит. По этому я и обратился сюда как к авторитетному источнику. Может вы поможете мне исправить мой код JQuery? | |
|
|
|
|
|
|
|
для: Гавриленко Дмитрий
(03.10.2013 в 18:32)
| | Боже упаси гнать, как вы выражаетесь.
Щелкал да, но даже не щелкая ничего понятно главное - то что вы делаете лишено смысла. А какой смысл разбираться в том, что не имеет смысла?
Потому и дал ссылку, вот там есть смысл, и там тоже есть ошибка (выбор контактов), но в данном случае будет польза от поиска этой ошибки, и такая работа интересна. А вот в вашем коде, извините, можете считать как угодно, гоню я или еще нечто. Могу сказать почему, и описать подробно почему, но тратить время впустую не буду.
Может лучше вам описать словами чего же вы хотите, типа ТЗ? | |
|
|
|
|
|
|
|
для: confirm
(03.10.2013 в 18:43)
| | Ну там же все понятно. Сайт одностраничник. Не должно быть загрузки когда нажимаешь по ссылкам. Информация динамически меняется. | |
|
|
|
|
|
|
|
для: Гавриленко Дмитрий
(03.10.2013 в 18:58)
| | Мне ничего не понятно. Я вижу по коду - есть меню со ссылками, и при выборе любой из них меню скрывается. Если бы это была игра в прятки я бы мог это понять, иначе в моем понимании, это просто глупость. | |
|
|
|
|
|
|
|
для: confirm
(03.10.2013 в 19:02)
| | Нажимая на картинку меню возвращается. | |
|
|
|
|
|
|
|
для: Гавриленко Дмитрий
(03.10.2013 в 19:05)
| | Оригинальная задумка. Я вам сказал - в том, в чем я не нахожу логики мне разбираться не охота, не вижу смысла в этом. Это тоже самое как знание того, что за миллиарды световых лет есть цивилизация, есть, ну и хорошо, но пользы практической от этого нет никакой. | |
|
|
|
|
|
|
|
для: Гавриленко Дмитрий
(03.10.2013 в 17:52)
| | 1. Я не вижу опережения. Т.е. показываться блок начинает именно тогда, когда скрылся предыдущий.
2. Клик по тегу A вызывает переход. Если у вас фактически его не происходит, его нужно отменять:
$('a').click(function(e){
e.preventDefault();
.......
});
// либо
$('a').click(function(e){
.......
return false;
});
|
3. С установкой $img.click() - это вы перемудрили.... Устанавливая новый обработчик, старый никуда не девается.... Он не перезаписывается новым. Т.е. после нескольких кликов, у вас будет несколько обработчиков. Например попробуйте кликнуть "о нашей компании", затем вернуться, затем кликнуть "портфолио" и, не дожидаясь конца анимации, кликнуть по картинке.
Итак, старый обработчик либо нужно убирать сразу после клика по A, но тогда войдя в подменю, на верхний уровень уже не выйти, либо не связывать его с кликом A, а вынести отдельно, установить только один раз, и в нем уже проверять что нужно показать, а что скрыть. | |
|
|
|