当我们在做 SPA 应用的时候,为了兼容老的浏览器(如IE9)我们不得不放弃 HTML5 browser history api 而只能采用 hash 路由的这种形式来实现前端路由,但是因为 hash 被路由占据了,导致本来不是问题的锚点功能却成了一个不大不小的问题。

经过我自己的搜索目前有两种方式能够解决这个问题,为了能在 react 生态下面简单优雅的使用,我专门封装了一个锚点组件 react-anchor-without-hash,它使用了类似原生 a 标签的写法,并且可以支持滚动的距离和指定滚动的元素,尽可能的满足业务的需求。

不过在介绍这个组件之前,还是得先说一下两种基本的解决方案。

两种解决方案

scrollIntoView

scrollIntoView 方法可以让当前的元素滚动到浏览器窗口的可视区域内。

它的使用方法如下:

var element = document.getElementById("box");

element.scrollIntoView();

这个 api 兼容 IE8 及以上的浏览器,所以可以放心使用。

注:IE10 之前的 IE 浏览器部分支持,具体请查看Can I Use

scrollTop

另一个方法是使用 scrollTop 这个 api,这个方法的兼容性也是比较好的,这个方法相比于 scrollIntoView 来说需要你自己定义要滚动的元素和要滚动的高度,虽然看起来麻烦一些,但是好处是自由度比较高,试想一下下面的场景:

  • 你有一个 A 元素在 Content 里面,Content 设置了滚动,你想让 A 元素滚动到可视区域内。

  • 如果用 scrollIntoView 会变成下面这样,A 元素显示到整个浏览器视口的最上面,这样就会和 Header 重合,被遮挡住一部分。

  • 所以这时候需要使用 scrollTop 去设置 content 滚动距离,比如说是 60px,最后的效果就变成了我们想要的结果。

使用方式如下:

const cont = document.querySelector('#container');
const a = document.querySelector('#a'); cont.scrollTop = a.offsetTop + 60;

react-anchor-without-hash

以上两种方式如果想方便的在项目里面使用多少都需要封装一下,而且使用起来和原生的 a 标签形式也相差甚远。

但是如果是在 react 技术栈下,我们可以利用组件来封装一个类似 a 标签的锚点,这样在使用形式上,我们就能更接近于原生的方式,降低使用成本。

于是我写了这个 react 组件,兼容以上两种方案,让你能够非常简单的实现锚点,如果使用了该组件的话,上面的实现方式就会变成下面这样:

import Anchor from 'react-anchor-without-hash'

// ......

const anchorProps = {
type: 'scrollTop',
container: '#container',
interval: 60
} <div id="container" style={{position: 'relative', overflow: 'scroll'}}>
<Anchor name="a" {...anchorProps}>
<div>
<h2>This is a</h2>
<div>There are some text...</div>
</div>
</Anchor>
</div>

这时候你只需要在页面的地址栏输入: http://somehost/path/#hash?_to=a 页面就会让 A 滚动到你想要的位置啦!

github:https://github.com/kwzm/react-anchor-without-hash

demo:https://kwzm.github.io/react-anchor-without-hash/

codesandbox: https://codesandbox.io/embed/react-anchor-without-hash-2xq2h

欢迎讨论和Star!!!

React SPA 应用 hash 路由如何使用锚点的更多相关文章

  1. H5小技巧之——巧用<a>标签锚链接(#锚点链接 #页面特定位置 #DOM定位 #hash路由中使用锚链接)

    #作者:矩阵鱼--代码中游泳的咸鱼 前端开发中,常遇到定位到页面某特定位置的需求,JavaScript提供的el.scrollIntoView() 和 el.scrollIntoViewIfNeede ...

  2. SPA中,Node路由优先级高于React路由

    一.问题描述 在一场面试中,面试官问到了React和Node路由之间的关系. 现在SPA(单页面应用)的使用越来越广. Node(后台)和React(前端)都有自己的路由,当我页面访问一个URL的时候 ...

  3. SPA中前端路由基本原理与实现方式

    SPA 前端路由原理与实现方式 通常 SPA 中前端路由有2中实现方式,本文会简单快速总结这两种方法及其实现: 修改 url 中 Hash 利用 H5 中的 history Hash 我们都知道 ur ...

  4. React+DvaJS 之 hook 路由权限控制

    博客 学院 下载 GitChat TinyMind 论坛 APP 问答 商城 VIP 活动 招聘 ITeye 写博客 发Chat 登录注册 原 React+DvaJS 之 hook 路由权限控制 20 ...

  5. HahsRouter hash 路由

    无刷新页面,切换视图,用hash 实现路由切换,本身附带history记录,简单舒服. 最近用vue,看到vue-route的路由,做单页应用切换视图真心易如反掌,分分钟爽到不行.为了加深理解其内涵原 ...

  6. 告别 hash 路由,迎接 history 路由

    博客地址:https://ainyi.com/69 三月来了,春天还会远吗.. 在这里,隆重宣布本博客告别 Vue 传统的 hash 路由,迎接好看而优雅的 history 路由~~ 映照官方说法 v ...

  7. 前端hash路由基本原理,及代码的基本实现

    路由就是指随着浏览器地址栏的变化,展示给用户的页面也不相同. 早期的路由都是后端实现的,直接根据 url 来 reload 页面,页面变得越来越复杂服务器端压力变大,随着 ajax 的出现,页面实现非 ...

  8. hash路由

    class HashRouter{ constructor(){ //用于存储不同hash值对应的回调函数 this.routers = {}; window.addEventListener('ha ...

  9. ASP.NET .Core 集成 React SPA 应用

    AgileConfig的UI使用react重写快完成了.上次搞定了基于jwt的登录模式(AntDesign Pro + .NET Core 实现基于JWT的登录认证),但是还有点问题.现在使用reac ...

随机推荐

  1. 【POJ - 2253】Frogger (Floyd算法)

    -->Frogger 中文翻译 Descriptions: 湖中有n块石头,编号从1到n,有两只青蛙,Bob在1号石头上,Alice在2号石头上,Bob想去看望Alice,但由于水很脏,他想避免 ...

  2. Java map笔记

    Map 是一个键值对的集合 花和尚 豹子头 鲁智深 林冲 如果想要从map中获得值,可以根据键 Map<Key,velue> Map虽然是集合,但是和collection的接口无关 我们可 ...

  3. 【译】宣告推出.NET Core 3.0 Preview 7(英雄的黎明)

    今天,我们宣布推出.NET Core 3.0 Preview 7.我们已经从创建新特性阶段过渡到了完善版本阶段.对于其余的预览版,我们将把重点放在质量(改进)上. 在Windows,macOS和Lin ...

  4. 改MySQL的编码方式,解决jdbc MySQL中文乱码问题

    进MySQL安装目录,打开my.ini 这两个地方改成gbk 重启服务

  5. host配置

    host添加地址 今天是我第一天入职,坐到工位的第一件事就是配置host,因为连接测试环境需要本地授权,所以要配置.这里简单记录下配置中遇到的问题和操作的步骤 操作环境是win10,之前公司一直使用的 ...

  6. 注解与AOP切面编程实现redis缓存与数据库查询的解耦

    一般缓存与数据库的配合使用是这样的. 1.查询缓存中是否有数据. 2.缓存中无数据,查询数据库. 3.把数据库数据插入到缓存中. 其实我们发现 1,3 都是固定的套路,只有2 是真正的业务代码.我们可 ...

  7. python创建虚拟环境(Windows)

    >>>构建Python虚拟环境的目的是为了防止真实环境被破坏!!! >>>每一个项目建议用一个虚拟环境为了防止软件版本号冲突!!! 1.在终端切换到一个新的磁盘 如 ...

  8. 用mongodb 固定集合实现只保留固定数量的记录,自动淘汰老旧数据

    在一个保存report记录的场景中,我们使用MongoDB进行数据存储 example: db: report Collection: daily_report 创建db:  use report; ...

  9. 深入理解Apache Kafka

    一.介绍 Kafka在世界享有盛名,大部分互联网公司都在使用它,那么它到底是什么呢? Kafka由LinkedIn公司于2011年推出,自那时起功能逐步迭代,目前演变成一个完整的平台级产品,它允许您冗 ...

  10. 浅谈Ceph纠删码

    目  录第1章 引言 1.1 文档说明 1.2 参考文档 第2章 纠删码概念和原理 2.1 概念 2.2 原理 第3章 CEPH纠删码介绍 3.1 CEPH纠删码用途 3.2 CEPH纠删码库 3.3 ...