文字横向滚动提示

index.js

function Marquee(wrapper, data, options) {
  if (!wrapper) {
    throw new Error("Not Found Wrapper!!!");
  }

  if (arguments.length === 1) {
    options = {};
  }

  if (arguments.length === 2) {
    options = data || {};
    data = null;
  }

  if (arguments.length === 3) {
    options = options || {};
  }
  var self = this;

  this.wrapper = wrapper;
  this.allWidth = 0;
  this.timer = null;
  this.listener = null;
  this._once_listener_ = false;

  this.threshold = options.threshold || 200;
  this.speed = options.speed || 10;
  this.delay = 100;

  var rect = wrapper.getBoundingClientRect();
  this.wrapperWidth = rect.width;

  this.wrapperClassName = "marquee";
  this.listClassName = "marquee--list";
  this.itemClassName = "marquee--item";

  this.data = []

  this._init();

  if (data) {
    this.data = data;
    this.append(this.data);

    if (options.autostart) {
      this.start();
    }
  }

  if (options.loop) {
    this.on(function () {
      self.append(self.data, true)
    })
  }
}

Marquee.prototype._init = function () {
  var self = this;

  self.wrapper.className = (
    self.wrapper.className +
    " " +
    self.wrapperClassName
  ).trim();

  var list = document.createElement("ul");
  list.className = "marquee--list";
  self.wrapper.appendChild(list);

  self.list = list;

  return this;
};

Marquee.prototype.on = function (fn) {
  this.listener = fn;
};

Marquee.prototype.emit = function () {
  if (!this._once_listener_) {
    this._once_listener_ = true;
    this.listener && this.listener();
  }
};

Marquee.prototype.start = function () {
  var self = this;

  // TODO 如果没有数据, ThrowError
  self.timer = setInterval(function () {
    self._marquee();
  }, self.delay);

  return this;
};

Marquee.prototype._marquee = function () {
  var self = this;

  var offsetLeft = self.list.offsetLeft;
  if (
    self.allWidth - Math.abs(offsetLeft) - self.wrapperWidth <
    self.threshold
  ) {
    self.emit();
  }

  if (
    Math.abs(offsetLeft) + self.wrapperWidth + self.speed >=
    self.allWidth
  ) {
    clearInterval(self.timer);
    self.timer = null;

    self.list.style.left =
      -(self.allWidth - self.wrapperWidth) + "px";
  } else {
    self.list.style.left =
      -(Math.abs(offsetLeft) + self.speed) + "px";
  }
};

Marquee.prototype.stop = function () {
  var self = this;

  clearInterval(self.timer);
  self.timer = null;

  return this;
};

Marquee.prototype.append = function (data, restart) {
  var self = this;

  this.data = data;

  self.stop();
  self._once_listener_ = false;

  data.forEach(function (d) {
    var li = document.createElement("li");
    li.className = self.itemClassName;
    // li.innerText = d;
    li.innerHTML = d;

    self.list.appendChild(li);
  });

  var allWidth = 0;
  var items = self.list.getElementsByClassName(
    self.itemClassName
  );
  for (var i = 0; i < items.length; i++) {
    var item = items[i];
    var rect = item.getBoundingClientRect();
    var width = rect.width;
    allWidth += width;
  }

  self.list.style.width = allWidth + "px";

  self.allWidth = allWidth;

  if (!!restart) {
    self.start();
  }

  return this;
};

export default Marquee

index.css

body {
  text-size-adjust: none;
  -webkit-text-size-adjust: none;
}
.marquee {
  position: relative;
  height: 30px;
  line-height: 30px;
  width: 100%;
  overflow: hidden;
  background-color: rgba(0, 0, 0, 0.6);
  color: #fff;
  z-index: 888;
}

.marquee--list {
  position: absolute;
  top: 0;
  left: 0;
  width: 100000px;
  height: 30px;
  line-height: 30px;
  list-style: none;
}

.marquee--list::after {
  content: "";
  display: block;
  clear: both;
}

.marquee--item {
  float: left;
  list-style: none;
  margin: 0 100px;
  font-size: 14px;
}

index.vue

<template>
  <div id="marquee"></div>
</template>

<script>
import "./index.css";
import Marquee from "./index";

export default {
  props: {
    list: {
      type: Array,
    },
  },
  data() {
    return {
      marquee: null,
    };
  },
  mounted() {
    this.marquee = new Marquee(document.getElementById("marquee"), null, {
      loop: true,
      speed: 2,
    });
  },
  watch: {
    list(newVal, oldVal) {
      if (newVal.length > 0) {
        this.marquee.append(newVal, true);
        this.marquee.start();
      }
    },
  },
};
</script>

组件使用

<scroll-x :list="horScrollXList"></scroll-x>
<script>
    import scrollX from '/'
    export default {
        components:{scrollX },
        data() {
            return {
                horScrollXList: [],
            }
        },
        created() {
            let data = res.data.data
            this.horScrollXList = data.map(function(v) {
                if (v.title == '谢谢参与') {
                    v.title = "<span class='txtColor'>" + v.title + '</span>'
                }
                return `${v.nickname}: 通过抽奖获得“  ${v.title}  ”*1`
            })
        },
    }
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值