当前位置: 首页 > news >正文

vue实现卡片遮罩层交互式功能

前言

在前端开发中,卡片遮罩层是一种常见的交互设计元素,用于强调某个区域或内容,并提供用户操作的入口。本文将带大家在 vue 中结合实际案例实现此功能。


实现效果

在这里插入图片描述


完整代码

html

<template><!-- 主容器 --><div class="box"><divclass="card"@click="cardDetails(index)"@mousedown.prevent="startLongPress($event, index)"@mouseup="stopLongPress"@mouseleave="stopLongPress"v-for="(item, index) in list":key="index"ref="cardRef"><!-- 卡片内容 --><div class="content"><div class="cardImg"><img :src="item.imgUrl" alt="" /></div><div class="introduce">{{ item.name }}</div></div><!-- 长按时显示的遮罩层 --><divv-show="item.showOverlay"class="overlay":class="{ 'expand-animation': item.showOverlay }"@click.stop><div class="buttonCon"><divv-for="(shadeItem, shadeIndex) in shadeList":key="shadeIndex"@click="onShade(shadeItem.title)">{{ shadeItem.title }}</div></div><span class="close" @click="closeOverlay($event, index)">&times;</span></div></div></div>
</template>

js

<script>
export default {data() {return {shadeList: [{ title: "商品不感兴趣" },{ title: "不想看到此类商品" },{ title: "已经买了" },{ title: "图片引起不适" },{ title: "更多..." },],longPressTimer: null, // 用于存储长按计时器list: [{imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg",name: "xxxxxxxxxxxxxxxxxxxxxxx",showOverlay: false,},{imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg",name: "xxxxxxxxxxxxxxxxxxxxxxx",showOverlay: false,},{imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg",name: "xxxxxxxxxxxxxxxxxxxxxxx",showOverlay: false,},{imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg",name: "xxxxxxxxxxxxxxxxxxxxxxx",showOverlay: false,},{imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg",name: "xxxxxxxxxxxxxxxxxxxxxxx",showOverlay: false,},{imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg",name: "xxxxxxxxxxxxxxxxxxxxxxx",showOverlay: false,},{imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg",name: "xxxxxxxxxxxxxxxxxxxxxxx",showOverlay: false,},{imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg",name: "xxxxxxxxxxxxxxxxxxxxxxx",showOverlay: false,},],};},mounted() {// 监听窗口滚动window.addEventListener("scroll", this.closeAllOverlaysOnScroll);},// 实例销毁前移除监听窗口的滚动beforeDestroy() {window.removeEventListener("scroll", this.closeAllOverlaysOnScroll);},methods: {// 滚动时关闭遮罩层closeAllOverlaysOnScroll() {this.list.forEach((item) => {this.$set(item, "showOverlay", false);});},// 开始长按事件startLongPress(event, index) {event.preventDefault();event.stopPropagation();this.closeOtherOverlays(index);this.longPressTimer = setTimeout(() => {this.list[index].showOverlay = true;document.addEventListener("click", this.checkClickOutside);}, 100);},closeOtherOverlays(index) {this.list.forEach((item, i) => {if (i !== index) {item.showOverlay = false;}});},// 点击卡片详情cardDetails(index) {if (!this.list[index].showOverlay) {console.log("点击卡片");}},// 结束长按事件stopLongPress() {clearTimeout(this.longPressTimer);document.removeEventListener("click", this.checkClickOutside);},// 关闭遮罩层closeOverlay(event, index) {event.stopPropagation(); // 阻止事件冒泡this.$set(this.list[index], "showOverlay", false); // 关闭当前卡片的遮罩层document.removeEventListener("click", this.checkClickOutside);},// 检查点击区域是否在遮罩层外checkClickOutside(event) {// 遍历所有卡片,关闭非点击卡片的遮罩层this.list.forEach((item, index) => {if (!this.$refs.cardRef[index].contains(event.target)) {this.$set(item, "showOverlay", false);}});document.removeEventListener("click", this.checkClickOutside);},// 点击遮罩层内容onShade(name) {console.log(name);},},
};
</script>

css

<style scoped lang="less">
.box {font-size: 16px;min-height: 100vh;background: #f0f0f0;padding: 8px;.card {width: 49%;display: inline-block;background-color: white;position: relative;overflow-wrap: break-word;user-select: none;margin-bottom: 10px;border-radius: 8px;.introduce {text-align: justify;overflow: hidden;padding: 0px 6px 6px 6px;font-size: 14px;height: 50px;font-size: 14px;}.cardImg {img {border-top-left-radius: 8px;border-top-right-radius: 8px;width: 100%;height: 120px;}}.overlay {padding: 16px 10px;box-sizing: border-box;border-radius: 8px;position: absolute;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(35, 35, 35, 0.8);&.expand-animation {animation: expand 0.3s forwards;}}.buttonCon {font-size: 14px;width: 100%;color: rgb(213, 207, 207);div:not(:last-child) {border-bottom: 1px solid rgb(82, 82, 82);margin-bottom: 8px;}div {padding: 0px 2px 4px 2px;}}.close {position: absolute;top: 2px;right: 8px;font-size: 20px;cursor: pointer;color: white;}}.card:nth-child(even) {margin-left: 2%;}
}@keyframes expand {0% {transform: scale(0);opacity: 0;}100% {transform: scale(1);opacity: 1;}
}
</style>

实现思路

这段代码实现了一个交互式的卡片列表功能,其中每个卡片包含一个图片和一些文字介绍。用户可以通过点击卡片来查看详情,同时也可以通过长按卡片来显示一个遮罩层,遮罩层上有一些操作按钮,如"商品不感兴趣"、"不想看到此类商品"等选项。此外,用户还可以点击遮罩层外的区域来关闭遮罩层。整体功能类似于一个商品展示页面,用户可以对商品进行不同的操作和反馈。

首先,实现卡片列表展示功能。通过循环遍历一个包含图片和文字介绍的数据数组,动态生成多个卡片组件。每个卡片组件包含一个图片元素和一个文字介绍元素,通过 vuev-for 指令实现数据绑定,将对应的图片和文字展示在每个卡片上。

其次,实现点击卡片查看详情的功能。为每个卡片组件添加点击事件监听器,当用户点击某个卡片时,触发相应的事件处理函数,展示该卡片的详细信息。这可以通过 vue@click 指令实现,为每个卡片元素添加点击事件处理逻辑。

接着,实现长按卡片显示遮罩层的功能。在代码中,为每个卡片组件添加长按事件监听器,当用户长按某个卡片时,显示遮罩层。通过 vue@touchstart 指令监听长按事件,并在事件触发时显示遮罩层。遮罩层可以是一个覆盖在卡片上方的半透明层,用来提供操作按钮和用户反馈选项。

在遮罩层上添加操作按钮,如"商品不感兴趣"、"不想看到此类商品"等选项。用户可以通过点击这些按钮来进行不同的操作和反馈。通过在遮罩层组件中添加按钮元素,并为每个按钮添加点击事件处理逻辑来实现。

最后,实现点击遮罩层外的区域关闭遮罩层的功能。为遮罩层外的区域添加点击事件监听器,当用户点击遮罩层外的区域时,关闭遮罩层。通过 vue@click 指令监听遮罩层外区域的点击事件,并在事件触发时关闭遮罩层。


http://www.mrgr.cn/news/5102.html

相关文章:

  • 倍内菲新品发布揭示宠物营养新纪元,引领行业保驾护航
  • 什么是天线OTA,怎么通过OTA数据评估产品射频环境情况
  • 004快速排序-python实现
  • FFmpeg的入门实践系列三(基础知识)
  • Docker微服务实战Demo
  • 自动化测试框架pytest+allure+requests
  • (待更)将windows11配置成生产力高的电脑:当计算机新生的你拿到新电脑时该配置哪些东西(python、mysql、git)
  • Linux基础I/O之文件缓冲区
  • 无人驾驶,并非无人之地
  • MFC在对话框中实现打印和打印预览
  • 配置ROS环境
  • 深度剖析C++string(上篇)
  • 瑞吉外卖--登录退出功能的实现
  • 在 uboot 中实现 UDP 协议
  • 记Windows文件右键扩展二级子菜单
  • 【前端面试】call、apply 、bind、箭头函数
  • 【Linux】实现三个迷你小程序(倒计时,旋转指针,进度条)
  • vivado RPM
  • 基于UDP的网络聊天室
  • android——workermanager