引导有状态按钮未按预期工作

Bootstrap stateful button not working as expected

本文关键字:工作 按钮 状态      更新时间:2023-09-26

我正在尝试让我的引导按钮显示"正在加载..."同时执行一些耗时的功能(从外部源获取数据)。有趣的是,使用 setTimeout 的参考实现效果很好。

在我看来,不知何故,$(button).button('loading')命令仅在函数关闭后执行,并且 setTimeout 通过在后台等待来解决这个问题。如何使用实际执行某些操作的代码复制 setTimeout 命令的结果?

Jsfiddle演示我的问题。

这是我的HTML代码:

<button type="button" class="btn btn-warning" id="comb" data-loading-text="Loading..." autocomplete="off" onclick="comb()">Combinations</button>
<button class="btn btn-primary" id="timer" data-loading-text="Loading..." autocomplete="off" onclick="timer()">Set Timeout</button>

这里是JavaScript:

function combinations(str) {
    var fn = function (active, rest, a) {
        if (!active && !rest) return;
        if (!rest) {
            a.push(active);
        } else {
            fn(active + rest[0], rest.slice(1), a);
            fn(active, rest.slice(1), a);
        }
        return a;
    }
    return fn("", str, []);
}
function comb() {
    var btn = $('#comb').button('loading');
    console.log(combinations('abcdefghijklmnopqrs'));//this is a function that takes a lot of time (~5s) to execute
    btn.button('reset');
}
function timer() {
    var btn = $('#timer').button('loading');
    setTimeout(function () {
        btn.button('reset');
    }, 3000);
}

我找到了一个有效的解决方案,这是一个黑客。我仍然希望有更好的建议和/或解释正在发生的事情。

这是 HTML:

<button type="button" class="btn btn-warning" id="comb" data-loading-text="Loading..." autocomplete="off" onclick="comb()">Combinations</button>

这里是工作 JavaScript(基本上我将我的代码包装在一个超时非常短的 setTimeout 命令中:

function combinations(str) {
    var fn = function (active, rest, a) {
        if (!active && !rest) return;
        if (!rest) {
            a.push(active);
        } else {
            fn(active + rest[0], rest.slice(1), a);
            fn(active, rest.slice(1), a);
        }
        return a;
    }
    return fn("", str, []);
}
function comb() {
    var btn = $('#comb').button('loading');
    setTimeout(function () {
        console.log(combinations('abcdefghijklmnopqrs'));
        btn.button('reset');
    },100);
}

在我看来,我正在执行的代码阻止引导 JavaScript(或 jQuery)更改按钮状态,直到它完成。setTimeout 命令现在让引导 javascript 有时间在我的代码执行之前更改按钮状态。我仍然觉得这很奇怪,并希望得到解释。

编辑:

这是一个演示解决方案的 jsfiddle

Edit2:我意识到 100 毫秒的超时比 10 毫秒更安全,因为一些速度较慢的设备/浏览器可能无法在 10 毫秒内重建页面。我相应地更新了代码/jsfiddle。

编辑3:在Bootstrap Github问题跟踪器的peterblazejevicz的帮助下,我发现了这个优雅的解决方案,使用了一个承诺:

function comb() {
    var btn = $('#promise').button('loading');
    var request = $.ajax('/');
    request.done(function (data) {
        console.log(combinations('abcdefghijklmnopqrs'));
    });
    request.always(function () {
        btn.button('reset');
    });
}

这是演示解决方案的更新和最终的jsfiddle