Bootstrap 点击后打开下拉菜单,直到 运行 功能完成

Bootstrap dropdown menu open after click until long running function completes

我有一个功能良好的 Bootstrap 下拉菜单,但是当从列表中选择一个项目时,调用一个函数需要长达 30 秒的时间。下拉菜单保持打开状态,直到函数完成并且 OnClick 事件退出。

<div class="container">
<div class="form-group">
<div class="col-xs-10">
  <div id="ddColor" class="dropdown">
    <h3 class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
                                <span id="ddColorChoice">Select Color</span>
                                <span class="caret"></span>
                            </h3>
    <ul class="dropdown-menu">
      <li><a href="#">Red</a></li>
      <li><a href="#">Green</a></li>
      <li><a href="#">Yellow</a></li>
      <li><a href="#">Blue</a></li>
    </ul>
  </div>
</div>

$("#ddColor").on("click", "li a ", function() {
  value = $(this).text();
  $("#ddColorChoice").text(value);
  SomeLongProcess(2000);
});


function SomeLongProcess(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds) {
      break;
    }
  }
}

有什么方法可以"close"点击下拉然后处理功能吗?

这是一个demo

谢谢!

我会使用 promises 和 deferreds 来处理一个漫长的 运行ning 过程。这样长的 运行ning 进程将 运行 异步,并且不会阻止浏览器响应。

具体来说,我会创建一个 deferred 作为我的 "container" 长 运行ning 进程。

var def = $.Deferred();

在延迟的完成事件中,我会调用长 运行ning 过程。在本例中,我还执行了一些其他操作:

def.done(function() {
    var t = p.html() + "<br/>def resolved, calling long running process";
    p.html(t);
    console.log("def done");
    LongRunningProcess(3000);
});

在点击事件中,我将解决我用来管理长 运行ning 事件的延迟。因为没有动作可做,"done"函数会立即执行,调用漫长的运行ning过程。

$(document).on("click", "li a ", function() {
    value = $(this).text();
    el.text(value);
    def.resolve();
});

You can find out more about promises here.

我用一个简单的 setTimeout 函数代替了一个例子。

function LongRunningProcess(ms) {
    var deferred = $.Deferred();
    setTimeout(function() {
        var t = p.html() + "<br/>long running process done";
        p.html(t);
        console.log("long running process done");
        deferred.resolve;
    }, ms);
    return deferred.promise();
}

Here is a link to the complete fiddle.