在Jquery下拉菜单中不受欢迎的“闪烁”?

时间:2010-03-26 21:34:34

标签: javascript jquery drop-down-menu toggle slide

我有以下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>

在任何下拉列表中选择较大的值时,代码都可以正常工作。此时,单击时,菜单仍将正确展开/折叠,但在执行此操作时会快速“闪烁”,就像整个元素以某种方式重置一样。数据本身很好,但闪光是不需要的。

奇怪的是,如果在下拉列表中选择了一个小值,则表示没有闪烁。当选择一个较大的值(例如,在18-99岁的年龄下拉列表中超过30)时,闪烁开始发生。

谁能告诉我为什么会这样?或者Jquery是否存在导致这种情况的不正确的事情。

感谢。

更新

为此添加赏金。在网上尝试了一些类似的插件/解决方案,但是当默认选择大的下拉列值时,它们似乎都会遇到这种“闪烁”问题。

如果有帮助,这是一个典型的类似解决方案:http://www.i-marco.nl/weblog/jquery-accordion-menu/index_collapsed.html# ...但是当在手风琴中添加下拉列表时,它会遇到同样的问题。

我希望有人有一个干净的解决方案,而不是需要以某种方式破解它。

4 个答案:

答案 0 :(得分:3)

从我的观察:问题似乎依赖于操作系统。选择由系统绘制,因为它们是系统控件。在我的Linux机器上,我在http://jsbin.com/ixake示例中没有遇到闪烁动画的问题。我希望你在Windows上测试它(r)

看起来每次重新绘制时,select都会“滚动”到正确的值。动画时会发生很多事情。

最简单的解决方案是用基于html的选择替换系统选择来删除系统依赖性。有一些不显眼的jquery插件可以为你做。

尝试 this 或从 here 中选择任何一个,如果第一个不太好。

之后你的动画应该只依赖于JS和样式。

答案 1 :(得分:2)

我认为问题是每次调整元素大小时,下拉列表会滚动到所选元素,这会导致闪烁。

答案是在javascript中保存每个选择(在更改说),然后当动画开始取消选择值,然后在动画停止时恢复它。这将为您提供与选择较小值时相同的性能,同时保留用户的选择。

您可能还希望确保表单在处于过渡阶段时无法提交,否则您将收到错误的值。

答案 2 :(得分:1)

我个人认为自动完成可能真的是要走的路。但是,我认为通过替换假的短选项来隐藏长选项会使幻灯片变得更加平滑。似乎在我测试的一个浏览器上工作得更好(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() { });
     }
});

答案 3 :(得分:1)

您可以执行的操作是在为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。不要试图在选择列表上使用readonly属性......它不存在。