3

我有这个非常简单的 jQuery 函数:

$(".milestone-in-tree").live({
    mouseenter: function() {
        setTimeout(
        $.ajax({
            type: "GET",
            url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
        }),5000)
    },
    mouseleave: function() {
        $(".grid-btn").delay(800).remove();
    }
});

我想让它在将 AJAX 请求发送到服务器之前等待 5 秒,但它不会等待,它只是立即发送它。为什么?

更新:

感谢您的所有反馈。我更改了所有答案中建议的功能:

$(".milestone-in-tree").live({
    mouseenter: function() {
        var node = $(this).data("pmnode")
        setTimeout(function() {
        $.ajax({
            type: "GET",
            url:"/projects/pmnodes/" + node + "/addbuttons.js"
        }),5000});
    },
    mouseleave: function() {
        $(".grid-btn").delay(800).remove();
    }
});

但我仍然没有延迟。有什么我误解了吗?PS:我创建了 node 变量,因为我忽略了一个原因, $(this) 在 SetTimeout 匿名函数中不再可访问。

更新 2

最后,我可以设法得到延迟,但我意识到在延迟之后请求仍然发送到服务器,即使在两者之间触发了 mouseleave 事件......

我可以找到解决方法。这是完全不同的。延迟不再起作用,但是 ajax 请求在 mouseleave 事件中被中止,这是我真正需要的。对于那些可能感兴趣的人,这是代码:

var button_request;
$(".milestone-in-tree").live({
    mouseover: function() {
        var node = $(this).data("pmnode");
        button_request = $.ajax({
                        type: "GET",
                        url:"/projects/pmnodes/" + node + "/addbuttons.js"
                    });
        setTimeout(function() {button_request;},5000)
    },
    mouseleave: function() {
        if (button_request) {
            button_request.abort();
            button_request = null;
                }
        $(".grid-btn").remove();
    }
});

当然 setTimeout 可以删除(因为它不起作用......)但为了清楚起见,我将其保留。

谢谢大家。

4

7 回答 7

7

试试这个:

$(".milestone-in-tree").live({
    mouseenter: function() {
        var pmnode = $(this).data("pmnode"); // cache the data in a variable
        setTimeout( function() { // this function(){...} wrapper is necessary
            $.ajax({
                type: "GET",
                url:"/projects/pmnodes/" + pmnode + "/addbuttons.js"
            })
        },5000)
    },
...

调用的第一个参数setTimeout()需要是一个字符串(你真的,真的不应该这样做)或一个自包含的函数对象。

通过放在$.ajax(...)那里,你告诉 JavaScript (1) 立即运行它并 (2) 将第一个参数设置为ajax 函数返回的任何内容——根据文档,它是一个 jqXHR 对象,它setTimeout不能做任何事情和。

只要养成将匿名function(){...}作为第一个参数setTimeout()setInterval()每次使用它的习惯,就可以了。

于 2012-06-18T15:34:59.940 回答
6

setTimeout()要么接受它的 Javascript 代码字符串eval(非常不好的做法,我可以添加),要么接受它在指定时间后调用的函数引用。

您在这里所做的既不是 --- 您正在调用一个函数作为setTimeout(). 正因为如此,它不会等待。

你要:

setTimeout(function () {
    $.ajax({});
}, 5000);

这就像以下之间的区别:

setTimeout(foo, 1000);

setTimeout(foo(), 1000);
于 2012-06-18T15:36:00.023 回答
5

您正在调用该$.ajax()函数,并将该调用返回的任何内容传递给setTimeout(). 您需要将其包装在一个匿名函数中:

setTimeout(function() {
    $.ajax({
        type: "GET",
        url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
    })
},5000);
于 2012-06-18T15:35:14.397 回答
2

包装一个匿名函数:

setTimeout(function(){
        $.ajax({
            type: "GET",
            url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
        });
},5000)
于 2012-06-18T15:35:01.260 回答
2

你直接调用它,把它放在函数回调中:

   setTimeout( function() {
    $.ajax({
        type: "GET",
        url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
    })
   } ,5000)
于 2012-06-18T15:35:31.260 回答
1

您传入的代码实际上正在执行,如果您想在第一个参数中运行代码,您需要将其包装在一个函数中:

$(".milestone-in-tree").live({
    mouseenter: function() {
        setTimeout(
function(){
        $.ajax({
            type: "GET",
            url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
        }),5000);
}
    },
    mouseleave: function() {
        $(".grid-btn").delay(800).remove();
    }
});
于 2012-06-18T15:35:08.467 回答
1

它需要一个function()

setTimeout(function(){
        $.ajax({
        ...
}, 5000)
于 2012-06-18T15:35:20.423 回答