【问题标题】:Hide several divs and only after all are hidden, then run a callback function隐藏几个div,等全部隐藏后,再运行回调函数
【发布时间】:2016-10-08 03:15:07
【问题描述】:

我需要在容器 div 中隐藏 .panel 类的所有 div。然后毕竟都被隐藏了,选择性地取消隐藏一些 .panel div。我尝试在 hide() 上使用回调,但回调针对每个隐藏的元素运行。在某些情况下,我最终会陷入几乎无限或长时间运行的循环,因为相同的 div 被隐藏并一遍又一遍地显示。

这不起作用,因为在隐藏完成之前显示第二个元素:

$("#detailsPanel").children(".panel").hide();
$("#membershipPanel").slideDown();
$("#specializationsPanel").slideDown();

如果我将这些步骤嵌套在回调中的隐藏之后,则回调会针对每个隐藏的 .panel div 运行。


完整代码

这是我的全部功能,如果这有助于找到我的逻辑缺陷。

function goWizard(step) {
    switch (step) {
        case 0:
            $("#formPanel").hide();
            $("#beginPanel").slideDown();
            $("#instructionsPanel").slideDown().children().slideDown();
            $("#loginPanel").slideDown().children().slideDown();
            break;
        case 1:
            $("#beginPanel").hide().children().hide();
            $("#stepTitle").text("Membership Category/Specialist Category :: Step 1 of 8");
            $("html, body").animate({ scrollTop: 0 }, "slow");
            $("#summaryPanel").slideDown().children().show();
            $("#formPanel").slideDown();

            var i = 0;
            var $panels = $("#detailsPanel").children(".panel");
            $panels.hide(function () {
                i++;
                if (i == $panels.length) {
                    $("#membershipPanel").show();
                    $("#specializationsPanel").show();
                }
            });

            $("#startOverButton").show();
            $("#prevStepButton").hide();
            $("#nextStepButton").show();
            $("#startOverButton").click(function () { goWizard(0); });
            $("#nextStepButton").click(function () { goWizard(2); });
            break;
        case 2:
            $("#beginPanel").hide().children().hide();
            $("#stepTitle").text("Section Membership :: Step 2 of 8");
            $("html, body").animate({ scrollTop: 0 }, "slow");
            $("#summaryPanel").slideDown().children().show();
            $("#formPanel").slideDown();

            var i = 0;
            var $panels = $("#detailsPanel").children(".panel");
            $panels.hide(function () {
                i++;
                if (i == $panels.length) {
                    $("#sectionsPanel").show();
                }
            });

            $("#startOverButton").hide();
            $("#prevStepButton").show();
            $("#nextStepButton").show();
            $("#prevStepButton").click(function () { goWizard(1); });
            $("#nextStepButton").click(function () { goWizard(3); });
            break;
        case 3:
            $("#beginPanel").hide().children().hide();
            $("#stepTitle").text("Insurance Compliance :: Step 3 of 8");
            $("html, body").animate({ scrollTop: 0 }, "slow");
            $("#summaryPanel").slideDown().children().show();
            $("#formPanel").slideDown();

            var i = 0;
            var $panels = $("#detailsPanel").children(".panel");
            $panels.hide(function () {
                i++;
                if (i == $panels.length) {
                    $("#insurancePanel").show();
                }
            });

            $("#startOverButton").hide();
            $("#prevStepButton").show();
            $("#nextStepButton").show();
            $("#prevStepButton").click(function () { goWizard(2); });
            $("#nextStepButton").click(function () { goWizard(4); });
            break;
        default:
            $("#beginPanel").slideDown();
            $("#formPanel").hide();
            break;
    }
}

【问题讨论】:

  • hide().children().hide()and .slideDown().children().show(); 没有意义

标签: javascript jquery css


【解决方案1】:

我会使用承诺:

$.when(
    $("#detailsPanel").children(".panel").hide().promise(),
    $("#membershipPanel").slideDown().promise(),
    $("#specializationsPanel").slideDown().promise()
).done(function() {
    console.log('all done');
});

示例:https://jsfiddle.net/jjh65h2y/

【讨论】:

  • 我更喜欢您的解决方案。最初在我的示例中包含了 Promise,但没有像你的那样简洁,我也无法测试。 +1!
【解决方案2】:

您可以修改 hide 回调以检查被隐藏的元素是否是最后一个,然后在该部分执行回调,如下所示...

var i = 0;
var $panels = $("#detailsPanel").children(".panel");
$panels.hide(function() {

    i++;
    if(i == $panels.length) {
        $("#membershipPanel").slideDown();
        $("#specializationsPanel").slideDown();
    }

});

【讨论】:

  • 谢谢@guedes。已编辑:)
  • 这看起来会起作用并且有点起作用,但是当我在我的步骤中来回移动时(使用它作为基本的向导表单),仍然有问题。例如,membershipPanel 显示在第 1 步,转到第 2 步然后第 3 步,然后返回第 2 步,第 1 步的面板出现。
  • 我觉得您描述的问题与我提供的 sn-p 无关,听起来更像是您调用该方法的方式。上面的 sn-p 只是隐藏了所有面板,然后显示了专门针对的两个。鉴于您现在才提供全部范围,我不确定我是否仍会建议我的解决方案。
  • @ConnieDeCinko 我认为您的实际问题不适合您预期输出的真正需求,请尝试澄清....看到您的代码似乎您正在硬编码,可以简化为一个简单的没有所有这些 id 的函数
  • 好的,如果我在按钮上使用 unbind,然后将函数重新附加到 click 事件,现在,我的步骤代码只会在每次按下按钮时触发一次。哇!
【解决方案3】:

给定一个 DOM 结构,例如(示例):

<div class="panel">text</div>
<div class="panel unhide">text</div>
<div class="panel">text</div>
<div class="panel unhide">text</div>
<div class="panel">text</div>

您可以使用 jQuery 以 2 种方式隐藏和取消隐藏元素。

要么:

$.when($('.panel').animate({opacity: 0}, 500)).then(function () {
  $('.unhide').animate({opacity: 1}, 500);
});

或者:

$('.panel').animate({opacity: 0}, 500).promise().done(function () {
  $('.unhide').animate({opacity: 1}, 500);
});

https://jsfiddle.net/q2mctsz6/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多