我使用一个函数来加载一个带有jQuery的页面,但只是在将鼠标悬停在li
之后的一段时间之后。为此,我在setTimeout
上使用mouseover
,如果鼠标在mouseleave
上徘徊不到500毫秒,请尝试在li
上将其删除。但是,jQuery.ajax
仍会启动,所以基本上,如果我将鼠标悬停在所有li
上,即使我只在li
停留1毫秒,也会启动大量的xhr。
var timer2;
var delay2 = 500;
$('body').on('mouseover','li',function(){
timer2 = setTimeout(function() {
var url="res.php";
jQuery.ajax(
{
type: 'POST',
url:url,
success: function(data){
$('#res').html(data);
}
});
}, delay2);
});
$('body').on('mouseleave', 'li', function() {
clearTimeout(timer2);
});
答案 0 :(得分:3)
在再次设置之前,请先清除超时时间:
var timer2 = null;
$('body').on('mouseover','li',function(){
clearTimeout(timer2);
timer2 = setTimeout(function(){ .....
您需要将超时初始化为null
,否则您将收到错误can't clear timeout of undefined
。
另外,试试这个来触发mouseleave:
$('body').on('mouseover','li',function(){
// ...
$(this).off("mouseleave").on("mouseleave", () => clearTimeout(timer2))
});
修改:工作代码段
var timer2 = null;
var delay2 = 2000;
$('body').on('mouseover', 'li', function() {
clearTimeout(timer2);
console.log("Setting timeout...")
timer2 = setTimeout(() => console.log("Ajax call!"), delay2);
$(this).off("mouseleave").on('mouseleave', () => {
console.log("Clearing timeout.")
clearTimeout(timer2);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>Hover over me</li>
<li>Over me too</li>
答案 1 :(得分:3)
这里的问题很简单。您使用鼠标悬停,当您在元素上时,鼠标悬停可以触发多个setTimeouts。
$("div")
.on("mouseover", function(){ console.log("mouseover"); })
.on("mouseenter", function(){ console.log("mouseenter"); });
span { background-color: red;
font-size: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span>Move mouse here</span> to <span>here</span> to <span>here</span></div>
因此,每次移动父级内部的元素时,都会触发另一次鼠标悬停。因此,如果是这种情况,您将创建多个事件。因此,如果您看到多个ajax调用li,那可能就是原因。
因此将其更改为mouseenter,接下来取消输入中的事件或通过li本身跟踪事件而不是全局。
$("ul")
.on("mouseenter", "li" function(){
$(this).data("timer", setTimeout( function () {});
}).on("mouseleave", "li" function(){
var id = $(this).data("timer");
if (id) window.clearTimeout(id);
})
如果你真的想确定,请清除mouseenter上的超时....
答案 2 :(得分:-1)
为该特定id
提供li
,并使用如下方式。这有效。查看console
Networks
标签进行验证。
var timer2;
var delay2 = 500;
var ajax;
$('body').on('mouseover','li#one',function(){
console.log("Mouse over");
clearTimeout(timer2);
timer2 = setTimeout(function() {
if(ajax) {ajax.abort();}
var url="res.php";
ajax = $.ajax(
{
type: 'POST',
url:url,
async:true,
success: function(data){
$('#res').html(data);
}
});
}, delay2);
});
$('body').on('mouseleave', 'li#one', function() {
console.log("Mouse left");
clearTimeout(timer2);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li id="one">One</li>
<li>Two</li>
答案 3 :(得分:-1)
解决此问题的方法很少
abort
之后mouseleave
您的请求
abort
您的请求// ...
var request;
$('body').on('mouseover','li',function(){
// ... I omited `setTimeout` to simplify the explanation
// you have to make this variable to be able to control your requests
var xhr = new window.XMLHttpRequest();
// here we save our request
request = jQuery.ajax(
{
// ...
// note this change here, it is required for jquery 3.0 and more
xhr : function(){ return xor; }
});
// ...
});
$('body').on('mouseleave', 'li', function() {
// ...
// now we can `abort` it any time user mouse leaves
request.abort();
});
// ...
var leaved = false
$('body').on('mouseover','li',function(){
// ... I omited `setTimeout` to simplify the explanation
leaved = false
jQuery.ajax(
{
// ...
success: function(data){
if (leaved) return;
$('#res').html(data);
}
});
// ...
});
$('body').on('mouseleave', 'li', function() {
// ...
leaved = true
});