06 antdesign react Anchor 不同页面之间实现锚点
react Anchor 不同页面之间实现锚点
- 一、定义
- 二、使用步骤
- 三、开发流程
- (一)、组件
- (二)、页面布局
- (三)、点击事件
- (四)、总结说明
- 一、react单页面应用,当前页面的锚点
- 二、react单页面应用,不同页面的锚点
- 思路:锚点只能在当前页面使用,所以用useEffect()拦截
- 三、总结
- 五、其它
- 解决办法:加上location.hash可以解决
一、定义
Anchor锚点是:用于跳转到页面指定位置。
何时使用
需要展现当前页面上可供跳转的锚点链接,以及快速在锚点之间跳转。
二、使用步骤
1、首先在react项目中引用antd的锚点
import {Anchor} from 'antd';const { Link } = Anchor;
2、发现页面进行跳转而不是点位到页面的锚点,发现url有所改变
浏览器支持的锚点必须是通过hash来实现的,
三、开发流程
(一)、组件
(二)、页面布局
onClick()点击事件
<Anchor onClick={onAnchorChange}><div className={styles.digUlItem}>{item.des.map((littleItem, littleIndex) => {return (<Linkkey={littleItem}href={`#${littleItem}`}title={littleItem}></Link>);})}</div>
</Anchor>
(三)、点击事件
const onAnchorChange = (e,link) => {e.preventDefault();console.log('ddd e anchor>>>', e);console.log('ddd hash anchor>>>', link);};
(四)、总结说明
一、react单页面应用,当前页面的锚点
简单使用
- antd中Anchor组件阻止默认路由跳转
- 使用Anchor组件时,添加click方法:
1、阻止默认事件 e.preventDefault();阻止link的href跳转路由事件;
2、使用H5的scrollToAnchor添加页面滚动效果:
当前页面实现锚点,的点击事件,代码如下:
链接: react+antd中Anchor锚点踩坑===当前页面跳转,阻止点击事件的默认事件
handleClickFun= (e, link) => {e.preventDefault();if (link.href) {// 找到锚点对应得的节点let element = document.getElementById(link.href);// 如果对应id的锚点存在,就跳滚动到锚点顶部element && element .scrollIntoView({block:'start', behavior:'smooth'});}
};
// block:表示垂直方向的滚动对齐方式,“start”, “center”, “end”, 或 “nearest”
// behavior:表示动画效果,auto/smooth(滚动效果)
使用加强版
- 点击事件阻止a标签的默认
e.preventDefault(); - 原理:
【antdesign中anchor点击锚点后手动刷新页面,显示空白】是因为antdesign anchor底层代码是使用a标签来进行锚点跳转的,所以我们需要阻止a标签的默认行为。
antd Anchor底层是使用的a标签实现锚点功能的,而a标签的默认行为就是路由跳转(跳转到href),只要阻止a标签的默认行为就可以了。
-
控制台打印效果,比较如下:
-
阻止默认事件前:
-
阻止默认事件后:
二、react单页面应用,不同页面的锚点
思路:锚点只能在当前页面使用,所以用useEffect()拦截
- 详细思路:我在项目中使用的锚点并不是真正意义上的锚点,只是利用了点击a便签会在浏览器的地址栏url出现#后的参数,可以理解为vue中的路由传参query。
通过react的函数组件的钩子函数useEffect()。通过useEffect(handleFun,[第二个参数])的第二个参数对浏览器的地址栏进行拦截。我拦截的是:location.hash 对#号后的部分进行拦截。这里而外说一句:location对象,他是window对象和document对象的属性,它表示载入窗口的url,它可以解析url。 - 代码如下:
useEffect(() => {let myTimerclearTimeout(myTimer);if (!!location.hash) {const scrollToAnchor = (anchorName) => {if (anchorName) {let anchorElement = document.getElementById(anchorName);console.log('element>>>', anchorElement)if (anchorElement !== null) {let scrollHeight = anchorElement.offsetTop - 65;if (!!scrollHeight) {myTimer = setTimeout(() => {window.scrollTo({left: 0, //x轴top: scrollHeight, //y轴behavior: 'smooth'})}, 500);//useEffect()中清除定时器,return出去就可以了。return () => clearTimeout(myTimer)} else {return () => clearTimeout(myTimer)}}}}scrollToAnchor(location.hash)}}, [location.hash])
useEffect(() => {console.log('location.hash>>>', location.hash);if (!!location.hash) {const scrollToAnchor = (anchorName) => {console.log('anchorName>>>', anchorName)if (anchorName) {let anchorElement = document.getElementById(anchorName);console.log('element>>>', anchorElement)if (anchorElement !== null) {let scrollHeight = anchorElement.offsetTop - 65;console.log('anchorElement.offsetTop>>>', anchorElement.offsetTop)console.log('scrollHeight>>>', scrollHeight)let myTimerif (!!scrollHeight) {myTimer = setTimeout(() => {console.log('定时器>>>');window.scrollTo({left: 0, //x轴top: scrollHeight, //y轴behavior: 'smooth'})}, 500);//useEffect()中清除定时器,return出去就可以了。return () => clearTimeout(myTimer)} else {//useEffect()中清除定时器,return出去就可以了。return () => clearTimeout(myTimer)}}}}scrollToAnchor(location.hash)}}, [location.hash])
- 完整代码:
import React,{useEffect} from 'react';
import styles from './index.less';
import { Image, Space } from 'antd';
import FarmServerList from '@/components/productServer/FarmServerList';
import farm1 from '@/assets/productServer/farm1.png';
export default function index({ content = [] }) {useEffect(() => {console.log('location.hash>>>', location.hash);if (!!location.hash) {const scrollToAnchor = (anchorName) => {console.log('anchorName>>>', anchorName)if (anchorName) {let anchorElement = document.getElementById(anchorName);console.log('element>>>', anchorElement)if (anchorElement !== null) {let scrollHeight = anchorElement.offsetTop - 65;console.log('anchorElement.offsetTop>>>', anchorElement.offsetTop)console.log('scrollHeight>>>', scrollHeight)let myTimerif (!!scrollHeight) {myTimer = setTimeout(() => {console.log('定时器>>>');window.scrollTo({left: 0, //x轴top: scrollHeight, //y轴behavior: 'smooth'})}, 500);//useEffect()中清除定时器,return出去就可以了。return () => clearTimeout(myTimer)} else {//useEffect()中清除定时器,return出去就可以了。return () => clearTimeout(myTimer)}}}}scrollToAnchor(location.hash)}}, [location.hash])return (<div className={styles.home_box}>{content.map((item,index) => {if (item.id % 2 == 0) {return (<div className={styles.content} key={item.id}><div className={styles.left}><Space direction={'vertical'} size={'large'}><span className={styles.span1} id={`#${index}`}>{item.title}</span><FarmServerList list={item.list} align={item.id % 2} /></Space></div><div className={styles.right}><Image src={item.img} preview={{ mask: false }} /></div></div>);} else {return (<div className={styles.content} key={item.id}><div className={styles.left}><Image src={item.img} preview={{ mask: false }} /></div><div className={styles.right}><Space direction={'vertical'} size={'large'}><span className={styles.span} id={`#${index}`}>{item.title}</span><FarmServerList list={item.list} /></Space></div></div>);}})}</div>);
}
三、总结
实际效果:能够实现从一个页面跳转到另外一个页面,并且根据浏览器地址栏location.hash获取到#号后的内容,从一个页面的锚点->点击->跳转到另一个页面->根据getElementById获取真实节点->windowm.scrollTo页面滚动
BUG点:
现象:点击第一次跳转不能滚动,重新第二次跳转能够实现滚动。
原因分析:react框架有虚拟Dom,在useEffect不能获取到真实的Dom节点,因为页面组件的useEffect会在浏览器加载一个页面渲染的时候调用useEffect()两次,第一次拿不到,第二次能拿到节点。
但我们想要第一节进入页面就实现滚动
所以:考虑使用react的函数组件的另一个狗子函数useRef()
链接: useEffect执行时机
链接: useRef()操作真实dom节点
五、其它
解决办法:加上location.hash可以解决
浏览器支持的锚点必须是通过hash来实现的,
不行的话就不能用锚点的形式,只能自己写个组件,注册点击事件,然后获取要滚动到的元素的位置,设置window的scrollTop
React不引入antd如何实现锚点跳转
代码如下:
scrollToAnchor (id){
document.getElementById(id).scrollIntoView(false);
}
render:
-
this.scrollToAnchor(‘Summarize’)}>Summarize
-
this.scrollToAnchor(‘ProductFunction’)}>ProductFunction
-
this.scrollToAnchor(‘ToHelpAnswer’)}>ToHelpAnswer
相关文章:
06 antdesign react Anchor 不同页面之间实现锚点
react Anchor 不同页面之间实现锚点一、定义二、使用步骤三、开发流程(一)、组件(二)、页面布局(三)、点击事件(四)、总结说明一、react单页面应用,当前页面的锚点二、react单页面应用,不同页面的锚点思路:锚点只能在当前页面使用,…...
mysql调优-内存缓冲池
因本地查询和服务器查询相比服务器慢了很多,同样的数据,同样的sql查询,考虑了是不是链接太多了,自行查询了下,我使用的c3p0的链接池,配置一个小时超时,正常情况下是20多个链接,而mys…...
【LeetCode】每日一题(5)
目录 题目:2341. 数组能形成多少数对 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 题目:2341. 数组能形成多少数对 -…...
输入任意多个整数, 把这些数据保存到文件data.txt中.(按ctrl + z)
#pragma once #include <iostream> #include <fstream> using namespace std; /* 输入任意多个整数, 把这些数据保存到文件data.txt中. 如果在输入的过程中, 输入错误, 则提示用户重新输入. 指导用户输入结束(按ctrl z) [每行最多保存10个整数] */ int main() { …...
Mysql数据库的时间(3)一如何用函数插入时间
暂时用下面四个日期函数插入时间 如:insert into Stu(time) values (now()); Mysql的时间函数描述对应的Mysql的时间类型now()/sysdate()NOW()函数以YYYY-MM-DD HH:MM:SS返回当前的日期时间date/time/dateTime/timeStamp/yearcurDate()/current_date()返回当前的日期YYYY-M…...
关于eval函数(将JSON格式的字符串转换成JSON格式对象)
<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>关于eval函数</title> </head> <body> <!--JSON是一种行业内的数据交换格式标准。在JS当中以对象的形式存在…...
2023最强软件测试面试题,精选100 道,内附答案版,冲刺金3银4
精挑细选,整理了100道软件测试面试题,都是非常常见的面试题,篇幅较长,所以只放出了题目,答案在评论区! 测试技术面试题 1、什么是兼容性测试?兼容性测试侧重哪些方面? 2、我现在有…...
一文搞懂Docker容器里进程的 pid 是如何申请出来的?
如果大家有过在容器中执行 ps 命令的经验,都会知道在容器中的进程的 pid 一般是比较小的。例如下面我的这个例子。 # ps -ef PID USER TIME COMMAND1 root 0:00 ./demo-ie13 root 0:00 /bin/bash21 root 0:00 ps -ef 不知道大家是否和我一样…...
若依框架如何新增自定义主题风格
若依框架新增主题风格1.实现结果2.实现步骤2.1Settings目录下2.2 variables.scss2.3 sidebar.scss2.4 Logo.vue2.5 Siderbar目录下的index.vue1.实现结果 2.实现步骤 需要改动的文件目录: 2.1Settings目录下 <div class"setting-drawer-block-checbox-it…...
C语言格式化输入和输出; Format格式化
Format格式化 %1s或者%2s,%3s:取字符串的前1,2或者3位。%*c:屏蔽一个字符。%[A-Z]:取一个A到Z的值。 %[^a-z]:不取a到z的值。 %[^\n]:取非换行之前的值。printf("%5d", a):左边补 格式化:有正则在其中。 int main() {printf("%5d\n&quo…...
Revit教程:怎么关掉工具栏的实时提示?
一、Revit中如何关闭工具栏的实时帮助提示 如图1所示,Revit会对每一个命令有一个简单的图文说明,方便不熟悉软件的用户使用。对于已经熟悉软件的用户,会觉得鼠标在菜单上悬停时弹出的实时帮助页面很干扰使用,而且很占内存资源&…...
javascript 简介
JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备。JavaScript 是脚本语言JavaScript 是一种轻量级的编程语言。JavaScript 是可插入 HTML 页面的编程代码。JavaScript…...
医学图象分割常用损失函数(附Pytorch和Keras代码)
对损失函数没有太大的了解,就是知道它很重要,搜集了一些常用的医学图象分割损失函数,学习一下! 医学图象分割常见损失函数前言1 Dice Loss2 BCE-Dice Loss3 Jaccard/Intersection over Union (IoU) Loss4 Focal Loss5 Tvesky Loss…...
【新2023】华为OD机试 - 病菌感染(Python)
华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 病菌感染 题目 在一个地图中(地图有N*N个区域组成) 有部分区域被感染病菌 感染区域每天都会把周围上下左右的四个区域感染 请根据给定的地图计算多少天以后全部区域都会被感染 如果初始地图上所有区域都…...
QGIS中进行批量坡向计算
QGIS中进行坡向计算1. 坡向计算中的Z因子(垂直单位与水平单位的比值)2. 坡向计算步骤坡度计算的姊妹篇–坡向计算来了 1. 坡向计算中的Z因子(垂直单位与水平单位的比值) z 因子是一个转换因子,当输入表面的垂直坐标&…...
Redis持久化机制
一、RDB RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。 RDB是Redis默认的持久化机制 - RDB持久化文件,速度比较快,而且存储的是一个二进制的文件,传输起来很方便。 - RD…...
2、VUE面试题
1, 如何让CSS只在当前组件中起作用?在组件中的style前面加上scoped2、<keep-alive></keep-alive>的作用是什么?keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。3, vue组件中如何获取dom元素?使…...
DeepSort:论文翻译
文章目录摘要1、简介2、利用深度关联度量进行排序2.1、轨迹处理和状态估计2.3、匹配的级联2.4、深度外观描述符3、实验4、结论论文链接:https://arxiv.org/pdf/1703.07402.pdf摘要 简单在线实时跟踪(SORT)是一种实用的多目标跟踪方法,专注于简单、有效的…...
Debezium系列之:重置Sqlserver数据库的LSN拉取历史数据
Debezium系列之:重置Sqlserver数据库的LSN拉取历史数据 一、需求背景二、理解LSN三、sqlserver offset数据样式四、写入历史LSN五、观察历史数据六、拉取最新数据一、需求背景 需要重新拉取sqlserver数据库采集表的历史数据或者connector故障,从指定LSN处拉取历史数据二、理解…...
一起Talk Android吧(第四百九十四回:在Android中使用MQTT通信四)
文章目录 问题概述解决办法经验总结各位看官们大家好,这一回中咱们说的例子是" 在Android中使用MQTT通信四",本章回内容与前后章节内容无关联。闲话休提,言归正转,让我们一起Talk Android吧! 问题概述 我们在很早之前介绍过MQTT的用法,本章回是在原来的基础上…...
【vcpkg】cpprestsdk之64位编译链接及踩坑
▒ 目录 ▒🛫 问题描述1️⃣ 多版本vs报错指定VS路径2️⃣ error LNK2001: 问题排查通过IDA打开lib文件,确认导出内容查看源码增加参数--editable,重新编译3️⃣ error LNK2001: 外部符号__imp_?close_...去除__imp_🛬 结论vcpkg…...
初始QML
Qt Quick的介绍 : Qt Quick是QML的标准类型和功能库。它包括视觉类型,交互类型,动画,模型和视图,粒子效果和着色器效果。QML 应用程序开发人员可以通过单个导入语句访问所有这些功能,简单来说Qt Quick是一…...
SpringAOP切面实例实现对数据过滤返回,SpringAOP切面实现对用户权限控制,通过@Around注解过滤修改方法返回值
文章目录需求内容:实现:步骤一:导入SpringAOP相关依赖pom.xml步骤二:自定义两个注解步骤三:需要用到的实体类**步骤四:切面具体实现**用法1.需要过滤返回值的方法添加注解FilterByUser2.数据Dto在需要过滤的字段添加Fi…...
【Kubernetes】【九】Label,Deployment,Service
Label Label是kubernetes系统中的一个重要概念。它的作用就是在资源上添加标识,用来对它们进行区分和选择。 Label的特点: 一个Label会以key/value键值对的形式附加到各种对象上,如Node、Pod、Service等等一个资源对象可以定义任意数量的L…...
RuoYi-Vue部署(Nginx+Tomcat)
环境搭建RuoYi-Vue搭建、Linux安装Nginx、Linux安装JDK8、Linux安装MySql8、Linux安装Redis、Linux安装Tomcat9前端打包 1.ruoyi-ui鼠标右键-->打开于终端2.安装依赖:npm install --registryhttps://registry.npm.taobao.org-->node_modules3.编译打包&#x…...
Hive提升篇-Hive修改事务
简介 Hive 默认是不允许数据更新操作的,毕竟它不擅长,即使在0.14版本后,做一些额外的配置便可开启Hive数据更新操作。而在海量数据场景下做update、delete之类的行级数据操作时,效率并不如意。 简单使用 修改HIVE_HOME/conf/hi…...
PMP项目管理未来的发展与趋势
什么是项目管理?关于项目管理的解释主要是基于国际项目管理三大体系不同的解释及本领域权威专家的解释。 项目管理就是以项目为对象的系统管理方法,通过一个临时性的、专门的柔性组织,对项目进行高效率的计划、组织、指导和控制,以…...
深度学习算法面试常问问题(三)
pooling层是如何进行反向传播的? average pooling: 在前向传播中,就是把一个patch的值取平均传递给下一层的一个像素。因此,在反向传播中,就是把某个像素的值平均分成n份 分配给上一层。 max pooling: 在前…...
GEE学习笔记 八十七:python版GEE动态加载地图方法
在Google Earth Engine的python版API更新后,之前使用folium动态加载地图的代码就不能在正常运行,因为整个Google Earth Engine的地图加载服务的URL发生了更新,所以我们也需要更新相关绘制方法。下面我会讲解一种新的绘制方法,大家…...
第三章 SQL错误信息
文章目录第三章 SQL错误信息SQLCODE 0和100SQLCODE -400检索SQL消息文本第三章 SQL错误信息 下表列出了SQL数字错误代码及其错误消息。这些代码作为SQLCODE变量值返回。 注意:虽然本文档将错误代码列为负值,但JDBC和ODBC客户端始终收到正值。例如&…...
郑州网站制作多少钱/网络推销
先放两篇整理内置对象较全的博客: https://segmentfault.com/a/1190000011467723 https://www.cnblogs.com/liuluteresa/p/6413988.html 再来一篇面试题 https://blog.csdn.net/mino_miao/article/details/81167867 对下述定时器面试题中同步异步问题的详解…...
广州网站建设费/郑州seo排名优化
为什么80%的码农都做不了架构师?>>> 在上一篇文章《》中,我们详细说明了一下如何创建一个可以使用增删改操作的jqGrid。 但是在实际的修改、新增保存中,会看到如下的错误提示:error Status:"OK".Error code…...
宁波网站推广方式/电商网站开发
文章目录二分图一. 二分图的判断二.二分图的最大匹配三. 二分图最小点覆盖和最大独立集四. 二分图的最大权匹配二分图 二分图又称作二部图, 设G(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i&…...
ps切片怎么做网站/南宁seo计费管理
删除字典中的null 我们在处理数据库接口的过程中,如果数据中出现null,我们是没法处理的。我在使用NSUserDaults保存后,出现崩溃。 null产生原因 null是后台在处理数据的时候,如果没有设置value值,数据库默认填充的值。…...
在农村开个网站要多少钱/企业关键词推广
为什么80%的码农都做不了架构师?>>> 方法一: 一般会更新操作都会判断null值,为null就不更新对应的字段。但是有时候需要把特定的字段更新为null,使用mybatis-plus时可以在实体类特定属性上面加注解TableField(strateg…...
做情诗网站/快速开发平台
用法一: 在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局。那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在代码中动态的更…...