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方法。