views:

17

answers:

1

Hi,

I have this code somewhere in my plugin:

$('tr', $this).hover(function(){
  var cur_color = null;
  cur_color = $this.css('background-color');
$this.css('background-color', options.tr_hover_bgcolor);
}, function(){
  $this.css('background-color', cur_color);
});

Above, $this refers to wrapped set or table as an example. The code is supposed to change the rows background color on mouse enter and mouse leave. It does not work when used inside the plugin. Outside the plugin the similar code just works fine. Also that is the only part of the code not working in the plugin, rest of the things are working fine.

This code works which is not a plugin:

$('#' + table_id + ' tr').hover(function(){
  cur_color = $(this).css('background-color');
  $(this).css('background-color', '#FFF3B3');
}, function(){
  $(this).css('background-color', cur_color);
});

Can you please point out why above code doesn't work in the plugin?

Thanks

+3  A: 

This part:

$('tr', $this).hover(function(){
  var cur_color = null;
  cur_color = $this.css('background-color');
  $this.css('background-color', options.tr_hover_bgcolor);
}, function(){
  $this.css('background-color', cur_color);
});

Should be something like this:

$('tr', $this).hover(function() {
  $.data(this, 'bgColor', $(this).css('background-color'));
  $(this).css('background-color', options.tr_hover_bgcolor);
}, function() {
  $(this).css('background-color', $.data(this, 'bgColor'));
});

So you're changing the background of the hovered row, instead of the whole table. The version that works is currently relying on a global variable...where as the plugin version was out of scope. This approach instead stores it per-row using $.data().


Unless you need to support IE6 though (or need this to be dynamic), you can do something like this in CSS:

.hoverTable tr:hover { background-color: #EEEEEE; }

Not sure if it's an option, just something to be aware of.


Also, take a look at the .delegate() way, which is much faster to bind if you have many rows:

$($this).delegate('tr', 'mouseeneter', function() {
   $.data(this, 'bgColor', $(this).css('background-color'));
   $(this).css('background-color', options.tr_hover_bgcolor);
}).delegate('tr', 'mouseleave', function() {
   $(this).css('background-color', $.data(this, 'bgColor'));
});

This attaches a single handler to each table, instead of each row in each table, and listens for the events to bubble. If you have many rows, this is much faster to bind, resulting in better page load time.

Nick Craver
Thanks it works :) What is $.data, what does it do?
@user429381 - [`$.data()` ](http://api.jquery.com/jQuery.data/) stores and gets data associated with the DOM element you're dealing with, via a cache mechanism jQuery uses, it's just a handy way to store things :) Also you may want to look at [`.delegate()`](http://api.jquery.com/delegate/) here, binding to the table once instead of a `mouseenter`/`mouseleave` handler for every row :)
Nick Craver
@user429381 - I added how delegate would look, it'll greatly improve performance on pages with a large number of rows.
Nick Craver