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.mzph.cn/news/877735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ctfshow WEB刷题

web1 直接右键打开&#xff0c;在源代码里 web2 ctrlu查看源码 web3 打开bp抓包发送直接就得到了 web4 用dirsearch扫描发现txt文件 访问 接着访问得到flag web5 用dirbuster扫描看看有没有phps源码泄露&#xff0c;发现存在 访问下载文件打开就是flag web6 用dirsearch扫…

ES6笔记总结(Xmind格式):第三天

Xmind鸟瞰图&#xff1a; 简单文字总结&#xff1a; ES6知识总结&#xff1a; Promise的使用: 1.使用 new Promise() 构造函数来创建一个 promise 对象 2.接受两个函数作为参数&#xff1a;resolve 和 reject ①resolve 函数在异步操作成功完成时调用&#xf…

python办公自动化:初识`python-docx`

1.1 什么是python-docx python-docx是一个用于在Python中创建和操作Word文档的库。它提供了一组简洁的API&#xff0c;让开发者可以轻松地生成、修改、和读取Microsoft Word (.docx)文件&#xff0c;而不需要安装Microsoft Office。这使得python-docx成为办公自动化、报告生成…

特征工程中预处理中,字符串转成元组

要在函数内部实现将 saved_feature_combinations 转换为元组形式&#xff0c;可以在检查 saved_feature_combinations 是否为空后&#xff0c;直接将它们转换为元组。你可以在现有逻辑的基础上添加转换步骤。 def process_and_save_combinations(self, saved_feature_combinat…

python构建一个web程序

from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return 欢迎来到我的Python Web程序!if __name__ __main__:app.run(debugTrue)1、安装flask D:\Users\USER\PycharmProjects\pythonProject1\p01>pip install flask WARNING: Ignoring invalid…

服务器五大关键组件拆解分析

拆解服务器五大关键组件 "AI服务器五大硬件揭秘&#xff1a;深入剖析PCB构造&#xff0c;揭示内部真实面貌。本文通过一步步拆解PCB,为读者呈现了一台服务器的内部世界&#xff0c;力求让您对服务器升级的潜在价值有更深的理解和把握。" 1、五大硬件部分可归纳为——…

自定义开屏启动广告页

自定义开屏启动广告页 文章目录 自定义开屏启动广告页效果图简单版轮播方式css 效果图 简单版 图片 倒计时 <template><view class"guide fcc" :style"{ background: url(${ imgUrl }) no-repeat}"><view class"skip_btn" cli…

黑神话悟空,高清壁纸、原画,游戏截图

黑神话悟空&#xff0c;高清壁纸、原画&#xff0c;游戏截图&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/cd17c05c4f33

c++每日练习记录4-(递归思想)

题解1迭代&#xff1a; 利用利用两个新的指针&#xff0c;一个用于保存输出的初始节点&#xff0c;另外一个用于地址的迭代指向。 ListNode *mergeTwoLists(ListNode *list1, ListNode *list2){ListNode *list_node new ListNode(0);ListNode *list_node1 list_node;while (l…

springboot中后缀匹配模式useSuffixPatternMatch、useTrailingSlashMatch的源码匹配分析

背景&#xff1a; 上篇文章&#xff0c;已经说了&#xff0c;如果我们直接debug调试没法找到源码中具体的代码&#xff0c;那么就可以通过jd-gui反编译的方式通过搜关键词的方式来找到源码中具体的位置&#xff0c;这次简单说下spring中的两种后缀匹配模式useSuffixPatternMat…

进外包,对简历是否有影响?

hello 大家好 今天来跟大家聊聊外包&#xff0c;主要是最近很多朋友私信问我&#xff0c;去外包公司会不会去自己的简历产生影响。 外包类型 我们先来聊聊外包类型&#xff1b;第一种类型&#xff0c;人头外包&#xff0c;也就是你入职的公司是没有开发岗位&#xff0c;只是把你…

机器人学——逆向运动学(机械臂)

正/逆运动学对比 求解 求解目标 Reachable workspace 与 Dexterous workspace Subspace 解的数目 多重解 解的选择 求解方法 栗子一 x,y,fai已知&#xff0c;求解theta(1,2,3)的具体数值 几何法 余弦定理定义&#xff1a;对于任意三角形ABC&#xff0c;设其三个内角分别为…

大数据技术之Zookeeper客户端 API 操作(4)

目录 客户端 API 操作 IDEA 环境搭建 创建 ZooKeeper 客户端 创建子节点 获取子节点并监听节点变化 判断 Znode 是否存在 客户端向服务端写数据流程 客户端 API 操作 前提: 保证 hadoop12、hadoop13、hadoop14 服务器上的 Zookeeper 集群服务端已启动。 IDEA 环境搭建…

设计模式---简单工厂模式

简单工厂模式&#xff08;Simple Factory Pattern&#xff09; 是一种创建型设计模式&#xff0c;它定义了一个工厂类&#xff0c;通过这个工厂类可以创建不同类型的对象。简单工厂模式的主要目的是将对象的创建逻辑集中在一个地方&#xff0c;简化客户端的代码&#xff0c;使得…

黑神话 悟空 配置 Mac玩游戏

兄弟们&#xff0c;这次《黑神话&#xff1a;悟空》真的是全网吹爆了&#xff01;我提前开香槟拿个年度游戏好吧&#xff01;Mac玩家也不用担心&#xff0c;系统兼容工具CrossOver也在第一时间支持了《黑神话&#xff1a;悟空》&#xff0c;现在你可以直接在Mac上玩《黑神话&am…

CSS的:target伪类:动态URL定位样式的指南

CSS的:target伪类是一种强大的工具&#xff0c;它允许开发者根据URL的锚点&#xff08;即页面内某个元素的ID&#xff09;来改变对应元素的样式。这在创建可滚动的页面、文章目录跳转、或任何需要通过URL直接指向页面特定部分的场景中非常有用。本文将详细介绍:target伪类的使用…

Python实现人脸轮廓提取

目录 一、背景知识1.1 人脸检测和轮廓提取的意义1.2 人脸检测方法概述1.3 轮廓提取方法概述二、常用的人脸轮廓提取方法2.1 基于边缘检测的轮廓提取2.2 基于形态学操作的轮廓提取2.3 基于特征点检测的轮廓提取三、Python实现人脸轮廓提取3.1 安装依赖库3.2 使用Dlib进行人脸检测…

World of Warcraft [CLASSIC] the Eye of Eternity [EOE] P1-P2

World of Warcraft [CLASSIC] the Eye of Eternity [EOE] 永恒之眼&#xff08;蓝龙&#xff09; 第一阶段 第二阶段 第三阶段 载具1-6技能介绍 World of Warcraft [CLASSIC] the Eye of Eternity [EOE]_永恒之眼 eoe-CSDN博客 永恒之眼怎么出副本呢&#xff0c;战斗结束&am…

嵌入式学习----网络通信之TCP协议通信

TCP&#xff08;即传输控制协议&#xff09;&#xff1a;是一种面向连接的传输层协议&#xff0c;它能提供高可靠性通信(即数 据无误、数据无丢失、数据无失序、数据无重复到达的通信) 适用情况&#xff1a; 1. 适合于对传输质量要求较高&#xff0c;以及传输大量数据 的通信。…

Leetcode 2760.最长奇偶子数组

给你一个下标从 0 开始的整数数组 nums 和一个整数 threshold 。 请你从 nums 的子数组中找出以下标 l 开头、下标 r 结尾 (0 < l < r < nums.length) 且满足以下条件的 最长子数组 &#xff1a; nums[l] % 2 0对于范围 [l, r - 1] 内的所有下标 i &#xff0c;num…