一、需求背景

1、需要实现小程序新功能引导
2、不使用第三方库(第三方组件试了几个,都是各种兼容性问题,放弃)

二、实现步骤

1、写一个公共的guide组件,代码如下
components/Guide/index.tsx文件

import React, { useEffect, useState } from "react";
import Taro from "@tarojs/taro";
import { View, Button } from "@tarojs/components";
import { AtCurtain } from "taro-ui";import "./index.less";interface Props {// 需要指引的整体元素,会对此块增加一个整体的蒙层,直接用guild元素包裹即可children: React.ReactNode;// 指引的具体domguildList: {content: string; // 指引内容id: string; // 指引的id  --eg:  'test'}[];// 是否默认对被引导的dom添加高亮,只对子元素的子元素动态添加类名【cur-guide】isAuto?: boolean;// 1、此字段只对isAuto为false时生效// 2、部分页面,需传入此字段微调整距离顶部的距离otherHeight?: number;// 此字段只对isAuto为false时生效// activeGuide值变化时触发,用来在isAuto为false时,告知外部需要高亮哪个dom,请外部根据此判断添加类明【cur-guide】onChange?: (activeGuideId) => void;
}interface TaroElementProps {className?: string;children?: React.ReactNode;props: {id: string;[key: string]: any;};
}
type TaroElement = React.ReactElement<TaroElementProps>;const Guide = (props: Props) => {const [isOpened, setIsOpened] = useState(true);const [activeGuide, setActiveGuide] = useState(0);const [tipPosition, setTipPosition] = useState({top: 0,left: 0,});useEffect(() => {if (!props.isAuto) {updatePosition();props.onChange?.(props.guildList[activeGuide]?.id);}}, [activeGuide]);const updatePosition = () => {Taro.nextTick(() => {if (!props.guildList[activeGuide]) return;const query = Taro.createSelectorQuery();query.select(`#${props.guildList[activeGuide].id}`).boundingClientRect().selectViewport().scrollOffset().exec((res) => {if (res && res[0] && res[1]) {// res[0] 是元素的位置信息// res[1] 是页面滚动的位置信息const rect = res[0];const scrollTop = res[1].scrollTop;// 计算元素距离顶部的实际距离(包含滚动距离)const actualTop = rect.top + scrollTop;setTipPosition({top:actualTop +rect.height -(props.otherHeight || 0) +12,left: rect.left + rect.width / 2,});}});});};const onPre = () => {if (activeGuide <= 0) {setActiveGuide(0);setIsOpened(false);return;}setActiveGuide(activeGuide - 1);};const onNext = () => {if (activeGuide >= props.guildList.length - 1) {setActiveGuide(props.guildList.length - 1);setIsOpened(false);return;}setActiveGuide(activeGuide + 1);};const renderTip = () => {return (<ViewclassName="cur-guide-tip"style={{top: `${tipPosition.top}px`,left: `${tipPosition.left}px`,}}><Button onClick={onPre}>上一步</Button><Button onClick={onNext}>下一步</Button></View>);};// 递归处理子元素,找到对应index的元素添加提示内容const enhanceChildren = (children: React.ReactNode) => {return React.Children.map(children, (child) => {if (!React.isValidElement(child)) return child;// 如果当前元素是数组(比如map渲染的列表),需要特殊处理if (child.props.children) {// 处理子元素const enhancedChildren = React.Children.map(child.props.children,(subChild) => {if (!React.isValidElement(subChild)) return subChild;const subChildProps = (subChild as TaroElement).props as any;const isCurrentActive =subChildProps.id === props.guildList[activeGuide]?.id;// 如果是当前激活的索引,为其添加提示内容if (isCurrentActive && isOpened) {const subChildProps = (subChild as TaroElement).props;return React.cloneElement(subChild as TaroElement, {className: `${subChildProps.className || ""} ${isCurrentActive ? "cur-guide" : ""}`,children: [...(Array.isArray(subChildProps.children)? subChildProps.children: [subChildProps.children]),renderTip(),],});}return subChild;});return React.cloneElement(child as TaroElement, {...child.props,children: enhancedChildren,});}return child;});};const renderBody = () => {return (<><View>{props.children}</View>{isOpened && renderTip()}</>);};const renderBodyAuto = () => {return <View>{enhanceChildren(props.children)}</View>;};return (<View className="fc-guide">{props.isAuto ? renderBodyAuto() : renderBody()}{isOpened && (<AtCurtain isOpened={isOpened} onClose={() => {}}></AtCurtain>)}</View>);
};
export default Guide;

components/Guide/index.less文件

.fc-guide {position: relative;.at-curtain {z-index: 20;.at-curtain__btn-close {display: none;}}// 这个是相对顶部距离的定位(isAuto为false时).cur-guide-tip {padding: 24px;background-color: #fff;position: absolute;z-index: 22;transform: translate(-50%, 0);}// 相对当前高亮元素的定位(isAuto为true时).cur-guide {background: #f5f5f5;position: relative;z-index: 22;.cur-guide-tip {bottom: 0 !important;left: 50% !important;transform: translate(-50%, 100% + 12px);}}
}

2、使用方式
a.isAuto为true时的传值结构
在这里插入图片描述
b.isAuto为false时
需要配合onChange事件将当前激活id传给父组件,然后父组件再根据当前激活id去选择高亮哪个dom元素(类名判断写在和id设置同一个dom上),然后给对应dom绑上’cur-guide‘类名即可

最终效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/85241.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/85241.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/85241.shtml

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

相关文章

键盘动作可视化技术浅析:如何做到低延迟显示

在做屏幕录制或者操作演示的时候&#xff0c;你是否遇到过这样的问题&#xff1a;观众看不清你按了哪个键、点了哪里&#xff1f;这是能完美解决这个问题的小工具Keyviz。它可以把你的键盘输入和鼠标点击实时显示在屏幕上&#xff0c;清晰直观&#xff0c;特别适合教学、录屏、…

Prufer序列 学习笔记

文章目录 P r u f e r Prufer Prufer 序列对树建立 P r u f e r Prufer Prufer 序列对 P r u f e r Prufer Prufer 序列重建树 应用Cayley 公式[HNOI2004] 树的计数「雅礼集训 2017 Day8」共[THUPC 2018] 城市地铁规划CF156D Clues[ARC106F] Figures P r u f e r Prufer Pruf…

高性能场景使用Protocol Buffers/Apache Avro进行序列化怎么实现呢

我们以Protocol Buffers&#xff08;Protobuf&#xff09;和Apache Avro为例&#xff0c;分别展示高性能序列化的实现方式。 由于两者都需要定义Schema&#xff0c;然后生成代码&#xff0c;因此步骤包括&#xff1a; 1. 定义Schema文件 2. 使用工具生成Java类 3. 在代码中…

iOS端网页调试 debug proxy策略:项目中的工具协同实践

移动开发中的调试&#xff0c;一直是效率瓶颈之一。特别是当前 Web 前端与 App 原生高度耦合的背景下&#xff0c;页面调试不仅受限于浏览器&#xff0c;还要面对 WebView 实现差异、系统权限控制、设备多样性等复杂情况。 但我们是否可以构建一套**“设备无关”的调试工作流*…

springboot项目启动报错:spring boot application in default package

启动类报错&#xff1a; 问题&#xff1a; springboot的启动方法不能直接在java目录下 解决&#xff1a; 1.使用CompentScan 和EnableAutoConfiguration注解 2.启动类放在java目录下的package目录下

机器学习实验报告5-K-means 算法

4.1 k-means算法简介 聚类分析&#xff0c;作为机器学习领域中的一种无监督学习方法&#xff0c;在数据探索与知识发现过程中扮演着举足轻重的角色。它能够在没有先验知识或标签信息的情况下&#xff0c;通过挖掘数据中的内在结构和规律&#xff0c;将数据对象自动划分为多个类…

【已解决】yoloOnnx git工程部署

首先 yoloonnx一个VS工程下来整个工程大概1-2个g的大小因此在git的过程中总是会因为文件超过100M而触发报错&#xff0c;上传不上去&#xff0c;因此现在需要做一个过滤才能把工程重新上传上去&#xff0c;那么这个时候别人需要下载下来的时候确实不完整的工程&#xff0c;因此…

如何轻松地将照片从电脑传输到安卓手机

一些安卓用户正在寻找有效可靠的方法&#xff0c;将照片从电脑传输到安卓设备。如果您也想将有趣或难忘的照片导入安卓手机或平板电脑&#xff0c;可以参考这篇文章&#xff0c;它提供了 6 种可靠的方法&#xff0c;让您轻松传输照片。 第 1 部分&#xff1a;如何通过 Android …

准备纯血鸿蒙理论高级认证的一些心得

最近在准备纯血鸿蒙理论高级认证&#xff0c;一些心得记录下来&#xff0c;希望早日考过高级&#xff01; 一、考试目标&#xff1a; HarmonyOS核心技术理念HarmonyOS应用架构设计ArkTS原理和实践ArkUI开发HarmonyOS关键技术能力开发工程管理、代码编辑、调试与定位应用上架运…

义乌购拍立淘API接入指南

一、接口概述 拍立淘是义乌购平台提供的以图搜货服务&#xff0c;通过HTTP RESTful API实现。当前版本为v3.2&#xff0c;支持JPG/PNG格式图片&#xff08;≤5MB&#xff09;&#xff0c;返回相似商品列表及供应链信息。 二、接入准备 申请开发者账号 # 开发者注册示例&…

Web 连接和跟踪

大家读完觉得有帮助记得及时关注和点赞&#xff01;&#xff01;&#xff01; 抽象 网络跟踪是一种普遍且不透明的做法&#xff0c;可实现个性化广告、重新定位和转化跟踪。 随着时间的推移&#xff0c;它已经演变成一个复杂的侵入性生态系统&#xff0c;采用越来越复杂的技术来…

前端技术栈与 SpreadJS 深度融合:打造高效数据表格应用

引言 在当今数字化的时代&#xff0c;数据表格应用在各种 Web 项目中扮演着至关重要的角色。从企业级的管理系统到电商平台的商品展示&#xff0c;数据表格都是用户与数据交互的重要界面。前端技术栈如 JavaScript、HTML 和 CSS 为构建用户界面提供了强大的工具和方法&#xf…

如何用ai描述缺陷(bug)

附件1&#xff1a; 附件2&#xff1a; 将附件1和附件2发送给deepseek&#xff0c;且输入对话框的文字&#xff1a; 然后进入禅道用户登录 - 禅道 ### **缺陷报告&#xff1a;登录功能无响应缺陷** **提交平台**&#xff1a;禅道缺陷管理系统 **发现环境**&#xff1a;测试环…

软考 系统架构设计师系列知识点之杂项集萃(89)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;88&#xff09; 第161题 下面可提供安全电子邮件服务的是&#xff08; &#xff09;。 A. RSA B. SSL C. SET D. S/MIME 正确答案&#xff1a;D。 解析&#xff1a; MIME&#xff08;Multi…

开源 Arkts 鸿蒙应用 开发(一)工程文件分析

文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发&#xff0c;公司安排开发app&#xff0c;临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 Arkts …

protobuf遇到protoc-gen-go: unable to determine Go import path for “xxx“

问题 这个错误是因为 .proto 文件中缺少必需的 go_package 选项。在 protobuf 生成 Go 代码时&#xff0c;这是关键配置项。 pandaVM:~/dev/pb$ protoc --go_out. pb.proto protoc-gen-go: unable to determine Go import path for "pb.proto"Please specify eithe…

linux unix socket 通信demo

好&#xff0c;下面是已经整合完善的版本&#xff1a; ✅ 功能点&#xff08;你要求的全部实现了&#xff09;&#xff1a; Unix Domain Socket (SOCK_STREAM) 服务端先启动&#xff1a;正常通信 客户端先启动&#xff1a;等待服务端直到连接成功 客户端每秒发送一条消息 服务端…

近期GitHub热榜推荐

【1】fluentui-system-icons (HTML) &#x1f468;‍&#x1f4bb; 作者&#xff1a; microsoft &#x1f4e6; 仓库&#xff1a; microsoft / fluentui-system-icons &#x1f310; 链接&#xff1a; https://github.com/microsoft/fluentui-system-icons ⭐ 星标&#xf…

Jupyter 是什么?基于浏览器的交互式计算环境

&#x1f9e0; 一、Jupyter 是什么&#xff1f; Jupyter 是一个基于浏览器的交互式计算环境&#xff0c;名字取自Julia Python R 三种语言&#xff0c;但现在已支持超过40种编程语言。它最核心的功能是让你在同一个文档&#xff08;.ipynb 文件&#xff09;中混合编写代码、…

CTF解题:[NSSCTF 2022 Spring Recruit]弱类型比较绕过

一、漏洞背景介绍 在 CTF&#xff08;Capture The Flag&#xff09;竞赛和 Web 安全测试中&#xff0c;PHP 语言的类型比较漏洞是常见的考点。这类漏洞源于 PHP 的弱类型特性&#xff0c;即当使用进行比较时&#xff0c;PHP 会自动进行类型转换&#xff0c;从而导致一些不符合…