使用CSS无限滚动文本

时间:2017-08-30 21:07:45

标签: javascript html css animation

在我的HTML页面上,我需要有一行文字在页面上“无限地”滚动,例如

“Hello World ... Hello World ... Hello World ... Hello World ...”

类似于自动收报机磁带,但是同一文本开始滚动到它的末尾没有间隙。

我尝试过使用动画:marquee CSS样式,我可以获取文本卷,然后跳回来,然后再次滚动,但这不是我需要的。

CSS可以实现吗?如果有一个可行的解决方案,JS就没问题。

3 个答案:

答案 0 :(得分:2)

在此尝试"文字滚动"使用文本&图像和鼠标效果(js + css)

http://www.dynamicdrive.com/dynamicindex2/crawler/index.htm

答案 1 :(得分:1)

您是否愿意使用可以执行此操作的lib?

这一个:http://www.cssscript.com/marquee-like-horizontal-scroller-with-pure-javascript-marquee-js/做得很好。

$(document).ready(function() {
  new Marquee('example', {
    // once or continuous
    continuous: true,
    // 'rtl' or 'ltr'
    direction: 'rtl',
    // pause between loops
    delayAfter: 1000,
    // when to start
    delayBefore: 0,
    // scroll speed
    speed: 0.5,
    // loops
    loops: -1
  });
});

////////////////////////////// LIBRARY BELOW ///////

// See: http://www.cssscript.com/marquee-like-horizontal-scroller-with-pure-javascript-marquee-js/
/*
	Vanilla Javascript Marquee
	Version: 0.1.0
	Author: Robert Bossaert <https://github.com/robertbossaert>
	Example call:
	
	new Marquee('element');
	new Marquee('element', {
		direction: 'rtl',
	});
*/
var Marquee = function(element, defaults) {
  "use strict";

  var elem = document.getElementById(element),
    options = (defaults === undefined) ? {} : defaults,
    continuous = options.continuous || true, // once or continuous
    delayAfter = options.delayAfter || 1000, // pause between loops
    delayBefore = options.delayBefore || 0, // when to start
    direction = options.direction || 'ltr', // ltr or rtl
    loops = options.loops || -1,
    speed = options.speed || 0.5,
    timer = null,
    milestone = 0,
    marqueeElem = null,
    elemWidth = null,
    self = this,
    ltrCond = 0,
    loopCnt = 0,
    start = 0,
    process = null,
    constructor = function(elem) {

      // Build html
      var elemHTML = elem.innerHTML,
        elemNode = elem.childNodes[1] || elem;

      elemWidth = elemNode.offsetWidth;

      marqueeElem = '<div>' + elemHTML + '</div>';
      elem.innerHTML = marqueeElem;
      marqueeElem = elem.getElementsByTagName('div')[0];
      elem.style.overflow = 'hidden';
      marqueeElem.style.whiteSpace = 'nowrap';
      marqueeElem.style.position = 'relative';

      if (continuous === true) {
        marqueeElem.innerHTML += elemHTML;
        marqueeElem.style.width = '200%';

        if (direction === 'ltr') {
          start = -elemWidth;
        }
      } else {
        ltrCond = elem.offsetWidth;

        if (direction === 'rtl') {
          milestone = ltrCond;
        }
      }

      if (direction === 'ltr') {
        milestone = -elemWidth;
      } else if (direction === 'rtl') {
        speed = -speed;
      }

      self.start();

      return marqueeElem;
    }

  this.start = function() {
    process = window.setInterval(function() {
      self.play();
    });
  };

  this.play = function() {
    // beginning
    marqueeElem.style.left = start + 'px';
    start = start + speed;

    if (start > ltrCond || start < -elemWidth) {
      start = milestone;
      loopCnt++;

      if (loops !== -1 && loopCnt >= loops) {
        marqueeElem.style.left = 0;
      }
    }
  }

  this.end = function() {
    window.clearInterval(process);
  }

  // Init plugin
  marqueeElem = constructor(elem);
}
body {
  background: #edf3f9;
  color: #3f4f5f;
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}

.container {
  margin: 0 auto;
  width: 800px;
}

header {
  border-bottom: 2px solid #3f4f5f;
  padding: 6.25em 0 3.95em;
  text-align: center;
  width: 100%;
}

header h1 {
  margin: 0 0 10px;
}

.example {
  padding: 3em 0;
}

h2 {
  text-align: center;
}

pre {
  background: #f5f2f0;
  color: #000;
  font-family: Consolas, Monaco, 'Andale Mono', monospace;
  line-height: 26px;
  padding: 1em;
  text-shadow: 0 1px white;
  white-space: pre-wrap;
}

pre span.string {
  color: #690;
}

pre span.number {
  color: #905;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="example">
  The quick brown fox ran over to the bar to drink some water. He walked up to the bar tender and said: blah blah blah.
</div>

答案 2 :(得分:0)

这是一个基于 Dreamer 发布的库的演示。 我不喜欢它如何在元素上设置内联样式或者如何使用cookie来存储过去的设置,所以我在crawler.js代码中删除了它。

这是一个非常古老的库(ie5被提到(!))但它似乎可以解决问题。

$(function() {

  marqueeInit({
    uniqueid: 'mycrawler',
    style: {
      
    },
    inc: 5, //speed - pixel increment for each iteration of this marquee's movement
    mouse: 'cursor driven', //mouseover behavior ('pause' 'cursor driven' or false)
    moveatleast: 2,
    neutral: 150,
    persist: true,
    savedirection: true
  });
});

//////////////// CRAWLER.JS FOLLOWS ///////////

/* Text and/or Image Crawler Script v1.53 (c)2009-2012 John Davenport Scheuer
   as first seen in http://www.dynamicdrive.com/forums/
   username: jscheuer1 - This Notice Must Remain for Legal Use
   updated: 4/2011 for random order option, more (see below)
   */

/* Update 4/2011 to v1.5 - Adds optional random property. Set it to true to use.
   Fixes browser crash from empty crawlers, ad and image blocking software/routines.
   Fixes behavior in some IE of breaking script if an image is missing.
   Adds alt attributes to images without them to aid in diagnosis of missing/corrupt
   images. This may be disabled with the new optional noAddedAlt property set to true.
   Internal workings enhanced for greater speed of execution, less memory usage.
   */

/* Update 11/2011 - Detect and randomize td elements within a single table with a single tr */

// updated 7/2012 to 1.51 for optional integration with 3rd party initializing scripts -
// ref: http://www.dynamicdrive.com/forums/showthread.php?p=278161#post278161
// updated 8/2012 to 1.52 for greater compatibility with IE in Quirks Mode

/* Update 10/2012 to v1.53 - Adds optional persist property to have the crawler remember its
   position and direction page to page and on page reload. To enable it in the marqueeInit set
   persist: true,
   */

///////////////// No Need to Edit - Configuration is Done in the On Page marqueeInit call(s) /////////////////


function marqueeInit(config) {
  if (!document.createElement) return;
  marqueeInit.ar.push(config);
  marqueeInit.run(config.uniqueid);
}

(function() {

  if (!document.createElement) return;

  if (typeof opera === 'undefined') {
    window.opera = false;
  }

  marqueeInit.ar = [];

  document.write('<style type="text/css">.marquee{white-space:nowrap;overflow:hidden;visibility:hidden;}' +
    '#marq_kill_marg_bord{border:none!important;margin:0!important;}<\/style>');
  var c = 0,
    tTRE = [/^\s*$/, /^\s*/, /\s*$/, /[^\/]+$/],
    req1 = {
      'position': 'relative',
      'overflow': 'hidden'
    },
    defaultconfig = {
      style: { //default style object for marquee containers without configured style
        'margin': '0 auto'
      },
      direction: 'left',
      inc: 2, //default speed - pixel increment for each iteration of a marquee's movement
      mouse: 'pause' //default mouseover behavior ('pause' 'cursor driven' or false)
    },
    dash, ie = false,
    oldie = 0,
    ie5 = false,
    iever = 0;

  /*@cc_on @*/
  /*@if(@_jscript_version >= 5)
  ie = true;
  try{document.documentMode = 2000}catch(e){};
  iever = Math.min(document.documentMode, navigator.appVersion.replace(/^.*MSIE (\d+\.\d+).*$/, '$1'));
  if(iever < 6)
   oldie = 1;
  if(iever < 5.5){
   Array.prototype.push = function(el){this[this.length] = el;};
   ie5 = true;
   dash = /(-(.))/;
   String.prototype.encamel = function(s, m){
    s = this;
    while((m = dash.exec(s)))
     s = s.replace(m[1], m[2].toUpperCase());
    return s;
   };
  }
  @end @*/

  if (!ie5) {
    dash = /-(.)/g;

    function toHump(a, b) {
      return b.toUpperCase();
    };
    String.prototype.encamel = function() {
      return this.replace(dash, toHump);
    };
  }

  if (ie && iever < 8) {
    marqueeInit.table = [];
    window.attachEvent('onload', function() {
      marqueeInit.OK = true;
      var i = -1,
        limit = marqueeInit.table.length;
      while (++i < limit)
        marqueeInit.run(marqueeInit.table[i]);
    });
  }

  function intable(el) {
    while ((el = el.parentNode))
      if (el.tagName && el.tagName.toLowerCase() === 'table')
        return true;
    return false;
  };

  marqueeInit.run = function(id) {
    if (ie && !marqueeInit.OK && iever < 8 && intable(document.getElementById(id))) {
      marqueeInit.table.push(id);
      return;
    }
    if (!document.getElementById(id))
      setTimeout(function() {
        marqueeInit.run(id);
      }, 300);
    else
      new Marq(c++, document.getElementById(id));
  }

  function trimTags(tag) {
    var r = [],
      i = 0,
      e;
    while ((e = tag.firstChild) && e.nodeType === 3 && tTRE[0].test(e.nodeValue))
      tag.removeChild(e);
    while ((e = tag.lastChild) && e.nodeType === 3 && tTRE[0].test(e.nodeValue))
      tag.removeChild(e);
    if ((e = tag.firstChild) && e.nodeType === 3)
      e.nodeValue = e.nodeValue.replace(tTRE[1], '');
    if ((e = tag.lastChild) && e.nodeType === 3)
      e.nodeValue = e.nodeValue.replace(tTRE[2], '');
    while ((e = tag.firstChild))
      r[i++] = tag.removeChild(e);
    return r;
  }

  function randthem(tag) {
    var els = oldie ? tag.all : tag.getElementsByTagName('*'),
      i = els.length,
      childels = [];
    while (--i > -1) {
      if (els[i].parentNode === tag) {
        childels.push(els[i]);
      }
    }
    childels.sort(function() {
      return 0.5 - Math.random();
    });
    i = childels.length;
    while (--i > -1) {
      tag.appendChild(childels[i]);
    }
  }

  function Marq(c, tag) {
    var p, u, s, a, ims, ic, i, marqContent, cObj = this;
    this.mq = marqueeInit.ar[c];
    if (this.mq.random) {
      if (tag.getElementsByTagName && tag.getElementsByTagName('tr').length === 1 && tag.childNodes.length === 1) {
        randthem(tag.getElementsByTagName('tr')[0]);
      } else {
        randthem(tag);
      }
    }
    for (p in defaultconfig)
      if ((this.mq.hasOwnProperty && !this.mq.hasOwnProperty(p)) || (!this.mq.hasOwnProperty && !this.mq[p]))
        this.mq[p] = defaultconfig[p];

    this.mq.style.width = !this.mq.style.width || isNaN(parseInt(this.mq.style.width)) ? '100%' : this.mq.style.width;
    if (!tag.getElementsByTagName('img')[0])
      this.mq.style.height = !this.mq.style.height || isNaN(parseInt(this.mq.style.height)) ? tag.offsetHeight + 3 + 'px' : this.mq.style.height;
    else
      this.mq.style.height = !this.mq.style.height || isNaN(parseInt(this.mq.style.height)) ? 'auto' : this.mq.style.height;
    u = this.mq.style.width.split(/\d/);
    this.cw = this.mq.style.width ? [parseInt(this.mq.style.width), u[u.length - 1]] : ['a'];
    marqContent = trimTags(tag);
    tag.className = tag.id = '';
    tag.removeAttribute('class', 0);
    tag.removeAttribute('id', 0);
    if (ie)
      tag.removeAttribute('className', 0);
    tag.appendChild(tag.cloneNode(false));
    tag.className = ['marquee', c].join('');
    tag.style.overflow = 'hidden';
    this.c = tag.firstChild;
    this.c.appendChild(this.c.cloneNode(false));
    this.c.style.visibility = 'hidden';
    a = [
      [req1, this.c.style],
      [this.mq.style, this.c.style]
    ];
    for (i = a.length - 1; i > -1; --i)
      for (p in a[i][0])
        if ((a[i][0].hasOwnProperty && a[i][0].hasOwnProperty(p)) || (!a[i][0].hasOwnProperty))
          a[i][1][p.encamel()] = a[i][0][p];
    this.m = this.c.firstChild;
    if (this.mq.mouse === 'pause') {
      this.c.onmouseover = function() {
        cObj.mq.stopped = true;
      };
      this.c.onmouseout = function() {
        cObj.mq.stopped = false;
      };
    }
    this.m.style.position = 'absolute';
    this.m.style.left = '-10000000px';
    this.m.style.whiteSpace = 'nowrap';
    if (ie5) this.c.firstChild.appendChild((this.m = document.createElement('nobr')));
    if (!this.mq.noAddedSpace)
      this.m.appendChild(document.createTextNode('\xa0'));
    for (i = 0; marqContent[i]; ++i)
      this.m.appendChild(marqContent[i]);
    if (ie5) this.m = this.c.firstChild;
    ims = this.m.getElementsByTagName('img');
    if (ims.length) {
      for (ic = 0, i = 0; i < ims.length; ++i) {
        ims[i].style.display = 'inline';
        if (!ims[i].alt && !this.mq.noAddedAlt) {
          ims[i].alt = (tTRE[3].exec(ims[i].src)) || ('Image #' + [i + 1]);
          if (!ims[i].title) {
            ims[i].title = '';
          }
        }
        ims[i].style.display = 'inline';
        ims[i].style.verticalAlign = ims[i].style.verticalAlign || 'top';
        if (typeof ims[i].complete === 'boolean' && ims[i].complete)
          ic++;
        else {
          ims[i].onload = ims[i].onerror = function() {
            if (++ic === ims.length)
              cObj.setup(c);
          };
        }
        if (ic === ims.length)
          this.setup(c);
      }
    } else this.setup(c)
  }

  Marq.prototype.setup = function(c) {
    if (this.mq.setup) return;
    this.mq.setup = this;
    var s, w, cObj = this,
      exit = 10000;
    if (this.c.style.height === 'auto')
      this.c.style.height = this.m.offsetHeight + 4 + 'px';
    this.c.appendChild(this.m.cloneNode(true));
    this.m = [this.m, this.m.nextSibling];
    if (typeof this.mq.initcontent === 'function') {
      this.mq.initcontent.apply(this.mq, [this.m]);
    }
    if (this.mq.mouse === 'cursor driven') {
      this.r = this.mq.neutral || 16;
      this.sinc = this.mq.inc;
      this.c.onmousemove = function(e) {
        cObj.mq.stopped = false;
        cObj.directspeed(e)
      };
      if (this.mq.moveatleast) {
        this.mq.inc = this.mq.moveatleast;
        if (this.mq.savedirection) {
          if (this.mq.savedirection === 'reverse') {
            this.c.onmouseout = function(e) {
              if (cObj.contains(e)) return;
              cObj.mq.inc = cObj.mq.moveatleast;
              cObj.mq.direction = cObj.mq.direction === 'right' ? 'left' : 'right';
            };
          } else {
            this.mq.savedirection = this.mq.direction;
            this.c.onmouseout = function(e) {
              if (cObj.contains(e)) return;
              cObj.mq.inc = cObj.mq.moveatleast;
              cObj.mq.direction = cObj.mq.savedirection;
            };
          }
        } else
          this.c.onmouseout = function(e) {
            if (!cObj.contains(e)) cObj.mq.inc = cObj.mq.moveatleast;
          };
      } else
        this.c.onmouseout = function(e) {
          if (!cObj.contains(e)) cObj.slowdeath();
        };
    }
    this.w = this.m[0].offsetWidth;
    this.m[0].style.left = 0;
    this.c.id = 'marq_kill_marg_bord';
    this.m[0].style.top = this.m[1].style.top = Math.floor((this.c.offsetHeight - this.m[0].offsetHeight) / 2 - oldie) + 'px';
    this.c.id = '';
    this.c.removeAttribute('id', 0);
    this.m[1].style.left = this.w + 'px';
    s = this.mq.moveatleast ? Math.max(this.mq.moveatleast, this.sinc) : (this.sinc || this.mq.inc);
    while (this.c.offsetWidth > this.w - s && --exit) {
      w = isNaN(this.cw[0]) ? this.w - s : --this.cw[0];
      if (w < 1 || this.w < Math.max(1, s)) {
        break;
      }
      this.c.style.width = isNaN(this.cw[0]) ? this.w - s + 'px' : --this.cw[0] + this.cw[1];
    }
    this.c.style.visibility = 'visible';
    this.runit();
  }

  Marq.prototype.slowdeath = function() {
    var cObj = this;
    if (this.mq.inc) {
      this.mq.inc -= 1;
      this.timer = setTimeout(function() {
        cObj.slowdeath();
      }, 100);
    }
  }

  Marq.prototype.runit = function() {
    var cObj = this,
      d = this.mq.direction === 'right' ? 1 : -1;
    if (this.mq.stopped || this.mq.stopMarquee) {
      setTimeout(function() {
        cObj.runit();
      }, 300);
      return;
    }
    if (this.mq.mouse != 'cursor driven')
      this.mq.inc = Math.max(1, this.mq.inc);
    if (d * parseInt(this.m[0].style.left) >= this.w)
      this.m[0].style.left = parseInt(this.m[1].style.left) - d * this.w + 'px';
    if (d * parseInt(this.m[1].style.left) >= this.w)
      this.m[1].style.left = parseInt(this.m[0].style.left) - d * this.w + 'px';
    this.m[0].style.left = parseInt(this.m[0].style.left) + d * this.mq.inc + 'px';
    this.m[1].style.left = parseInt(this.m[1].style.left) + d * this.mq.inc + 'px';

    setTimeout(function() {
      cObj.runit();
    }, 30 + (this.mq.addDelay || 0));
  }

  Marq.prototype.directspeed = function(e) {
    e = e || window.event;
    if (this.timer) clearTimeout(this.timer);
    var c = this.c,
      w = c.offsetWidth,
      l = c.offsetLeft,
      mp = (typeof e.pageX === 'number' ?
        e.pageX : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft) - l,
      lb = (w - this.r) / 2,
      rb = (w + this.r) / 2;
    while ((c = c.offsetParent)) mp -= c.offsetLeft;
    this.mq.direction = mp > rb ? 'left' : 'right';
    this.mq.inc = Math.round((mp > rb ? (mp - rb) : mp < lb ? (lb - mp) : 0) / lb * this.sinc);
  }

  Marq.prototype.contains = function(e) {
    if (e && e.relatedTarget) {
      var c = e.relatedTarget;
      if (c === this.c) return true;
      while ((c = c.parentNode))
        if (c === this.c) return true;
    }
    return false;
  }

  function resize() {
    for (var s, w, m, i = 0; i < marqueeInit.ar.length; ++i) {
      if (marqueeInit.ar[i] && marqueeInit.ar[i].setup) {
        m = marqueeInit.ar[i].setup;
        s = m.mq.moveatleast ? Math.max(m.mq.moveatleast, m.sinc) : (m.sinc || m.mq.inc);
        m.c.style.width = m.mq.style.width;
        m.cw[0] = m.cw.length > 1 ? parseInt(m.mq.style.width) : 'a';
        while (m.c.offsetWidth > m.w - s) {
          w = isNaN(m.cw[0]) ? m.w - s : --m.cw[0];
          if (w < 1) {
            break;
          }
          m.c.style.width = isNaN(m.cw[0]) ? m.w - s + 'px' : --m.cw[0] + m.cw[1];
        }
      }
    }
  }

  function unload() {
    for (var m, i = 0; i < marqueeInit.ar.length; ++i) {
      if (marqueeInit.ar[i] && marqueeInit.ar[i].persist && marqueeInit.ar[i].setup) {
        m = marqueeInit.ar[i].setup;
        m.cookie.set(m.mq.uniqueid, m.m[0].style.left + ':' + m.m[1].style.left + ':' + m.mq.direction);
      }
    }
  }

  if (window.addEventListener) {
    window.addEventListener('resize', resize, false);
    window.addEventListener('unload', unload, false);
  } else if (window.attachEvent) {
    window.attachEvent('onresize', resize);
    window.attachEvent('onunload', unload);
  }

})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="marquee" id="mycrawler">
  Those confounded friars dully buzz that faltering jay. An appraising tongue acutely causes our courageous hogs. Their fitting submarines deftly break your approving improvisations. Her downcast taxonomies actually box up those disgusted turtles.
</div>