2010-11-08 2 views
2

У меня есть html-таблица, которую я пытаюсь добавить в анимацию с помощью jQuery. Я очень близок к тому, что хочу, но имею одну нерешенную проблему. Я попытаюсь описать то, что я делаю, с вырезанием версии таблицы и скриптов, насколько это возможно.Как сделать так, чтобы задержка анимации 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 row slideUp не отображалась, когда мышь покидает одну из строк в тегах <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> на другой, эффекты 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 не мой сильный костюм, как вы можете сказать.

+0

Я решил большую часть своей проблемы. Использование одной и той же переменной «div» было основной проблемой. Замена второго div на div2 фиксировала большинство проблем (небольшая проблема остается, когда мы быстро перебираем, что потребует динамических имен переменных - надеюсь, я скоро это разрешу). – brad

ответ

0

ОК, я, наконец, решил это (и многому научился).

Код в том виде, как это предусмотрено, работает, если я заменю div на div2 в части кода мыши. Использование одного и того же имени переменной для вверх и вниз привело к тому, что анимация не появилась. Единственная проблема заключается в том, что, если я быстро перейду к многочисленным строкам, я все равно получаю неожиданные результаты, так как это одно имя переменной становится злоупотребляемым и злоупотребляемым.

Мое решение состоит в том, чтобы обеспечить каждую строку .slide уникальным идентификатором;

<tr class='slide'><div class='hidden'>Surprise!</div></tr> 

я затем использовать этот идентификатор, чтобы генерировать динамическое имя переменного с помощью 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 еще - я иду в спортзал, а).

1

Попробуйте использовать плагин hoverIntent вместо того, чтобы пытаться имитировать «задержанный зависание» с помощью mouseenter и mouseleave. Я почти всегда использую hoverIntent вместо простого наведения.

+0

Спасибо. Я посмотрел на hoverintent, и он не совсем достиг того, чего я хочу. – brad

Смежные вопросы