单击后,Bootstrap下拉菜单打开,直到长时间运行的功能完成

时间:2016-02-18 17:06:08

标签: twitter-bootstrap-3 dropdown

我有一个功能正常的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;
    }
  }
}

有没有办法“关闭”点击下拉列表然后处理该功能?

这是demo

谢谢!

1 个答案:

答案 0 :(得分:0)

我会使用promises和deferred来处理长时间运行的进程。这样,长时间运行的进程将异步运行,而不会阻止浏览器响应。

具体来说,我会创建一个延迟作为我的&#34;容器&#34;对于长期运行的过程。

var def = $.Deferred();

在延迟的完成事件中,我会调用长时间运行的进程。在这种情况下,我还要做其他几项行动:

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

在点击事件中,我会解决我用来管理长时间运行事件的延迟。因为没有行动要做,所以&#34;完成&#34;函数将立即执行,调用长时间运行的进程。

$(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