javascript(jquery):延迟事件执行'事件气泡订单'直到ajax调用完成

时间:2013-01-02 18:02:11

标签: javascript-events sleep wait event-bubbling

编辑:响应关于在锚元素上执行点击事件programaticaly的评论,或者使用,window.open-由于弹出窗口阻止程序,我无法使用这些。 我必须允许用户在锚点上使用原始鼠标点击事件来完成其过程 - 从而产生一个未阻止的新窗口。

这里最好的妥协似乎是执行同步的ajax请求 - 并向用户提供一个spinner gif,直到请求完成。

编辑:小提琴http://jsfiddle.net/cXdJg/35/

考虑一个带有播放器页面链接的网页编辑器。

点击设置为播放器的href链接, 编辑器检查内容是否已保存到服务器:

如果是:不做任何事。

如果不是:执行ajax请求以保存内容。 在ajax调用结束时:允许anchor元素上的click事件继续;导致在新浏览器窗口中执行播放器页面请求。

如何在延迟ajax调用结束的情况下延迟拦截click元素上的click事件的函数结束,而不冻结浏览器? 见http://www.devcheater.com/#Conclusion

我检查了http://ajaxpatterns.org/Submission_Throttling,但是看不到我如何在这里应用这个例子。

代码形式的想法示例:

$('a.play').click(function){
    if(!isSaved){
          save();  //saves the content and **sets isSaved to true**
    }
     while (!isSaved){
          //burn time until isSaved,  but don't freeze the browser!
     }
     //allow the event handler to end, after which the click on anchor element will
     //  load the player page in new window.
}

6 个答案:

答案 0 :(得分:2)

我认为您发布的链接(http://www.devcheater.com/#Conclusion)指的是您在这里遇到的最大问题:您特别想要做的事情似乎不太可能。但是,您可以尝试这样的事情(从JSFiddle重用的代码):

此方法不允许click处理程序返回true,其想法是您将从success函数打开链接。这使用window.open,因此弹出窗口可能会被阻止,直到用户允许它为止。

$('.wait').click(function(event){
    var $element = $(this);

    $.ajax({
        type: "POST",
        url: 'some_url',
        data: '',
        cache: false,
        success: function() {
            $('.result').html("ajax call complete on "+ new Date().toTimeString());

            var href = $element.attr('href');

            if (typeof href != "undefined") {
                window.open(href);
            }                    
        }
    });

    event.preventDefault();
    return false;
});

答案 1 :(得分:1)

查看jQuery.ajax async选项。

$.ajax({
  url: '.....',
  async: false      //Here
});

答案 2 :(得分:1)

解决方案#1

您是否可以控制“播放器”代码?在打开播放器之前,不要等待数据保存,让播放器等待数据准备好。

你可以这样做:

当您点击链接并且 isSaved 为false时,立即启动AJAX async 调用以保存数据,让播放器在新窗口中打开。< / p>

播放器的链接将在(在URL上)一个参数,该参数将告知数据未就绪(正在保存)。播放器将开始查询服务器(每隔几秒钟一次异步ajax调用)以获取数据的“最后版本”。

当保存的数据准备就绪时,它将被提供给播放器。

一个重要的细节:当玩家向服务器询问数据时,最重要的是提供该数据的最新版本。

为确保这一点,您必须生成一个随机数字,以识别最新版本的数据。

保存数据时,将密钥与ajax调用一起传递。将其与将调用播放器的URL一起传递。同样,当查询保存的数据时,播放器会将密钥传递给服务器。

比实施更难解释!

解决方案#2

当用户进行更改时,禁用链接,开始保存,保存完成后再次启用链接。

点击链接 isSaved 将始终为真。

-

希望这会有所帮助..

答案 3 :(得分:1)

我认为你有几个选择:

  • 您可以查看jQuery队列方法,该方法允许您对功能块的执行进行排队以使它们同步。
  • 另一种方法可能是使用ajax完整处理程序中的jQuery.trigger()触发click事件。如果某些事件处理程序执行两次并不重要,那么这将是最简单的解决方案。
  • 最后,您可以使用$('[href tag event trigger]').data('events')从事件中提取所有事件处理程序,删除当前上下文中函数的事件处理程序,并在保存的ajax完整处理程序中调用其余事件。

http://api.jquery.com/queue/

http://api.jquery.com/trigger/

http://api.jquery.com/data/

答案 4 :(得分:1)

添加事件侦听器以进行单击并加载,并在代码中创建关联的事件处理程序。

// handles click
var handleClick = function(event){
var $element = $(this);

$.ajax({
    type: "POST",
    url: 'some_url',
    data: '',
    cache: false,
    async: false,
    success: function() {
        $('.result').trigger('loaded', $element.attr('href'));
    }
});

// Handles loaded state
var handleLoad = function(href){
    $(this).html('ajax call complete on '+ new Date().toTimeString());
    // your window is already loaded.
};

// create the event listeners
$(document).on('click', '.wait', handleClick);
$(document).on('loaded', '.result' handleLoad);

答案 5 :(得分:0)

while( !isSaved )
$.delay(100);