[英]How do I make this jquery animation delay work properly?
我有一個html表,我正在嘗試用jQuery添加一些動畫。 我非常接近我想要的,但是有一個未解決的問題。 我將嘗試描述我正在做的事情,盡可能縮小表和腳本的版本。
該表定義如下:
<table>
<tbody class="group">
<tr>First</tr>
<tr class='slide'><div class='hidden'>Surprise!</div></tr>
</tbody>
<tbody class="group">
<tr>Second</tr>
<tr class='slide'><div class='hidden'>Surprise!</div></tr>
</tbody>
<tbody class="group">
<tr>Third</tr>
<tr class='slide'><div class='hidden'>Surprise!</div></tr>
</tbody>
</table>
我想要的效果是,一旦頁面加載后,所有<tr class='slide'>
行都將被隱藏,然后在鼠標指針進入上面的行時將slideDown放到視圖中。 我希望.slide行能夠保留在視圖中,只要鼠標指針保持在上方行或.slide行(包含在<tbody>
標記內)中即可。 然后,當鼠標離開<tbody>
標記內的任一行時,我希望.slide行能夠滑出視圖。 我已經成功地通過以下代碼成功做到了這一點。
<script>
$(function() {
hideRows();
setupEventHandlers();
});
function hideRows() {
$("div.hidden").each(function() {
$(this).hide();
});
};
//The hideRows function is much more complicated in my actual page
//as I have to calculate the div height prior to hiding so it animates
//correctly. That's why I don't just set display:none; in the stylesheet.
function setupEventHandlers() {
$('.group').mouseenter(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
$(this).slideDown();
});
});
$('.group').mouseleave(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
$(this).slideUp();
});
});
};
//note that I have to animate the div rather than the tr
//as slidedown and slideup don't work on table rows
</script>
盡管這樣做有效,但存在一個問題,如果您將鼠標移到多行上,則會設置一個巨大的亂七八糟的混亂狀態,這種混亂狀態可以持續很長時間,直到所有動畫結束。 我想要做的是添加一個超時,這樣動畫在進入<tbody>
之后不會開始一秒鍾左右。 如果在觸發動畫之前鼠標離開<tbody>
,則應將其取消。 當鼠標指針離開<tbody>
,slideUp效果也應延遲相同的量-我的最后一個要求是,如果您從一個<tbody>
向下移動到下一個<tbody>
,則會在第二個位置出現slideDown和slideUp效果。同時看起來它們之間的標題行正在向上移動(我希望這有一定道理)。 我嘗試了幾種方法來完成此操作,但未成功。 我最大的努力如下。
var timer;
function setupEventHandlers() {
$('.group').mouseenter(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
div = $(this);
timer = setTimeout("div.slideDown();",1000);
});
});
$('.group').mouseleave(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
clearTimeout(timer);
div = $(this);
setTimeout("div.slideUp();",1000);
});
});
};
這幾乎可行。 如果我快速輸入然后離開一行,則不會發生動畫。 如果我輸入一行並等待1秒鍾,則下一行會按計划向下滑動。 如果我然后將行退到一側,則隱藏的行將按計划在1秒后向上滑動。 但是,如果我在下面輸入該行,則會出錯。 1秒鍾后,新行會按預期滑入視圖,但舊行仍然存在。 我的假設是我的計時器變量被無意中破壞了。 我嘗試通過使用一組計時器並為每一行分配一個特定的計時器來對過程進行更具體的說明,但這沒有什么區別。 如您所知,JavaScript不是我的強項。
嘗試使用hoverIntent插件,而不是試圖模仿“延遲懸停”用mouseenter
和mouseleave
。 我幾乎總是使用hoverIntent而不是普通的hover。
好的,我終於解決了這個問題(並學到了很多東西)。
如果我在代碼的mouseleave部分中將div替換為div2,則提供的代碼有效。 向上和向下使用相同的變量名將導致動畫不發生。 唯一的問題是,如果我將鼠標快速移到許多行上,由於這個變量名被過度使用和濫用,我仍然會得到意想不到的結果。
我的解決方案是為每個.slide行提供唯一的ID,如下所示;
<tr class='slide'><div class='hidden'>Surprise!</div></tr>
然后,我使用此id使用eval生成動態變量名稱,並在setTimeout中的字符串中引用它。 我的最終代碼如下所示。
var timer;
function setupEventHandlers() {
$('.group').mouseenter(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
id = this.id;
eval("divdown_" + id + " = $(this);");
downstring = "divdown_" + id + ".slideDown();";
timer = setTimeout(downstring,1000);
});
});
$('.group').mouseleave(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
clearTimeout(timer);
id = this.id;
eval("divup_" + id + " = $(this);");
upstring = "divup_" + id + ".slideUp();";
setTimeout(upstring,1000);
});
});
};
而且效果很好(至少在Firefox中,我太害怕嘗試IE了-我要去體育館了)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.