React SPA 应用 hash 路由如何使用锚点

当我们在做 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!!!

原文地址:https://www.cnblogs.com/kwzm/p/11379999.html

时间: 2024-08-30 13:17:21

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

SPA学习之 - 路由插件(crossroads.js)

Crossroads.js是一个受Rails, Pyramid, Django, CakePHP等基于路由/分发(Route/Dispatch)方式处理路由的后端MVC框架启发的一套js专业路由库.它能够直接解析传入的字符串并根据相应的规则来过滤和验证路由,然后再执行下一步的操作. A duck can walk, fly and swim, but he can’t do any of these things well… crossroads.js是一个独立的库功能十分强大和灵活,而且职责单

HahsRouter hash 路由

无刷新页面,切换视图,用hash 实现路由切换,本身附带history记录,简单舒服. 最近用vue,看到vue-route的路由,做单页应用切换视图真心易如反掌,分分钟爽到不行.为了加深理解其内涵原理,遂决意写一个最简单的hash 路由. 思路很简单,自己维护一个 hash route 的哈希表,通过注册路由及其处理事件,通过hashchange来触发对应事件处理,有点像观察者模式的思想,先注册,再派发. 实现方法 maps 批量注册 add 单条注册 remove 单条删除 clear 全部

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

路由就是指随着浏览器地址栏的变化,展示给用户的页面也不相同. 早期的路由都是后端实现的,直接根据 url 来 reload 页面,页面变得越来越复杂服务器端压力变大,随着 ajax 的出现,页面实现非 reload 就能刷新数据,也给前端路由的出现奠定了基础.我们可以通过记录 url 来记录 ajax 的变化,从而实现前端路由.(可以根据不同的url来展示不同的页面,很好的优化了页面的交互体验.)目前有两种方式: 1:H5的history的新API(pushstate.replacestate.

关于vue 和react 中的hash与锚点冲突问题

// 可以利用事件委托进行处理hash和锚点的冲突问题. // handleAnchorClick(e){ if (e.target && e.target.tagName.toLowerCase() === 'a') { // 确定点击元素是不是a元素: // Determine whether the click element is a element; const href = e.target.href; // 确定你的锚点href const regx = /#锚点名字\/.+

React Native的原生路由

新项目移动端要用React-native搭建,于是又开启了新一波学习之旅 文档里查到的Navigator例子均为使用Navigator作为某个组件render方法的唯一返回值,这在某些情况下有些不符合人类思维(或者说是我的思维...),例如:微信,典型的上中下布局,进入消息/朋友/朋友圈分别指向三个页面,他们在互相切换时主要是页面中间部分发生改变,上部只是改变了几个文字,下部只是当前tab页的图标变为高亮 在这种需求下一.我理想的实现方式为: <View> <Header /> &

单页应用 WebApp SPA 骨架 框架 路由 页面切换 转场

这里收录三个同类产品,找到他们花了我不少时间呢. 张鑫旭写的mobilebone自述:mobile移动端,PC桌面端页面无刷新过场JS骨架,简单.专注!http://www.zhangxinxu.com/wordpress/2014/10/mobilebone-js-mobile-web-app-core/https://github.com/zhangxinxu/mobilebone/ 赵达写的spa自述:SPA是为构建WebApp设计的路由控制和视图转换框架http://zhaoda.net

react项目配置引入路由

要是用也是国际惯例,npm下!! npm install -S react-router 1 下完后直接import就可以使用,像这样 import { Router, Route, hashHistory } from 'react-router'; 1 Router是大壳子,类似于路由容器的东西 Route是具体实施路由的对象 hashHistory表示路由切换的hash值,决定最终结果 因为直接的项目结构比较建的随意,所以把目录进行了重新整理,把main.js变成一个大容器,不做任何业务主

React使用react-router-dom配置路由

一.什么是 react-router-dom React-router-dom 提供了 BrowserRouter,Route,Link 等 api,我们可以通过 dom 的事件控制路由 二.react-router-dom 的安装 在项目根目录终端引入: npm install react-router-dom --save-dev 三.react-router-dom 的使用 这里新建两个组件,分别为“home”和“detail”: 在 src 下新建 containers 文件夹,里面分别

React 子组件进行路由跳转

react路由跳转: 1.DOM跳转 <Link href={`/device/list`} to={`/device/add`}></Link> 2.js跳转 this.props.history.push("/device/add") 具体路由跳转细节,请自行百度 问题: 父组件: <TabPane tab="终端配置" key="1"> <A/> </TabPane> <Ta