You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Marquee 3000无法实现从右向左滚动的问题解决

解决Marquee 3000无法从右向左滚动的问题

问题背景

我花了一整天时间尝试让Marquee 3000在包含图标的区域实现从右向左滚动,以下是我的相关配置:

现有配置

HTML结构

<div class="elementor-element elementor-element-deb8b11 e-con-full my-ticker-section marquee3k e-flex e-con is-init" data-id="deb8b11" data-element_type="container" data-settings='{"content_width":"full","background_background":"classic"}' data-marquee3k="" data-speed="1" data-reverse="true">
    <div class="my-ticker-content">
        <div class="my-ticker-item">
            <!-- 第一个项的图标和标题 -->
        </div>
        <div class="my-ticker-item">
            <!-- 第二个项的图标和标题 -->
        </div>
        <!-- 更多项... -->
    </div>
</div>

JavaScript代码(通过WordPress代码片段加载)

// 加载Marquee3k脚本
function enqueue_marquee3k_script() {
    wp_enqueue_script('marquee3k', get_template_directory_uri() . '/js/marquee3k.min.js', array(), null, true);
}
add_action('wp_enqueue_scripts', 'enqueue_marquee3k_script');

// 添加内联脚本初始化Marquee3k
function add_inline_script_for_marquee() {
    echo '
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            Marquee3k.init();
        });
    </script>
    ';
}
add_action('wp_footer', 'add_inline_script_for_marquee');

CSS样式

.my-ticker-item {
    display: inline-block;
    margin-right: 20px; /* 项之间的间距 */
    text-align: center; /* 居中名称、图标和价格 */
}

.item-name, .item-price {
    display: block;
}

.item-icon img {
    width: 50px; /* 根据需要调整 */
    height: 50px; /* 根据需要调整 */
}

问题现象

我通过Elementor Pro给容器添加了data-marquee3k、data-speed="1"、data-reverse="true"属性,页面上的紫色滚动区域能够正常运行,但始终无法实现从右向左的滚动效果。

解决方法

替换项目中的marquee3k.js文件为以下修改后的版本:

/**
 * MARQUEE 3000 MARQUEE 3000 MARQUEE 3000 MARQUEE 3000 MARQUEE 3000
 * http://github.com/ezekielaquino/marquee3000
 * Marquees for the new millennium v1.0
 * MIT License
 */

;(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define([], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory();
  } else {
    root.Marquee3k = factory();
  }
}(this, function() {
  'use strict';

  let animationId = 0;

  class Marquee3k {
    constructor(element, options) {

      if (element.children.length === 0) {
        throw new Error("Encountered a marquee element without children, please supply a wrapper for your content");
      }

      this.element = element;
      this.selector = options.selector;
      this.speed = element.dataset.speed || 0.25;
      this.pausable = element.dataset.pausable === 'true' ? true : false;
      this.reverse = element.dataset.reverse === 'false' ? false : true; // CHANGED HERE
      this.paused = false;
      this.parent = element.parentElement;
      this.parentProps = this.parent.getBoundingClientRect();
      this.content = element.children[0];
      this.innerContent = this.content.innerHTML;
      this.wrapStyles = '';
      this.offset = 0;

      this._setupWrapper();
      this._setupContent();
      this._setupEvents();

      this.wrapper.appendChild(this.content);
      this.element.appendChild(this.wrapper);
    }

    _setupWrapper() {
      this.wrapper = document.createElement('div');
      this.wrapper.classList.add('marquee3k__wrapper');
      this.wrapper.style.whiteSpace = 'nowrap';
    }

    _setupContent() {
      this.content.classList.add(`${this.selector}__copy`);
      this.content.style.display = 'inline-block';
      this.contentWidth = this.content.offsetWidth;

      this.requiredReps = this.contentWidth > this.parentProps.width ? 2 : Math.ceil((this.parentProps.width - this.contentWidth) / this.contentWidth) + 1;

      for (let i = 0; i < this.requiredReps; i++) {
        this._createClone();
      }

      if (!this.reverse) { // CHANGED HERE
        this.offset = this.contentWidth * -1;
      }

      this.element.classList.add('is-init');
    }

    _setupEvents() {
      this.element.addEventListener('mouseenter', () => {
        if (this.pausable) this.paused = true;
      });

      this.element.addEventListener('mouseleave', () => {
        if (this.pausable) this.paused = false;
      });
    }

    _createClone() {
      const clone = this.content.cloneNode(true);
      clone.style.display = 'inline-block';
      clone.classList.add(`${this.selector}__copy`);
      this.wrapper.appendChild(clone);
    }

    animate() {
      if (!this.paused) {
        const isScrolled = !this.reverse ? this.offset < 0 : this.offset > this.contentWidth * -1; // CHANGED HERE
        const direction = !this.reverse ? -1 : 1; // CHANGED HERE
        const reset = !this.reverse ? this.contentWidth * -1 : 0; // CHANGED HERE

        if (isScrolled) this.offset -= this.speed * direction;
        else this.offset = reset;

        this.wrapper.style.whiteSpace = 'nowrap';
        this.wrapper.style.transform = `translate(${this.offset}px, 0) translateZ(0)`;
      }
    }

    _refresh() {
      this.contentWidth = this.content.offsetWidth;
    }

    repopulate(difference, isLarger) {
      this.contentWidth = this.content.offsetWidth;

      if (isLarger) {
        const amount = Math.ceil(difference / this.contentWidth) + 1;

        for (let i = 0; i < amount; i++) {
          this._createClone();
        }
      }
    }

    static refresh(index) {
      MARQUEES[index]._refresh();
    }

    static pause(index) {
      MARQUEES[index].paused = true;
    }

    static play(index) {
      MARQUEES[index].paused = false;
    }

    static toggle(index) {
      MARQUEES[index].paused = !MARQUEES[index].paused;
    }

    static refreshAll() {
      for (let i = 0; i < MARQUEES.length; i++) {
        MARQUEES[i]._refresh();
      }
    }

    static pauseAll() {
      for (let i = 0; i < MARQUEES.length; i++) {
        MARQUEES[i].paused = true;
      }
    }

    static playAll() {
      for (let i = 0; i < MARQUEES.length; i++) {
        MARQUEES[i].paused = false;
      }
    }

    static toggleAll() {
      for (let i = 0; i < MARQUEES.length; i++) {
        MARQUEES[i].paused = !MARQUEES[i].paused;
      }
    }

    static init(options = { selector: 'marquee3k' }) {
      if (animationId) window.cancelAnimationFrame(animationId);

      window.MARQUEES = [];
      const marquees = Array.from(document.querySelectorAll(`.${options.selector}`));
      let previousWidth = window.innerWidth;
      let timer;

      for (let i = 0; i < marquees.length; i++) {
        const marquee = marquees[i];
        const instance = new Marquee3k(marquee, options);
        MARQUEES.push(instance);
      }

      animate();

      function animate() {
        for (let i = 0; i < MARQUEES.length; i++) {
          MARQUEES[i].animate();
        }
        animationId = window.requestAnimationFrame(animate);
      }

      window.addEventListener('resize', () => {
        clearTimeout(timer);

        timer = setTimeout(() => {
          const isLarger = previousWidth < window.innerWidth;
          const difference = window.innerWidth - previousWidth;

          for (let i = 0; i < MARQUEES.length; i++) {
            MARQUEES[i].repopulate(difference, isLarger);
          }

          previousWidth = this.innerWidth;
        }, 250);
      });
    }
  }

  return Marquee3k;

}));

内容的提问来源于stack exchange,提问作者Christian Kozyge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 23:38:08