0

I'm adding dynamic content from a database to a marquee I found online. The problem is - the content length varies widely and the script needs a set, static width for it to work properly. I either need to figure out a way to generate the width while I'm pulling the content, or to have the script auto generate width for items. It's a very to the point script I found on here actually. Here's a JSFiddle to see how it works.

For those who don't like JSFiddle here's some simple html/css

<h1>This runs differently than the ticker for some reason. It's highly annoying in my personal opinion.</h1>
<div id="ticker">    
    <div class="event">test1</div>
    <div class="event">This is Test 2</div>
    <div class="event">test3</div>
    <div class="event">This is test number 4</div>
</div>​

css

.event{float: left;}
/* Add width and it will run, sorta fine
.event{width:100px;}
*/

Jquery

(function($) {
        $.fn.textWidth = function(){
            return $(this).width();
        };

        $.fn.marquee = function(args) {
            var that = $(this);
            var $textWidth = that.textWidth(),
                offset = that.width(),
                width = offset,
                css = {
                    'text-indent' : that.css('text-indent'),
                    'overflow' : that.css('overflow'), 
                    'white-space' : that.css('white-space')
                },
                marqueeCss = {
                    'text-indent' : width,
                    'overflow' : 'hidden',
                    'white-space' : 'nowrap'
                },
                args = $.extend(true, { count: -1, speed: 1e1, leftToRight: false }, args),
                i = 0,
                stop = $textWidth*-1,
                dfd = $.Deferred();
            function go() {
                if (that.data('isStopped') != 1)
                {
                if(!that.length) return dfd.reject();
                if(width == stop) {
                    i++;
                    if(i == args.count) {
                        that.css(css);
                        return dfd.resolve();
                    }
                    if(args.leftToRight) {
                        width = $textWidth*-1;
                    } else {
                        width = offset;
                    }
                }
                that.css('text-indent', width + 'px');
                if(args.leftToRight) {
                    width++;
                } else {
                    width--;
                }
            }

                setTimeout(go, 10);
            };
            if(args.leftToRight) {
                width = $textWidth*-1;
                width++;
                stop = offset;
            } else {
                width--;            
            }
            that.css(marqueeCss);
            that.data('isStopped', 0);
            that.bind('mouseover', function() { $(this).data('isStopped', 1); }).bind('mouseout', function() { $(this).data('isStopped', 0); });
            go();
            return dfd.promise();
        };        
    })(jQuery);
        $('h1').marquee();
        $('#ticker').marquee();​

The first thing I thought about was to get the width of each list item before generating the marquee, and put the width inline. I couldn't figure out how to do that though and after awhile of playing around with it I gave up. Here's a link to the website it is on - where the content is added via ajax. The marquee is at the top. I'll remove the link after a bit. Suggestions on what I should do?

animuson
  • 53,861
  • 28
  • 137
  • 147
Howdy_McGee
  • 10,422
  • 29
  • 111
  • 186
  • When I have made tickers in the past i have always calculated the ticker "viewport" dimension and the item dimension and then calculated the star position and end position for the text and animated in that fashion (using top and left values)... text-indent is an approach that never crossed my mind. – prodigitalson May 15 '12 at 03:07

1 Answers1

1

Just an idea, I don't see the code where you're adding the dynamic part but do they have to be inside <div> tags? Could you use .append() instead?

Something like:

$('#ticker').append(response.data); //or whatever the variable would be

So basically it just adds the text to that div instead of being separate div's. You may need to not start the scrolling until all the data is appended in order for the marquee plugin to compensate for the newly added text.

OR

Here is some code you could use that would solve your initial problem:

Add this function to your code:

$.fn.textWidthTrue = function(){
  var html_org = $(this).html();
  var html_calc = '<span>' + html_org + '</span>';
  $(this).html(html_calc);
  var width = $(this).find('span:first').width();
  $(this).html(html_org);
  return width;
};

As seen here: Calculating text width

Then add this:

$('#ticker').find('.event').each(function(i){ // set the width correctly 
   $(this).width($(this).textWidthTrue());
});

JSFiddle: http://jsfiddle.net/NYQEL/12/

Community
  • 1
  • 1
sirmdawg
  • 2,579
  • 3
  • 21
  • 32
  • The reason why I just cant append is because I want to style each event, I have the response separated by date / event right now. That was a pretty good answer and it makes sense thank you for your help much appreciated! – Howdy_McGee May 15 '12 at 05:16