32

I'm trying to find a very simple and smooth, lightweight javascript or jquery marquee. I already tried silk marquee or something, but it wouldn't work with the application I was using. So the simpler and shorter, the better - and easier to debug. Does anybody know of a easy to implement javascript replacement for the marquee?

Pastebin

Code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript">
var tWidth='300px';                  // width (in pixels)
var tHeight='25px';                  // height (in pixels)
var tcolour='#ffffcc';               // background colour:
var moStop=true;                     // pause on mouseover (true or false)
var fontfamily = 'arial,sans-serif'; // font for content
var tSpeed=3;                        // scroll speed (1 = slow, 5 = fast)

// enter your ticker content here (use \/ and \' in place of / and ' respectively)
var content='Are you looking for loads of useful information <a href="http:\/\/javascript.about.com\/">About Javascript<\/a>? Well now you\'ve found it.';

var cps=-tSpeed; var aw, mq; var fsz = parseInt(tHeight) - 4; function startticker(){if (document.getElementById) {var tick = '<div style="position:relative;width:'+tWidth+';height:'+tHeight+';overflow:hidden;background-color:'+tcolour+'"'; if (moStop) tick += ' onmouseover="cps=0" onmouseout="cps=-tSpeed"'; tick +='><div id="mq" style="position:absolute;right:0px;top:0px;font-family:'+fontfamily+';font-size:'+fsz+'px;white-space:nowrap;"><\/div><\/div>'; document.getElementById('ticker').innerHTML = tick; mq = document.getElementById("mq"); mq.style.right=(10+parseInt(tWidth))+"px"; mq.innerHTML='<span id="tx">'+content+'<\/span>'; aw = document.getElementById("tx").offsetWidth; lefttime=setInterval("scrollticker()",50);}} function scrollticker(){mq.style.right = (parseInt(mq.style.right)>(-10 - aw)) ?
mq.style.right = parseInt(mq.style.right)+cps+"px": parseInt(tWidth)+10+"px";} window.onload=startticker;
</script>
</head>
<body>
<div id="ticker">
    this is a simple scrolling text!
</div>
</body>
</html>
Derp
  • 921
  • 3
  • 14
  • 22
  • 2
    `wouldn't work` is hardly descriptive, please describe how it doesn't work? And please post your markup as well – Andreas Wong May 11 '12 at 08:15
  • @derp. could you post a sample javascript and html code that you've used? we can help you see what's causing the issue. – OnesimusUnbound May 11 '12 at 08:17
  • 4
    Hiya; flick some code man, that will help us to help you anyhow see this hope this helps, http://jsfiddle.net/FWWEn/ have a nice one, cheerios! – Tats_innit May 11 '12 at 08:18
  • I've long deleted the silk marquee after playing around with it for a couple hours and moved on to a couple other marquees that didn't quite pan out. The problem is I'm trying to implement it into joomla that's why the more simple it is the better. I'm just looking for more options :/ – Derp May 11 '12 at 08:20
  • Here's the latest I've tried, kept erroring in a loop telling me it cant find `scrollticker()` when it is clearly there. This works on its on, in its own document but not when i implement it into joomla. So i'm looking for more like this. http://pastebin.com/L9EmncR1 – Derp May 11 '12 at 08:22
  • @Christoph I really tried, but it's too bumpy :( – Derp May 11 '12 at 08:23
  • 1
    @Tats_innit: Why don't you add that as an answer? Nice coding. – jgauffin May 11 '12 at 08:24
  • @jgauffin okies bruv, adding now, have a nice one, cheers – Tats_innit May 11 '12 at 08:25
  • 1
    @Derp This wasn't meant to be serious;) Tats code looks really good. – Christoph May 11 '12 at 08:25

10 Answers10

46

hiya simple demo from recommendations in above comments: http://jsfiddle.net/FWWEn/

with pause functionality on mouseover: http://jsfiddle.net/zrW5q/

hope this helps, have a nice one, cheers!

(function($) {
  $.fn.textWidth = function() {
    var calc = '<span style="display:none">' + $(this).text() + '</span>';
    $('body').append(calc);
    var width = $('body').find('span:last').width();
    $('body').find('span:last').remove();
    return 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.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, args.speed);
    };
    if (args.leftToRight) {
      width = textWidth * -1;
      width++;
      stop = offset;
    } else {
      width--;
    }
    that.css(marqueeCss);
    go();
    return dfd.promise();
  };
})(jQuery);

$('h1').marquee();
$('h2').marquee({
  count: 2
});
$('h3').marquee({
  speed: 5
});
$('h4').marquee({
  leftToRight: true
});
$('h5').marquee({
  count: 1,
  speed: 2
}).done(function() {
  $('h5').css('color', '#f00');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<h1>Hello World!</h1>
<h2>I'll marquee twice</h2>
<h3>I go fast!</h3>
<h4>Left to right</h4>
<h5>I'll defer that question</h5>
showdev
  • 28,454
  • 37
  • 55
  • 73
Tats_innit
  • 33,991
  • 10
  • 71
  • 77
  • This code looks great and runs fine in jsfiddle, but when I try to run it locally it doesn't seem to work? Any ideas? http://pastebin.com/iDSgpJDy – Derp May 11 '12 at 08:33
  • Hiya @Derp I hope you have included Jquery src like this in your page `` and the Jquery code will go inside the `` tags, let me know how it goes! cheers – Tats_innit May 11 '12 at 08:35
  • Yeah, check out the pastebin I linked in my first comment, pastebin.com/iDSgpJDy I'm using 1.7.js though not 1.5, and I'm embedding it via script tags. Not sure what is wrong – Derp May 11 '12 at 08:41
  • @Derp can you replicate in jsfiddle **demo** with 1.7.2 version here: http://jsfiddle.net/xYdBj/ I am not sure If I can see the output in paste bin please, cheerios! – Tats_innit May 11 '12 at 08:42
  • That's the weird thing, I copy my exact html doc into jsfiddle and it works like a charm but locally or on a server its just nothing. I know my jquery is linking correctly, maybe its my doc type. I'm playing around with different options. Thanks – Derp May 11 '12 at 08:47
  • Hiya @Derp further I copy pasted your code in jsfiddle :) working like a rocket http://jsfiddle.net/xYdBj/1/ have a nice one, cheers – Tats_innit May 11 '12 at 08:49
  • OK This works great, but if you embed it in the head it will not work. You need doc ready for it to work. Is there a way to add mouse over pause? – Derp May 11 '12 at 09:42
  • @Derp saweet here you go with **pause** feature here: http://jsfiddle.net/zrW5q/ play around a bit :) have a good one, IN this case if you will mouseover it will "pause" the marquee and then restart it again. cheerios! – Tats_innit May 11 '12 at 11:11
  • That's anything but "very smooth" in my Firefox... sigh... not your fault of course; it's the dozens upon dozens of layers of abstractions that burn millions of CPU cycles just to move some text around... – Roman Starkov Nov 03 '12 at 19:46
  • @romkyns `:)` one thing I am looking to identify is the official documentation from microsoft #if_there_is_any to understand what was the thinking behind the marquee tag which always stayed *non-standard* html tag - lemme know if you find one `:))` thanks for the comment though. see you around bruv. – Tats_innit Nov 04 '12 at 01:08
  • 4
    does this implementation allow for wrap around of a large amount of text? everything I'm found/tried seems to wait for the text to go off the screen and start over, instead of being seamless. – Maslow Jan 18 '13 at 16:18
  • This is still not smooth! – Mehdi Raash Feb 02 '20 at 11:44
  • This may have been a good implementation at the time but is now outdated. – Howdy_McGee Apr 13 '22 at 20:10
14

I've made very simple function for marquee. See: http://jsfiddle.net/vivekw/pHNpk/2/ It pauses on mouseover & resumes on mouseleave. Speed can be varied. Easy to understand.

function marquee(a, b) {
var width = b.width();
var start_pos = a.width();
var end_pos = -width;

function scroll() {
    if (b.position().left <= -width) {
        b.css('left', start_pos);
        scroll();
    }
    else {
        time = (parseInt(b.position().left, 10) - end_pos) *
            (10000 / (start_pos - end_pos)); // Increase or decrease speed by changing value 10000
        b.animate({
            'left': -width
        }, time, 'linear', function() {
            scroll();
        });
    }
}

b.css({
    'width': width,
    'left': start_pos
});
scroll(a, b);
b.mouseenter(function() {     // Remove these lines
    b.stop();                 //
    b.clearQueue();           // if you don't want
});                           //
b.mouseleave(function() {     // marquee to pause
    scroll(a, b);             //
});                           // on mouse over
}

$(document).ready(function() {
    marquee($('#display'), $('#text'));  //Enter name of container element & marquee element
});
Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
Vivek Waghmare
  • 141
  • 1
  • 4
11

I just created a simple jQuery plugin for that. Try it ;)

https://github.com/aamirafridi/jQuery.Marquee

Aamir Afridi
  • 6,364
  • 3
  • 42
  • 42
  • 1
    Link works. The script however is very choppy. I recommend the [silky smooth marquee](http://remysharp.com/2008/09/10/the-silky-smooth-marquee/) instead – Onimusha Feb 03 '13 at 14:00
  • Try now. Little bit improved. CSS3 fallback coming soon ;) – Aamir Afridi Feb 28 '13 at 12:24
  • Follow the instructions shown on http://aamirafridi.com/jquery/jquery-marquee-plugin. You are not applying the CSS to marquee element. – Aamir Afridi Mar 21 '14 at 11:29
  • 1
    @Onimusha the plugin now supports CSS3 and is much smoother now. – Aamir Afridi Mar 21 '14 at 11:30
  • I get this for the rawgithub link: `This request has been blacklisted. Stop abusing rawgithub.com or worse things will happen soon.` Do you have another link I can use that updates? – J82 Mar 22 '14 at 08:46
  • @AamirAfridi Since the rawgithub link wasn't working, I integrated `jquery.marquee.min.js` to the end of my script in the footer and it was working for awhile but now it has stopped working for some reason. It looks like the surrounding divs are being added, but the marquee is not moving. Here is a pastebin of what outputs: http://pastebin.com/KCH76pY2. Can you help me figure this out? The live site is at keebs.com/sandbox. The latest tweet at the top is supposed to marquee. – J82 Mar 22 '14 at 10:34
  • @AamirAfridi I just found out that it works in Firefox, but not Chrome, Safari, or IE. Also, I tested it without any browser extensions. – J82 Mar 22 '14 at 12:49
  • @AamirAfridi I have created the question here: http://stackoverflow.com/questions/22582726/jquery-marquee-only-working-in-firefox – J82 Mar 22 '14 at 21:46
  • There is no percentage ability. It requires a fixed PX and no %. It blows up when I try to use 100% of a container. Have you cured that one yet ? – Jay Lepore Jul 27 '21 at 00:05
  • @JayLepore can you create a demo to explain the issue? – Aamir Afridi Jul 27 '21 at 09:17
7

The following works:

http://jsfiddle.net/xAGRJ/4/

The problem with your original code was you are calling scrollticker() by passing a string to setInterval, where you should just pass the function name and treat it as a variable:

lefttime = setInterval(scrollticker, 50);

instead of

lefttime = setInterval("scrollticker()", 50);
Andreas Wong
  • 59,630
  • 19
  • 106
  • 123
  • @Derp bro if that fixed your issue at least accept his answer :) just an observation, take it easy :), cheers! – Tats_innit May 11 '12 at 08:39
  • Well I fixed one and it caused another, being `tSpeed not defined` probably here - `onmouseout="cps=-tSpeed"` im trying to fix it now though. – Derp May 11 '12 at 08:44
  • this will affect scope of variables, passing as string will use a different scope that has access to variables that using the setTimeout with function variable reference scope will not be able to access the same variables. Some refactoring might fix it but that generally requires rewriting where the string version may work ok. Still I wonder if requestAnimationFrame or jquery animate might be smoother approaches than incrementing with a loop on a timout-set framerate... smoothness seems to be an issue with any timeout iterated animation frames. – OG Sean Jun 17 '20 at 18:06
7

Why write custom jQuery code for Marquee... just use a plugin for jQuery - marquee() and use it like in the example below:

First include :

<script type='text/javascript' src='//cdn.jsdelivr.net/jquery.marquee/1.3.1/jquery.marquee.min.js'></script>

and then:

//proporcional speed counter (for responsive/fluid use)
var widths = $('.marquee').width()
var duration = widths * 7;

$('.marquee').marquee({
    //speed in milliseconds of the marquee
    duration: duration, // for responsive/fluid use
    //duration: 8000, // for fixed container
    //gap in pixels between the tickers
    gap: $('.marquee').width(),
    //time in milliseconds before the marquee will start animating
    delayBeforeStart: 0,
    //'left' or 'right'
    direction: 'left',
    //true or false - should the marquee be duplicated to show an effect of continues flow
    duplicated: true
});

If you can make it simpler and better I dare you all people :). Don't make your life more difficult than it should be. More about this plugin and its functionalities at: http://aamirafridi.com/jquery/jquery-marquee-plugin

Antoine
  • 800
  • 3
  • 14
  • 29
DevWL
  • 17,345
  • 6
  • 90
  • 86
2

I made my own version, based in the code presented above by @Tats_innit . The difference is the pause function. Works a little better in that aspect.

(function ($) {
var timeVar, width=0;

$.fn.textWidth = function () {
    var calc = '<span style="display:none">' + $(this).text() + '</span>';
    $('body').append(calc);
    var width = $('body').find('span:last').width();
    $('body').find('span:last').remove();
    return width;
};

$.fn.marquee = function (args) {
    var that = $(this);
    if (width == 0) { width = that.width(); };
    var textWidth = that.textWidth(), offset = that.width(), i = 0, stop = textWidth * -1, dfd = $.Deferred(),
        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, pause: false }, args);

    function go() {
        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=width-2;
        }
        if (args.pause == false) { timeVar = setTimeout(function () { go() }, args.speed); };
        if (args.pause == true) { clearTimeout(timeVar); };
    };

    if (args.leftToRight) {
        width = textWidth * -1;
        width++;
        stop = offset;
    } else {
        width--;
    }
    that.css(marqueeCss);

    timeVar = setTimeout(function () { go() }, 100);

    return dfd.promise();
};
})(jQuery);

usage:

for start: $('#Text1').marquee()

pause: $('#Text1').marquee({ pause: true })

resume: $('#Text1').marquee({ pause: false })

BernieSF
  • 1,722
  • 1
  • 28
  • 42
1

Responsive resist jQuery marquee simple plugin. Tutorial:

// start plugin
    (function($){
        $.fn.marque = function(options, callback){

            // check callback

            if(typeof callback == 'function'){
                callback.call(this);
            } else{
                console.log("second argument (callback) is not a function");
                // throw "callback must be a function"; //only if callback for some reason is required
                // return this; //only if callback for some reason is required
            }

            //set and overwrite default functions
            var defOptions = $.extend({
                speedPixelsInOneSecound: 150, //speed will behave same for different screen where duration will be different for each size of the screen
                select: $('.message div'),
                clickSelect: '', // selector that on click will redirect user ... (optional)
                clickUrl: '' //... to this url. (optional)
            }, options);

            //Run marque plugin
            var windowWidth = $(window).width();
            var textWidth = defOptions.select.outerWidth();
            var duration = (windowWidth + textWidth) * 1000 / defOptions.speedPixelsInOneSecound;
            var startingPosition = (windowWidth + textWidth);
            var curentPosition = (windowWidth + textWidth);
            var speedProportionToLocation = curentPosition / startingPosition;
            defOptions.select.css({'right': -(textWidth)});
            defOptions.select.show();
            var animation;


            function marquee(animation){
                curentPosition = (windowWidth + defOptions.select.outerWidth());
                speedProportionToLocation = curentPosition / startingPosition;
                animation = defOptions.select.animate({'right': windowWidth+'px'}, duration * speedProportionToLocation, "linear", function(){
                     defOptions.select.css({'right': -(textWidth)});
                });
            }
            var play = setInterval(marquee, 200);

            //add onclick behaviour
            if(defOptions.clickSelect != '' && defOptions.clickUrl != ''){
                defOptions.clickSelect.click(function(){
                    window.location.href = defOptions.clickUrl;
                });
            }
            return this;
        };

    }(jQuery)); 
// end plugin 

Use this custom jQuery plugin as bellow:

//use example
$(window).marque({
    speedPixelsInOneSecound: 150, // spped pixels/secound
    select: $('.message div'), // select an object on which you want to apply marquee effects.
    clickSelect: $('.message'), // select clicable object (optional)
    clickUrl: 'services.php' // define redirection url (optional)
});
Antoine
  • 800
  • 3
  • 14
  • 29
DevWL
  • 17,345
  • 6
  • 90
  • 86
1

My text marquee for more text, and position absolute enabled

http://jsfiddle.net/zrW5q/2075/

(function($) {
$.fn.textWidth = function() {
var calc = document.createElement('span');
$(calc).text($(this).text());
$(calc).css({
  position: 'absolute',
  visibility: 'hidden',
  height: 'auto',
  width: 'auto',
  'white-space': 'nowrap'
});
$('body').append(calc);
var width = $(calc).width();
$(calc).remove();
return 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.css('overflow') != "hidden") {
        that.css('text-indent', width + 'px');
        return false;
    }
    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, args.speed);
};

if (args.leftToRight) {
    width = textWidth * -1;
    width++;
    stop = offset;
} else {
    width--;
}
that.css(marqueeCss);
go();
return dfd.promise();
};
// $('h1').marquee();
$("h1").marquee();
$("h1").mouseover(function () {     
    $(this).removeAttr("style");
}).mouseout(function () {
    $(this).marquee();
});
})(jQuery);
0

Marquee using CSS animations.

`<style>
.items-holder {
animation: moveSlideshow 5s linear infinite;
}

.items-holder:hover {
animation-play-state: paused;
}

@keyframes moveSlideshow {
100% { 
transform: translateX(100%);  
}
}
</style>`
Aleexious
  • 1
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 26 '22 at 13:59
0

I try use only css for it this link.

<style>
    .header {
        background: #212121;
        overflow: hidden;
        height: 65px;
        position: relative;
    }
    .header div {
        display: flex;
        flex-direction: row;
        align-items: center;
        overflow: hidden;
        height: 65px;
        transform: translate(100%, 0);
    }
    .header div * {
        font-family: "Roboto", sans-serif;
        color: #fff339;
        text-transform: uppercase;
        text-decoration: none;
    }
    .header div img {
        height: 60px;
        margin-right: 20px;
    }
    .header .ticker-wrapper__container{
        display: flex;
        flex-direction: row;
        align-items: center;
        position: absolute;
        top: 0;
        right: 0;
        animation: ticker 30s infinite linear forwards;
    }

    .header:hover .ticker-wrapper__container{
        animation-play-state: paused;
    }

    .ticker-wrapper__container a{
        display: flex;
        margin-right: 60px;
        align-items: center;
    }

    @keyframes ticker {
        0% {
            transform: translate(100%, 0);
        }
        50% {
            transform: translate(0, 0);
        }
        100% {
            transform: translate(-100%, 0);
        }
    }
</style>