jQuery fadeIn и fadeOut - замена div

Я новичок в jQuery и javascript в целом, но пробиваюсь через такие сайты.

У меня есть страница с шестью скрытыми div, которые вызываются соответствующими ссылками с отдельными идентификаторами. Когда каждый div становится видимым (.fadeIn), текущий отображаемый div скрывается (.fadeOut).

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

Вот мой js:

Спасибо заранее. Майк

$(document).ready(function(){

$("#link1").click(function() {
$("#panel2").fadeOut("slow", function() {                       
$("#panel3").fadeOut("slow", function() {
$("#panel4").fadeOut("slow", function() {                       
$("#panel5").fadeOut("slow", function() {
$("#panel6").fadeOut("slow", function() {
$("#panel1").fadeIn("slow")});
});
});
});
});
});

$("#link2").click(function() {
    $("#panel1").fadeOut("slow", function() {
$("#panel3").fadeOut("slow", function() {
$("#panel4").fadeOut("slow", function() {                       
$("#panel5").fadeOut("slow", function() {
$("#panel6").fadeOut("slow", function() {
$("#panel2").fadeIn("slow")});
});
});
});
});
});

$("#link3").click(function() {
    $("#panel1").fadeOut("slow", function() {
$("#panel2").fadeOut("slow", function() {
$("#panel4").fadeOut("slow", function() {                       
$("#panel5").fadeOut("slow", function() {
$("#panel6").fadeOut("slow", function() {
$("#panel3").fadeIn("slow")});
});
});
});
});
});

$("#link4").click(function() {
    $("#panel1").fadeOut("slow", function() {
$("#panel2").fadeOut("slow", function() {
$("#panel3").fadeOut("slow", function() {                       
$("#panel5").fadeOut("slow", function() {
$("#panel6").fadeOut("slow", function() {
$("#panel4").fadeIn("slow")});
});
});
});
});
});

$("#link5").click(function() {
    $("#panel1").fadeOut("slow", function() {
$("#panel2").fadeOut("slow", function() {
$("#panel3").fadeOut("slow", function() {                       
$("#panel4").fadeOut("slow", function() {
$("#panel6").fadeOut("slow", function() {
$("#panel5").fadeIn("slow")});
});
});
});
});
});

$("#link6").click(function() {
    $("#panel1").fadeOut("slow", function() {
$("#panel2").fadeOut("slow", function() {
$("#panel3").fadeOut("slow", function() {                       
$("#panel4").fadeOut("slow", function() {
$("#panel5").fadeOut("slow", function() {
$("#panel6").fadeIn("slow")});
});
});
});
});
});

});


person Mike Turbutt    schedule 06.04.2011    source источник


Ответы (6)


Этот код, безусловно, можно было бы сделать более эффективным и гибким, но для простого примера из 6 элементов, как показано выше, этого должно быть достаточно. В основном это было сделано просто как доказательство концепции.

Я решил добавить классы программно, но в идеале вы должны добавить классы в HTML. Если бы это был я, я бы, вероятно, также использовал расширение вместо замены строки идентификатора.

РЕДАКТИРОВАТЬ, добавлены исправления:
Рекурсивная функция для последовательной анимации гарантирует, что затухание будет обработано в нужное время. Для этого может быть более эффективный метод, например использование счетчика, но всего для 6 элементов это должно подойти, и это более точно соответствует исходному коду.
Исправлена ​​обработка анимации в неправильное время, например, когда вы нажмите несколько ссылок одновременно, заставляя несколько панелей пытаться исчезнуть, останавливая и заканчивая анимацию.

jQuery(function($){
    //add links/panels class to all elements whose id begins with link/panel
    $("[id^=link]").addClass("links");
    $("[id^=panel]").addClass("panels");

    $(".links").click(function(e){
        //find all panels, make a normal array, and stop/finish all animations
        var panels=$.makeArray($(".panels").stop(true, true));

        //find panel to show
        var panelShow=$("#"+this.id.replace("link","panel"));

        //recursive function to execute fades in sequence
        function queueFX(queue){
            if(queue.length==0){
                panelShow.fadeIn("slow");
                return;
            }
            $(queue.shift()).fadeOut("slow", function(){
                queueFX(queue);
            });
        }
        queueFX(panels);

        //stop event propogation and default behavior, commented out because you don't seem to want this behavior
        e.preventDefault();
        //e.stopPropagation();
        //return false;
    });
});
person user120242    schedule 06.04.2011
comment
Миллион благодарностей за это. Однако мои ссылки перестают работать с этим. У меня есть шесть уникальных ссылок с тегами href=#. Должен ли я использовать что-то другое? - person Mike Turbutt; 07.04.2011
comment
Это странно. Я проверил это сам на странице, которую вы предоставили, и, похоже, у меня все работает. Вы можете изменить return false, если хотите. Я добавил это, чтобы он не пытался перейти по ссылке. Может быть не то, что вы хотели - person user120242; 07.04.2011
comment
Закомментировал возврат false и объяснил его, а также добавил исправления, чтобы анимации вели себя так, как вы, скорее всего, и предполагали. - person user120242; 07.04.2011
comment
Действительно жаль, что я не понял это, поскольку вы все так полезны. Мои ссылки по-прежнему не работают с этим кодом. Думаю, мне придется пройти курс, чтобы не быть занозой в заднице. :о) - person Mike Turbutt; 07.04.2011
comment
Привет, все в порядке. Приятно иметь несколько хаков для скриптов, чтобы согнуть мой скрипт-фу :p Можете ли вы объяснить более подробно, что вы имеете в виду, говоря, что ваши ссылки не работают? Вы имеете в виду, что затухание не работает? - person user120242; 07.04.2011
comment
Спасибо за понимание. Да, щелчок по ссылкам не исчезает из видимой панели или исчезает из панели для соответствующей ссылки. Как будто он мертв. Я загрузил страницу с вашим скриптом на www.miketest.tk, чтобы вы могли ее увидеть. Я также понял, что у меня есть 6 панелей, оформленных с помощью класса, который я теперь изменил на отдельные идентификаторы (которые мне все равно понадобятся, поскольку я собираюсь использовать разные фоновые изображения на каждой панели). Мне интересно, не противоречит ли это классу, который вы создали в своем скрипте? - person Mike Turbutt; 07.04.2011
comment
Теперь я вижу, что пошло не так, вы не использовали событие готовности документа с этим кодом. Вам все равно нужно заключить его в готовое событие, я добавлю код, чтобы было понятно. Все элементы могут иметь несколько классов. например: ‹div class=class1 class2 class3 class4›‹/div› может упоминаться как $(div.class1) или $(.class2) или $(.class3)... - person user120242; 07.04.2011
comment
Заключено в событие готовности документа. Должно работать как сейчас. - person user120242; 07.04.2011
comment
Меня действительно нельзя выпускать одну! Крайне смущен своим невежеством и в высшей степени благодарен за вашу настойчивость и объяснения. Меня всегда поражало, как работают подобные сайты и как счастливы люди, помогающие совершенно незнакомым людям с их проблемами. Если бы только миром правили выродки, а не политики, это было бы адское место для жизни! Большое большое спасибо. Майк - person Mike Turbutt; 07.04.2011

Имея ваши идентификаторы, это может быть так:

$.each([1,2,3,4,5,6], function(_, index) {
    $('#link' + index).click(function() {
        $('[id^=panel]').fadeOut('slow', function() {
            $('#panel' + index).fadeIn('slow');
        });
    })
})
person zindel    schedule 06.04.2011

Лучше всего использовать http://api.jquery.com/toggle/.

Toggle позволяет вам анимацию для одного

$('#clickme').click(function() {
  $('#book').toggle('slow', function() {
    // Animation complete.
  });
});

Что касается истинного сокращения кода, я бы использовал идентификатор класса для ваших панелей.

Определите группы панелей, такие как

$("#panel3").fadeOut("slow", function() {
$("#panel4").fadeOut("slow", function() {                       
$("#panel5").fadeOut("slow", function() {
$("#panel6").fadeOut("slow", function() {

а затем назначьте связанные элементы HTML классом, например

Ваш jQuery теперь может быть $(".panelGroup1").fadeOut...

. селектор класса для jQuery, а # — это селектор идентификатора.

Проверьте селекторы, и вы сможете делать кучу других сумасшедших вещей

http://api.jquery.com/?ns0=1&s=Selector&go=

person PaulSCoder    schedule 06.04.2011
comment
Спасибо, Пол. Я проверю это. Что касается js, я действительно нуб, и мне нужно многому научиться. Отсюда огромный код выше. :о) - person Mike Turbutt; 07.04.2011
comment
Я только что прошел через все это в прошлом году. Такие места, как переполнение стека, спасли меня от многочасового просмотра сайта jquery api. - person PaulSCoder; 07.04.2011
comment
Я до сих пор нахожу удивительным великодушие таких людей, как вы, с вашим временем и знаниями. Спасибо миллион за предложение вашей помощи. Я много учусь. Ваше здоровье, - person Mike Turbutt; 08.04.2011

Много хороших решений, у меня есть общий комментарий:

Кажется немного ненужным, чтобы каждая панель имела уникальный идентификатор. У вас может быть веская причина для этого, но разве недостаточно сгруппировать панели с помощью селектора классов? Это сделало бы ваш общий код, а также ваш jquery, намного проще и легче в обслуживании.

person Frederik Wordenskjold    schedule 06.04.2011
comment
Каждая панель имеет уникальный фон, вызываемый в CSS в соответствии с содержимым этой панели. Это единственная причина на самом деле. - person Mike Turbutt; 07.04.2011

Вы можете сделать что-то вроде

function fadeElementIn(fadedElement) {
    $("[id^=panel]").fadeOut("slow");
    $(fadedElement).fadeIn("slow");
}

А потом:

$(document).ready(function(){

    $("#link1").click(fadeElementIn($("#panel1")));
    $("#link2").click(fadeElementIn($("#panel2")));
    $("#link3").click(fadeElementIn($("#panel3")));
    $("#link4").click(fadeElementIn($("#panel4")));
}

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

ваше здоровье

person jcane86    schedule 06.04.2011
comment
Спасибо, я попробую это. Зачем нужно корректировать позиционирование? Могу ли я добавить вторую часть функции в качестве обратного вызова? Таким образом, элемент fadedOut будет отображать: none в CSS до того, как появится элемент fadedIn. Или я что-то упускаю? - person Mike Turbutt; 07.04.2011
comment
о, да, вы, конечно, можете это сделать, я просто представил, как это как бы трансформируется из одного в другое (то есть старый исчезает, а новый появляется поверх него). Но да, вы вполне можете это сделать. - person jcane86; 07.04.2011
comment
Я наконец-то в порядке. Спасибо миллион за ваше время и опыт. Этот сайт (и вы, ребята) потрясающие. Хотел бы я, чтобы парень, который чинит мою машину, был таким же щедрым. :о) Ура - person Mike Turbutt; 08.04.2011

person    schedule
comment
Это приведет к исчезновению всех панелей одновременно, а не по порядку, как в исходном коде. Вы можете использовать рекурсивную функцию или плагин fxQueues: plugins.jquery.com/project/fxqueues. - person user120242; 06.04.2011
comment
@user120242 user120242: если я использую each(), то. - person Gaurav; 06.04.2011
comment
Это все равно не будет. Очереди присоединяются div. Кроме того, это выдает ошибку. - person user120242; 06.04.2011
comment
Перечитав ОП, я понял, что ОП, вероятно, на самом деле не предназначался для их последовательного исчезновения. Кажется, он мог сделать это непреднамеренно. - person user120242; 07.04.2011
comment
Все это было совершенно непреднамеренно. Я просто использовал то, что (с моими ограниченными знаниями) работало нормально. Нет необходимости в последовательном исчезновении, просто хочу, чтобы все div были закрыты, кроме того, для которого я щелкнул ссылку. - person Mike Turbutt; 07.04.2011
comment
Извиняюсь за это, ребята, но мои ссылки вообще не работают, используя приведенный выше код, и я получаю синтаксическую ошибку в строке 5. Мои ссылки простые href=# с идентификаторами от link1 до link6. Должен ли я делать что-то другое? Мне нравится простота приведенного выше кода, и, исходя из моего ограниченного понимания, он имеет смысл. - person Mike Turbutt; 07.04.2011
comment
@Mike Turbutt: пожалуйста, проверьте сейчас - person Gaurav; 07.04.2011
comment
Спасибо, Гаурав, этот код теперь работает, но он только затемняет div, который в данный момент отображается: блок (в данном случае id=panel1 при загрузке страницы). Он не исчезает в скрытом div из соответствующей выбранной ссылки. Если это поможет увидеть это, у меня есть страница на тестовом сервере www.miketest.tk Еще раз спасибо. - person Mike Turbutt; 07.04.2011
comment
Это действительно работает, Гаурав, и это так просто. Есть одна небольшая проблема (которую, вероятно, можно исправить с задержкой или чем-то еще), но div не исчезает до того, как появится новый div. Таким образом, он смещается до тех пор, пока другой не исчезнет. Могу ли я добавить строку 5 в качестве обратного вызова в строке 4, чтобы она не выполнялась до завершения? Блин, кажется, я знаю, о чем говорю! :о) - person Mike Turbutt; 07.04.2011
comment
Сортировка! Просто хотел сказать большое спасибо всем, кто прокомментировал и пытался мне помочь. То, что вы, ребята, делаете, и то, как вы это делаете, удивительно и вдохновляет. Надеюсь, что смогу быть кому-то полезен в будущем. Майк - person Mike Turbutt; 07.04.2011