Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have tried jQuery to create an alternative of marquee. And got no success; it flickers , it does not stop on hover. I edited and edited again...and finaly came out with a jQuery + javascript mess.

It works but its dirty, can someone help me ?

javascript:

$(document).ready(function(){  
        marquee();
        var timeout=1;
        function marquee(){
            var margin= -($('#mydiv > div:eq(0)').outerHeight()+ 20);
            $('#mydiv > div:eq(0)').animate({'margin-top': margin+'px'},4000,function(){
                $('#mydiv > div:eq(2)').html($(this).html());
                $(this).html('').css({'margin-top':'0px'}).appendTo($('#mydiv'));
                loop();
            });
        }
        function loop(){     
            if(timeout)
            setTimeout(marquee,0); 
        }
        $('#mydiv').hover(function(){
                timeout = 0;
                $('#mydiv > div:eq(0)').stop(true);
        },function(){
                timeout = 1;
                marquee();
        });
    });

Markup:

<div id='mydiv' style='width:300px;height:300px;overflow:hidden'> 
<div id='div1'>
    <h4> Advantages:</h4><br>
    <ul>
     <li>blah 1</li>
             <li>blah 2</li>
             <li>blah 3</li>
    </ul> 
</div>
<div id='div2'>
    <h4>Applications:</h4><br>
    <ul>
     <li>blah 1</li>
             <li>blah 2</li>
             <li>blah 3</li>
    </ul>
</div>  
<div id='div3'></div>

share|improve this question

migrated from stackoverflow.com Dec 16 '11 at 2:04

This question came from our site for professional and enthusiast programmers.

1  
I wouldn't recommend to put a marquee on a page unless you want to make harder for the user to notice your whole page and not just the marquee, also some users find marquees annoying. –  jclozano Dec 27 '11 at 17:57
    
I just created a jQuery plugin. Try this. github.com/aamirafridi/jQuery-Marquee –  Aamir Afridi Jan 11 '13 at 15:07

2 Answers 2

up vote 2 down vote accepted

A few points:

  • $(this).html('') will throw away the contents of #div1 (on the first iteration) and #div2 (on the second iteration). If you want the marquee to loop, that's not going to work.
  • This is a perfect use case for a simple jQuery plugin (see the documentation).
  • You should probably use next() instead of the eq selector, to make your code work with any number of children (or at least any number above 1).
  • To stop the animations on hover, you'll have to call stop() on any elements that may be half-way into an animation. Pausing and continuing the marquee would be good use cases for plugin methods.
  • You could consider using the position and top attributes to position the children; this is exactly what position: absolute is for.

Given below is an example of a simple plugin that does roughly what you want. To keep in theme with this site, I've stuck with your approach -- animation is done on margin-top and, as you can see, only the first child is animated.

Because of this, the marquee won't loop until all children are outside the parent div. To make it wrap sooner, I would advise rewriting the plugin to use position: absolute and the top attribute on each child. That way, each child can be idependently animated and the marquee can be looped earlier.

Finally, keep in mind that this example is far from perfect. For example, the total height of the children is re-calculated on each run. The plugin could be made more efficient simply by maintaining state.

Plugin:

(function($) {

    var methods = {
        init: function(options) {
            this.children(':first').stop();
            this.marquee('play');
        },
        play: function() {
            var marquee = this,
                pixelsPerSecond = 100,
                firstChild = this.children(':first'),
                totalHeight = 0,
                difference,
                duration;

            // Find the total height of the children by adding each child's height:
            this.children().each(function(index, element) {
                totalHeight += $(element).innerHeight();
            });

            // The distance the divs have to travel to reach -1 * totalHeight:
            difference = totalHeight + parseInt(firstChild.css('margin-top'), 10);

            // The duration of the animation needed to get the correct speed:
            duration = (difference/pixelsPerSecond) * 1000;

            // Animate the first child's margin-top to -1 * totalHeight:
            firstChild.animate(
                { 'margin-top': -1 * totalHeight },
                duration,
                'linear',
                function() {
                    // Move the first child back down (below the container):
                    firstChild.css('margin-top', marquee.innerHeight());
                    // Restart whole process... :)
                    marquee.marquee('play');
                }
            );
        },
        pause: function() {
            this.children(':first').stop();
        }
    };

    $.fn.marquee = function(method) {

        // Method calling logic
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.marquee');
        }

    };

})(jQuery);

Usage:

var marquee = $('#mydiv');

marquee.marquee();

marquee.hover(function() {
    marquee.marquee('pause');
}, function() {
    marquee.marquee('play');    
});

This example can also be found on jsfiddle: http://jsfiddle.net/PPvG/LgsrU/

share|improve this answer
    
superb work. No flickering at all. Thanks for giving time. But this plugin is working exactly like marquee. When all divs finished sliding up. It shows blank for some time and then shows the first div again. I wanted a continuous loop. –  Jashwant Jan 2 '12 at 9:44

I've been researching the best possible implementations for marquee myself. I indeed was looking for element marquee, rather than text marquee. I finally implemented the code using CSS3 transitions with graceful degradation to scroll animation for the older browsers. The CSS3 transitions, and indeed scroll implementation, is by far more efficient that offsetting elements using margin or any similar implementation.

Even with 4 simultaneous marquee elements on the page, the implementation has virtually no performance impact.

enter image description here

The demo can be seen at https://dev.anuary.com/60244f3a-b8b2-5678-bce5-f7e8742f0c69/. The code is available at https://github.com/gajus/marquee.

share|improve this answer
    
awesome !!!!!!! –  Jashwant Jan 11 '13 at 5:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.