Reputation: 583
I'm messing around with some jQuery stuff for a mockup and noticed some odd behavior. I'm hoping someone here can shed some light on it.
This is all mockup / test code, so please excuse the sloppyness.
So I have a table that I'm using in conjunction with the jQuery datatable plugin: http://www.datatables.net/
My table markup is as follows:
<table id="dexterIndex">
<thead>
<tr>
<th>Name</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
</tr>
</thead>
<tbody>
<tr>
<td>Test 1</td>
<td>Yes</td>
<td>2009-2010</td>
<td>Fall 2010</td>
<td>Fall 2010</td>
</tr>
<tr>
<td>Test 2</td>
<td>No</td>
<td>2009-2010</td>
<td>Fall 2010</td>
<td>Fall 2010</td>
</tr>
<tr>
<td>Test 3</td>
<td>Yes</td>
<td>2009-2010</td>
<td>Fall 2010</td>
<td>Fall 2010</td>
</tr>
<tr>
<td>Test 4</td>
<td>No</td>
<td>2009-2010</td>
<td>Fall 2010</td>
<td>Fall 2010</td>
</tr>
<tr>
<td>Test 5</td>
<td>No</td>
<td>2009-2010</td>
<td>Fall 2010</td>
<td>Fall 2010</td>
</tr>
<tr>
<td>Test 6</td>
<td>No</td>
<td>2009-2010</td>
<td>Fall 2010</td>
<td>Fall 2010</td>
</tr>
<tr>
<td>Test 7</td>
<td>Yes</td>
<td>2008-2009</td>
<td>Fall 2009</td>
<td>Fall 2009</td>
</tr>
</tbody>
</table>
Now, the functionality I'm going for is: On hover change the row background color If hovering for more than 'x' seconds slide down a sub-row for the row being hovered over.
Here is a screenshot of the effect working correctly (generally):
Upon leaving the row with one's mouse the sub-row slides back up.
This all works, but it seems that each time it slides back up it falls short by about a pixel. Here is an image after hovering/un-hovering 10 times. This is the table in the state after the sub-row slides up (meaning it's not just the sub-row showing with no text).
If I change slideUp/slideDown to fadeIn/fadeOut everything works fine and I don't get extra pixels. (I'll probably end up just using the fades, but i'm curious about this behavior).
This is what safari is reporting about the DOM in the bugged state (also, why can't I copy/paste in the Safari Web Inspector?):
And finally, here is some sloppy jQuery that handles the actual moving parts:
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$('#dexterIndex').dataTable()
$('#dexterIndex tbody tr')
.hover(function() {
var table_row = this
table_row.hovering = true
window.setTimeout(function() {
if (table_row.hovering) {
$('.school-info').slideUp('fast', function() {
$(this).remove()
})
table_row.hovering = false
var tr = $('<tr />').attr({'class': 'school-info',})
$(table_row).after(tr)
$('<td />')
.attr({
'colspan': 5
})
.css({
'display': 'none'
})
.text("Sub Row")
.appendTo(tr)
.slideDown('fast')
}
}, 2000)
$(this).children().each(function() {
(this.oldColor === undefined)? this.oldColor = $(this).css('background-color'): null;
$(this).css({'background-color': '#f3ffc0'})
})
},
function() {
this.hovering = false
$('.school-info').slideUp('fast', function() {
$(this).remove()
})
$(this).children().each(function() {
$(this).css({'background-color': this.oldColor})
})
})
})
TL;DR: slideUp slides up one pixel less each time, fadeOut doesn't have any issues.
If anyone can shed some light on this issue it'd be greatly appreciated.
Upvotes: 1
Views: 2102
Reputation: 37055
Couple of questions/ideas:
It seems this technique is being used for UI/richness, meaning that the sub-rows aren't calculated when the user hovers nor does it get created from an ajax call, etc. But you aren't hiding and unhiding the data, but instead creating it on hover and then removing it afterward. This is potentially very inaccessible and adds extra overhead to the browser-script.
So I'd suggest having the table load with the actual sub-rows and having your jquery hide them during load. You could simply add a class like "sub_row" to those tables.
Second, is this only happening in Safari? Is it happening in Firefox? Either way, I would guess you are losing a pixel from the browser adding a default border. I don't know why this would keep adding that border on each slideup, but I'm sure someone else here can spot that.
Lastly, I'm unfamiliar with your selector syntax. you are selecting your td
s and tr
s as :
$('<tr />)
and $(')
instead of:
$('tr')
and
$('td')
Any reason why?
Upvotes: 2