views:

127

answers:

1

I'm trying to make a marquee -- via jQuery, that is like Pandora's.

I want it to make it only start scrolling if

1) The width of the element would be cut off 2) If you're hovering over the element.

It should revert back to normal when you mouseoff it.

Here is what I have so far, which almost works:

var h3 = $('h3:first'), h3Width = h3.width();

if( h3.get(0).scrollWidth > h3Width ) {
    $(h3).addClass('department-scroll-container').css( 'width', h3.width() + 'px' ).wrapInner( '<span style="width: ' + h3Width + 'px; position: relative; display:block" />' );
    $('span:first', h3).clone().appendTo( h3 ).hide();

    // Create the event
    h3.mouseover( function() {
        var h3 = $(this), h3Width = $(this).width();

        $(this).find('span:first').animate({ 'right': h3Width + 'px' }, 5000 );
        var interval = setInterval( function() {
            var visible_span = $('span:visible:first', h3);

            $('span:hidden', h3).css( 'right', parseInt( -h3Width ) + 'px' ).show().animate({ 'right': h3Width + 'px' }, 5000, 'linear' );
            visible_span.hide();
        }, 5000 );

        $(this).data( 'interval', interval );
    }).mouseout( function() {
        var interval = $(this).data( 'interval' );
        clearInterval( interval );
        $(this).find('span:first').css( 'right', '0' ).end().find('span:last').hide();
    });
}

The problem is, this makes it scroll once.

I think the mouseout is getting triggered because of the span that is within it as well -- I need a way to make this smoother and somehow work.

Any ideas?


UPDATE

Thanks to the answer below, I got a solution, see below:

var h3 = $('h3:first', department), h3Width = h3.width();

// Marquee
if( h3.get(0).scrollWidth > h3Width ) {
    $(h3).addClass('department-scroll-container').css( 'width', h3.width() + 'px' ).wrapInner( '<span style="width: ' + h3Width + 'px; position: relative; display:block" />' );
    $('span:first', h3).clone().appendTo( h3 ).hide();

    // Create the event
    h3.mouseenter( function() {
        var h3 = $(this), h3Width = $(this).width();

        $(this).data( 'animate', true ).find('span:first').animate({ 'right': h3Width + 'px' }, 2500, 'linear' );

        setTimeout( function() {
            // Don't continue if it's been stopped
            if( !h3.data('animate') )
                return;

            var visible_span = $('span:visible:first', h3);

            $('span:hidden', h3).css( 'right', parseInt( -h3Width ) + 'px' ).show().animate({ 'right': h3Width + 'px' }, 5000, 'linear' );
            visible_span.hide();

            var interval = setInterval( function() {
                // Don't continue if it's been stopped
                if( !h3.data('animate') )
                    return;

                var visible_span = $('span:visible:first', h3);

                $('span:hidden', h3).css( 'right', parseInt( -h3Width ) + 'px' ).show().animate({ 'right': h3Width + 'px' }, 5000, 'linear' );
                visible_span.hide();
            }, 5000 );
         }, 2500 );

        $(this).data( 'interval', interval );
    }).mouseleave( function() {
        $(this).data( 'animate', false );

        var interval = $(this).data( 'interval' );
        clearInterval( interval );
        $(this).find('span:first').stop().css( 'right', '0' ).show().end().find('span:last').stop().hide();
    });
}
+1  A: 

use .mouseenter and .mouseleave instead of mouseout and mouseover

http://api.jquery.com/mouseenter/

http://api.jquery.com/mouseleave/

Mark