13

I'm hopeless at Javascript. This is what I have:

<script type="text/javascript">
    function beginrefresh(){

        //set the id of the target object
        var marquee = document.getElementById("marquee_text");

        if(marquee.scrollLeft >= marquee.scrollWidth - parseInt(marquee.style.width)) {
            marquee.scrollLeft = 0;
        }

        marquee.scrollLeft += 1;

        // set the delay (ms), bigger delay, slower movement
        setTimeout("beginrefresh()", 10);

    }
</script>

It scrolls to the left but I need it to repeat relatively seamlessly. At the moment it just jumps back to the beginning. It might not be possible the way I've done it, if not, anyone have a better method?

blork
  • 2,150
  • 6
  • 26
  • 45

7 Answers7

16

Here is a jQuery plugin with a lot of features:

http://jscroller2.markusbordihn.de/example/image-scroller-windiv/

And this one is "silky smooth"

http://remysharp.com/2008/09/10/the-silky-smooth-marquee/

Elmo
  • 6,409
  • 16
  • 72
  • 140
GeekyMonkey
  • 12,478
  • 6
  • 33
  • 39
  • I'm not having any luck with these or any others for a wrap-around. they wait for the end of the last thing to clear the screen before going again, any ideas? – Maslow Jan 18 '13 at 16:11
  • 2
    first link is dead. – Sp0T Feb 08 '17 at 08:11
8

Simple javascript solution:

window.addEventListener('load', function () {
 function go() {
  i = i < width ? i + step : 1;
  m.style.marginLeft = -i + 'px';
 }
 var i = 0,
  step = 3,
  space = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 var m = document.getElementById('marquee');
 var t = m.innerHTML; //text
 m.innerHTML = t + space;
 m.style.position = 'absolute'; // http://stackoverflow.com/questions/2057682/determine-pixel-length-of-string-in-javascript-jquery/2057789#2057789
 var width = (m.clientWidth + 1);
 m.style.position = '';
 m.innerHTML = t + space + t + space + t + space + t + space + t + space + t + space + t + space;
 m.addEventListener('mouseenter', function () {
  step = 0;
 }, true);
 m.addEventListener('mouseleave', function () {
  step = 3;
 }, true);
 var x = setInterval(go, 50);
}, true);
#marquee {
   background:#eee;
   overflow:hidden;
   white-space: nowrap;
 }
<div id="marquee">
 1 Hello world! 2 Hello world! <a href="#">3 Hello world!</a>
</div>

JSFiddle

BSMP
  • 4,596
  • 8
  • 33
  • 44
Stano
  • 8,749
  • 6
  • 30
  • 44
2

I recently implemented a marquee in HTML using Cycle 2 Jquery plugin : http://jquery.malsup.com/cycle2/demo/non-image.php

<div class="cycle-slideshow"  data-cycle-fx="scrollHorz" data-cycle-speed="9000" data-cycle-timeout="1"  data-cycle-easing="linear" data-cycle-pause-on-hover="true" data-cycle-slides="> div" >
  <div>  Text 1  </div>
  <div>  Text 2  </div>
</div>    
Manikandan
  • 78
  • 4
1

This script used to replace the marquee tag

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function() {
     
         $('.scrollingtext').bind('marquee', function() {
             var ob = $(this);
             var tw = ob.width();
             var ww = ob.parent().width();
             ob.css({ right: -tw });
             ob.animate({ right: ww }, 20000, 'linear', function() {
                 ob.trigger('marquee');
             });
         }).trigger('marquee');
     
     });
     </script>


<div class="scroll">
    <div class="scrollingtext"> Flash message without marquee tag using javascript!  </div>
 </div>
Zoe
  • 27,060
  • 21
  • 118
  • 148
M. Lak
  • 903
  • 9
  • 18
  • I converted the above jQuery to pure JavaScript: https://stackoverflow.com/questions/69454348/jquery-transform-animate-translation-to-pure-javascript/69459159#69459159 – Phil Huhn Oct 06 '21 at 02:31
1

HTML5 does not support the tag, however a lot of browsers will still display the text "properly" but your code will not validate. If this isn't an issue for you, that may be an option.

CSS3 has the ability, supposedly, to have marquee text, however because anyone that knows how to do it believes it's a "bad idea" for CSS, there is very limited information that I have found online. Even the W3 documents do not go into enough detail for the hobbyist or self-teaching person to implement it.

PHP and Perl can duplicate the effect as well. The script needed for this would be insanely complicated and take up much more resources than any other options. There is also the possibility that the script would run too quickly on some browsers, causing the effect to be completely negated.

So back to JavaScript - Your code (OP) seems to be about the cleanest, simplest, most effective I've found. I will be trying this. For the seamless thing, I will be looking into a way to limit the white space between end and beginning, possibly with doing a while loop (or similar) and actually run two of the script, letting one rest while the other is processing.

There may also be a way with a single function change to eliminate the white space. I'm new to JS, so don't know off the top of my head. - I know this isn't a full-on answer, but sometimes ideas can cause results, if only for someone else.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
AeSix
  • 19
  • 1
  • 5
    I'd love to know how you imagine PHP can "duplicate" the client-side marquee effect - considering PHP is a server-side language... Do tell? – Tom Glenn Oct 28 '11 at 14:29
0

Working with @Stano code and some jQuery I have created a script that will replace the old marquee tag with standard div. The code will also parse the marquee attributes like direction, scrolldelay and scrollamount.

Here is the code:

jQuery(function ($) {

    if ($('marquee').length == 0) {
        return;
    }

    $('marquee').each(function () {

        let direction = $(this).attr('direction');
        let scrollamount = $(this).attr('scrollamount');
        let scrolldelay = $(this).attr('scrolldelay');

        let newMarquee = $('<div class="new-marquee"></div>');
        $(newMarquee).html($(this).html());
        $(newMarquee).attr('direction',direction);
        $(newMarquee).attr('scrollamount',scrollamount);
        $(newMarquee).attr('scrolldelay',scrolldelay);
        $(newMarquee).css('white-space', 'nowrap');

        let wrapper = $('<div style="overflow:hidden"></div>').append(newMarquee);
        $(this).replaceWith(wrapper);

    });

    function start_marquee() {

        let marqueeElements = document.getElementsByClassName('new-marquee');
        let marqueLen = marqueeElements.length
        for (let k = 0; k < marqueLen; k++) {


            let space = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
            let marqueeEl = marqueeElements[k];

            let direction = marqueeEl.getAttribute('direction');
            let scrolldelay = marqueeEl.getAttribute('scrolldelay') * 100;
            let scrollamount = marqueeEl.getAttribute('scrollamount');

            let marqueeText = marqueeEl.innerHTML;

            marqueeEl.innerHTML = marqueeText + space;
            marqueeEl.style.position = 'absolute'; 

            let width = (marqueeEl.clientWidth + 1);
            let i = (direction == 'rigth') ? width : 0;
            let step = (scrollamount !== undefined) ? parseInt(scrollamount) : 3;

            marqueeEl.style.position = '';
            marqueeEl.innerHTML = marqueeText + space + marqueeText + space;



            let x = setInterval( function () {

                if ( direction.toLowerCase() == 'left') {

                    i = i < width ? i + step : 1;
                    marqueeEl.style.marginLeft = -i + 'px';

                } else {

                    i = i > -width ? i - step : width;
                    marqueeEl.style.marginLeft = -i + 'px';

                }

            }, scrolldelay);

        }
    }

    start_marquee ();
});

And here is a working codepen

Ale
  • 944
  • 3
  • 14
  • 34
0

I was recently working on a site that needed a marquee and had initially used the dynamic marquee, which worked well but I couldn't have the text begin off the screen. Took a look around but couldn't find anything quite as simple as I wanted so I made my own:

<div id="marquee">

<script type="text/javascript">

  let marquee = $('#marquee p');
  const appendToMarquee = (content) => {
    marquee.append(content);
  }
  
  const fillMarquee = (itemsToAppend, content) => {
    for (let i = 0; i < itemsToAppend; i++) {
      appendToMarquee(content);
    }
  }
  
  const animateMarquee = (itemsToAppend, content, width) => {
    fillMarquee(itemsToAppend, content);
    marquee.animate({left: `-=${width}`,}, width*10, 'linear', function() {
      animateMarquee(itemsToAppend, content, width);
    })
  }


  const initMarquee = () => {
    let width = $(window).width(),
    marqueeContent = "YOUR TEXT",
    itemsToAppend = width / marqueeContent.split("").length / 2;
    animateMarquee(itemsToAppend, marqueeContent, width);
  }

  initMarquee();
</script>

And the CSS:

#marquee {
  overflow: hidden;
  margin: 0;
  padding: 0.5em 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #000;
  color: #fff;
}

#marquee p {
  white-space: nowrap;
  margin: 0;
  overflow: visible;
  position: relative;
  left: 0;
}
OGadoury
  • 15
  • 6