У меня есть 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>
). Затем я хочу, чтобы строка .slide выскользнула из поля зрения, когда мышь оставляет одну из строк в тегах <tbody>
. Мне удалось сделать это успешно с помощью следующего кода.
<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>
к следующему эффекты в то же время, кажется, что строка заголовка между ними движется вверх (надеюсь, это имеет какой-то смысл). Я пробовал несколько способов сделать это, но безуспешно. Мои лучшие усилия заключаются в следующем:
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 - не моя сильная сторона, как вы можете сказать.