Вопрос

У меня есть следующий фрагмент Jquery:

$("#collapse-menu > li > a").click(function() {
    $(this).toggleClass("expanded").toggleClass("collapsed").find("+ ul").slideToggle("medium");
});

Что он в основном делает, так это расширяет или сворачивает меню из вложенных "списков", которые содержат выпадающие списки (упрощенный пример):

<ul id="collapse-menu">
   <li><a class="expanded">Basic Details</a>
      <ul>
         <li>
            <select> .... </select>
         </li>
         <li>
            <select> .... </select>
         </li>

Код работает абсолютно нормально, ЗА ИСКЛЮЧЕНИЕМ случаев, когда в любом из выпадающих списков выбрано большое значение.В этот момент, при нажатии, меню по-прежнему будет корректно расширяться / сворачиваться, но при этом быстро "мигать", как будто весь элемент каким-то образом сбрасывался.Сами данные в порядке, но нежелательно мигание.

Странно то, что если в выпадающем списке выбрано небольшое значение, то оно не мигает.Когда выбрано большое значение (скажем, выше 30 в выпадающем списке возраст 18-99), начинает происходить мигание.

Кто-нибудь может сказать мне, почему это происходит?Или есть ли что-то неправильное в Jquery, что является причиной этого.

Спасибо.

Обновить:

Добавляя к этому вознаграждение.Попробовали несколько похожих плагинов / решений в сети, но все они, похоже, страдают от этой проблемы "мигания", когда по умолчанию выбраны большие выпадающие значения.

Если это поможет, вот типичное подобное решение: http://www.i-marco.nl/weblog/jquery-accordion-menu/index_collapsed.html# ...но он страдает от той же проблемы, когда выпадающие списки добавляются внутри аккордеона.

Я надеюсь, что у кого-то есть чистое решение, вместо того чтобы каким-то образом взламывать это.

Это было полезно?

Решение

По моим наблюдениям:Проблема, по-видимому, зависит от операционной системы.Выбранные элементы определяются системой, поскольку они являются системными элементами управления.На моем компьютере с Linux я не испытываю никаких проблем с мигающей анимацией в http://jsbin.com/ixake пример.Я ожидаю, что вы протестировали это на Windows (r)

Похоже, что выбор "прокручивается" до нужного значения каждый раз, когда он перерисовывается.И это часто происходит во время анимации.

Самым простым решением было бы заменить system selects на selects на основе html, чтобы удалить системную зависимость.Существуют ненавязчивые плагины jquery, которые сделают это за Вас.

Попробуй это или выберите любой из здесь если тот, первый, был не слишком хорош.

После этого Ваша анимация должна зависеть только от JS и стиля.

Другие советы

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

Ответом было бы сохранить каждый выделенный элемент в javascript (скажем, при изменении), затем, когда анимация начнется, отменить выбор значения, а затем восстановить его, когда анимация остановится.Это даст вам ту же производительность, что и при выборе небольшого значения, сохраняя при этом пользовательский выбор.

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

Лично я считаю, что автозаполнение действительно может быть правильным решением.Однако у меня была идея, что скрытие длинного выделения путем замены поддельного короткого сделает слайд более плавным.Кажется, работает лучше в одном браузере, который я тестировал (Firefox 3.0.18).Код, вероятно, можно было бы очистить, и есть ошибка, из-за которой иногда выбранные значения не совпадают по размерам по умолчанию из-за внутренних полос прокрутки, но подделать это не должно быть слишком сложно.

$("#collapse-menu > li > a").click(function() {
    var was_expanded = $(this).hasClass('expanded');
    var uls = $(this).toggleClass("expanded").toggleClass("collapsed").find('+ ul');
    if (was_expanded) {
        $(this).parent().find('select').each(function() {
            var fake = $('<select class="fake"><option>' + $(this).val() + '</option></select>');
            $(this).parent().append(fake);
            $(this).hide();
        })
        uls.slideUp('medium', function() { });
    } else {
        $('.fake').remove();
        $('select').show();
        uls.slideDown('medium', function() { });
     }
});

Что вы можете сделать, это отключить списки выбора перед анимацией ul.

        $("#collapse-menu > li > a").click(function() {
            $(this)
                .toggleClass("expanded").toggleClass("collapsed")
                .find("+ ul").find("select").attr("disabled","disabled").end()
                .slideToggle("medium",function(){
                    $(this).find("select").each(function(){this.disabled=false;});
                });
        });

попробуйте сделать это и отчитайтесь.

Вероятно, вы захотите изменить стиль (CSS) отключенных списков выбора, чтобы они выглядели идентично тем, которые не отключены.


Примечания

Вышесказанное имеет побочный эффект, заключающийся в том, что выбранные значения не отправляются при отправке формы.Если для вас это проблема, то я предлагаю вам либо удалить все параметры из списка выбора, за исключением выбранного варианта, перед анимацией, а затем добавить их все обратно, как только анимация будет завершена.И если у вас это не сработает, предложение naugtur использовать списки выбора в стиле HTML, вероятно, лучший вариант.

p.s.не утруждайте себя попытками использовать атрибут "только для чтения" при выборе list...it не существует.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top