VueSeamlessScroll 无缝滚动点击事件不生效(需要给复制Dom加样式)

VueSeamlessScroll 无缝滚动点击事件不生效(需要给复制Dom加样式)

实现效果

  • VueSeamlessScroll 列表无缝滚动,且可以选择某一项进行选中改变背景,并且将选中的数据传到其他接口中
    在这里插入图片描述

遇到问题

  • 问题:数据的点击事件,只有第一遍循环的时候生效,后面循环出来的数据都不生效
  • 原因:不能点击的原因是因为html元素是复制出来的(滚动组件是将后面的复制出来一份,进行填铺页面,方便滚动)
  • 解决方案: 往滚动组件的父节点上添加绑定事件(js冒泡机制),通过e.target定位到具体点击位置。

具体实现

<template>
  <div
    class="scroll-list h_24"
    ref="scrollList"
    @click="onSelect($event)"
  >
    <vue-seamless-scroll
      v-if="data && data.length"
      :data="data"
      ref="seamlessScroll"
      :class-option="vueSeamlessOptions"
      :style="{ height: scrollHeight }"
    >
      <div class="scroll-list_body">
        <div
          class="scroll-list_body__item"
          v-for="(item, index) in data"
          :key="index"
          :data="JSON.stringify(item)"
          :style="{ backgroundColor: item.index === activeIndex ? color : '' }"
        >
          <!-- 你的滚动列表内容 -->
        </div>
      </div>
    </vue-seamless-scroll>
  </div>
</template>
<script>
import vueSeamlessScroll from "vue-seamless-scroll";
export default {
  name: "scroll-list",
  components: {
    vueSeamlessScroll,
  },
  props: {
    // 你的渲染数据
    data: {
      type: Array,
      default: () => [],
    },
    // 传入的选中背景色
    color: {
      type: String,
      default: "rgba(250, 173, 20, 0.1)",
    },
  },
  data() {
    return {
      // 滚动高度
      scrollHeight: 0,
      activeIndex: undefined,
      vueSeamlessOptions: {
        step: 1, // 设置步长为1,即每次滚动一条数据
        limitMoveNum: 8, // 限制滚动次数为8次
        hoverStop: true, // 鼠标悬停时停止滚动
        direction: 1, // 滚动方向为向下
      },
    };
  },
  watch: {
    data() {
      this.activeIndex = undefined;
    },
  },

  mounted() {
    const scrollHeight = this.$refs["scrollList"].clientHeight;
    if (scrollHeight) {
      this.scrollHeight = `${scrollHeight}px`;
    }
  },
  methods: {
    onSelect(e) {
      const path = e.path || (e.composedPath && e.composedPath());
      let target = path.filter((r) => /scroll-list_body__item/.test(r.className));
      if (target.length) target = target[0];
      else return;
      //列表超过8条数据即开始滚动有复制元素时才这样操作
      if (this.data.length > 8) {
        const classNames = document.getElementsByClassName("scroll-list_body__item");
        // 循环获取到的元素集合
        Array.prototype.forEach.call(classNames, function (element) {
          element.style.background = "";
        });
        target.style.background = this.color;
      }
      const data = JSON.parse(target.getAttribute("data")); // 单项数据详情,点击那行数据的所有数据
      this.activeIndex = data.index;
     //你要做的其他操作
    },
  },
};
</script>
<style lang="less" scoped>
.scroll-list {
  overflow: hidden;
  &_body {
    &__item {
      display: flex;
      align-items: center;
      padding: 8px 0;
      position: relative;
      cursor: pointer;
      // 你的滚动列表样式
    }
  }
}
</style>

扩展

  • 获取class为xxx的元素
// 获取class为email-tag的元素:
var elements = document.getElementsByClassName('xxx');
// 循环获取到的元素集合
Array.prototype.forEach.call(elements, function (element) {
   console.log(element)
});
  • 为什么不能直接用forEach 循环?

因为document.querySelectorAll()返回的并不是我们想当然的数组,而是NodeList,对NodeList,它里面没有.forEach方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值