Is there a cross-browser way to ignore opacity when using jquery's clone()?
-
19-09-2019 - |
Question
I'm using tables in my document, and I want to be able to have a user submit a new item to a list, then have it "automagically" appear at the top of the list (yes, this would be easier with DIVs but working with what I have).
I'm using jQuery, and clone()
to create a copy of the most recent table row, then using fadeIn()
to display the new item after I update and add it to the top of the list. Because internally jQuery converts elements (assuming DIVs) to 'block', I'm also changing the css class to 'table-row'. It works fine.
The whole code is here:
var row = $("tbody tr:first").clone().hide(); // clone and then set display:none
row.children("td[class=td-date]").html("today");
// set some properties
row.children("td[class=td-data]").html("data");
row.children("td[class=td-type]").html("type");
// fadeIn new row at the top of the table.
row.insertBefore("tbody tr:first").stop().fadeIn(2000).css("display","table-row");
The problem is that if I run the process too quickly - i.e. before the fadeIn completes, the "clone()" command ends up cloning the opacity as well.
I can actually get it to work in Firefox using by adjusting the first line above:
var row = $("tbody tr:first").clone().css("opacity","1").hide();
My concern now is that I'm not sure that any of this is being done efficiently, and/or that "opacity" is cross-browser safe to rely upon.
Has anyone done something like this before, and can offer any pointers on a more reliable approach?
Solution
opacity as a jQuery css attribute is safe cross-browser as it irons out the browser differences in the implementation. Here's the source
// IE uses filters for opacity
if ( !jQuery.support.opacity && name == "opacity" ) {
if ( set ) {
// IE has trouble with opacity if it does not have layout
// Force it by setting the zoom level
elem.zoom = 1;
// Set the alpha filter to set the opacity
elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
}
return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '': "";
}
The following works. Working Demo - add /edit to the URL to play with it.
// stop previous animation on the previous inserted element
var prevRow = $("tbody tr:first").stop(true,true);
var row = prevRow.clone();
row.children("td.td-date").text("today");
row.children("td.td-data").text("data");
row.children("td.td-type").text("type");
row.fadeIn(2000).prependTo("tbody");
OTHER TIPS
There is no reason to use hide on your clone. The clone isn't added to the dom yet so it can't be visible.
Try this:
var row = $("tbody tr:first").clone(); // clone
// set some properties
row.children("td[class=td-date]").html("today");
row.children("td[class=td-data]").html("data");
row.children("td[class=td-type]").html("type");
// fadeIn new row at the top of the table.
row.insertBefore("tbody tr:first").fadeOut(0).fadeIn(2000).css("display","table-row");
I think jQuery will handle it if you do this.
var row = $("tbody tr:first").clone().fadeIn(0).hide();