views:

43

answers:

2

Hi,

I'm trying to create an effect where if the user hovers the mouse over one of my li items, I show a few buttons that were hidden in the non-hovered state. Same kind of thing youtube is doing when you hover your mouse over comments. I'm trying this:

var gButtons = $(generateButtons());

function generateButtons() {
    var html = "<span>Btn1</span><span>Btn2</span>";
    return html;
}

$('#myList').delegate('li', 'hover', function(event) {
    if (event.type == 'mouseover') {
        var element = $(this);
        gButtons.appendTo(element.children('.panelButtons'));
    } else {
        gButtons.remove();
    }
});

<ul id='myList'>
  <li>
    <p>blah a</p>
    <p class='panelButtons'></p>
  <li>
  <li>
    <p>blah b</p>
    <p class='panelButtons'></p>
  <li>
  ...
</ul>

ok so my idea was that I create the gButtons element once at startup. Each li element gets an empty panel with class type 'panelButtons'. Whenever the user hovers over an li element, I just append it to the currently hovered element's empty 'panelButton' section.

I'm not sure if this will work because the order of messages [un-hover, hover] has to be consistent. I wanted to avoid generating the button markup for every single li item at page load, since I may have a large number of elements - it'd just be a lot of extra content.

Is this an ok way to go about it, any more optimal pattern?

Thank you

A: 

I'd just do something simple, with something along the lines of:

  <a href="vote" onmouseover="$('reg').show();">Vote Up</a><br />
  <div id="reg" style="display:none">Login or Register to vote</div>

You'll need some code to delay the onmouseout, and cancel the hiding of the reg div if you hover over reg, etc.

Derrick
+1  A: 

Unless there's some specific reason why you want to append and remove on each mouseover/mouseout event, I guess I'd do like Derrick suggested, except that I'd have jQuery handle the events for you.

Like this: http://jsfiddle.net/dFFqZ/

$('#myList').delegate('li', 'hover', function(event) {
    var element = $(this);
    if (event.type == 'mouseover') {
        element.children('.panelButtons').show();
    } else {
        element.children('.panelButtons').hide();
    }
}).find('.panelButtons')
    .append("<span>Btn1</span><span>Btn2</span>").hide();​

It will be much more efficient to do it this way.

You could even simplify your code down to this: http://jsfiddle.net/dFFqZ/1/

$('#myList').delegate('li', 'hover', function(event) {
    $(this).children('.panelButtons').toggle( event.type == 'mouseover' );
})
    .find('.panelButtons')
    .append("<span>Btn1</span><span>Btn2</span>").hide();​

EDIT: Added event.type == 'mouseover' to .toggle() as noted by @Nick Craver.

patrick dw
+1 - Don't forget about `.toggle(bool)` in these situations as well though, it can cut down on a good deal of code: http://jsfiddle.net/nick_craver/dFFqZ/2/
Nick Craver
@Nick - +1 I like that idea. I get a little worried in a situation like this that maybe an event will get missed, and the toggle will end up being inverted. The `boolean` adds a nice safeguard... or does it? I assume it remembers what the first action was.
patrick dw
@patrick - The boolean is literally just a `elem[bool ? 'show' : 'hide']()`, so it's nothing complicated/tricky, just a way to quickly reduce a `.show()`/`.hide()` combo :)
Nick Craver
Thanks @Nick. I see now. I should've just looked at the source http://github.com/jquery/jquery/blob/master/src/effects.js#L92. So it is a static mapping of 'true' to 'show'. Somehow I thought it gave consideration to the initial state. So it does provide a safeguard to ease my paranoid mind. :o)
patrick dw