На моей HTML-странице мне нужна строка с текстом, который катится «бесконечно» на странице, например,

"Hello World ... Hello World ... Hello World ... Hello World ..."

Вроде как тикерная лента, но с тем же текстом начало катиться в его конец без пробела.

Я пытался использовать стиль CSS animation: marquee , я могу получить откат текста, затем вернуться назад, затем снова откатить, но это не то, что мне нужно.

Возможно ли это с помощью CSS? JS будет в порядке, если есть рабочее решение.

0
user2349195 31 Авг 2017 в 00:07

3 ответа

Лучший ответ

Попробуйте здесь "переходящий текст" работать с текстом и изображениями и эффектами мыши (js + css)

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

2
31 Авг 2017 в 08:21

Вы открыты для использования библиотеки, которая делает это?

Вот этот: 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>
1
flyer 30 Авг 2017 в 21:35

Вот демонстрация, основанная на библиотеке, которую опубликовал Dreamer . Мне не понравилось, как он устанавливает встроенные стили для элемента или как он использует куки для сохранения прошлых настроек, поэтому я удалил это в коде crawler.js.

Это довольно старая библиотека (т.е. упоминается 5 (!)), Но, похоже, она работает.

$(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>
0
flyer 1 Сен 2017 в 14:48