React实现锚点跳转组件附带吸顶效果的示例代码
更新时间:2023年01月05日 08:52:24 作者:绘绘~
这篇文章主要为大家详细介绍了React如何实现移动端锚点跳转组件附带吸顶效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
React实现锚点跳转组件附带吸顶效果
import React, { useRef, useState, useEffect } from 'react'; import styles from './index.less'; import classnames from 'classnames'; function AnchorTabber(props) { const root = useRef(null); const header = useRef(null); const { attrbute = 'data-anchor', offsetY = 60, list = [], initialKey = list[0]?.key, children, } = props; const [state, setState] = useState({ activeKey: initialKey, }); const [key2Bottom, setKey2Bottom] = useState({ key2Bottom: {}, }); /** @type { HTMLDivElement } */ const scrollElement = document.querySelector('#root').firstChild; function scrollTo(key) { // if(!scrollElement) { // scrollElement = document.querySelector('#root').firstChild; // } const attribute = attrbute; /** @type { HTMLDivElement } */ const targetEl = root.current?.querySelector(`[${attribute}=${key}]`); if (targetEl) { const clientRect = targetEl.getBoundingClientRect(); const top = scrollElement.scrollTop + clientRect.top - offsetY; scrollElement.scrollTo({ top, behavior: 'smooth', }); // targetEl.scrollIntoView({ behavior: 'smooth', block: 'start' }); } } function updateElementsPosition() { const elements = document.querySelectorAll(`[${attrbute}]`); Array.from(elements).forEach(element => { const targetAttr = element.getAttribute(`${attrbute}`); const clientRect = element.getBoundingClientRect(); const bottom = clientRect.top + scrollElement.scrollTop; key2Bottom[targetAttr] = bottom; }); setKey2Bottom(key2Bottom); } function handleScroll() { const top = scrollElement.scrollTop + offsetY; // eslint-disable-next-line no-unused-vars const target = Object.entries(key2Bottom) .sort(([, v1], [, v2]) => v2 - v1) .find(([, v]) => v <= top); if (target) { setState({ activeKey: target[0], }); } } useEffect(() => { updateElementsPosition(); // document.addEventListener('touchstart', updateElementsPosition); scrollElement.addEventListener('scroll', handleScroll); return () => { // document.removeEventListener('touchstart', updateElementsPosition); scrollElement.removeEventListener('scroll', handleScroll); }; }); function handleItemClick(tabber) { scrollTo(tabber.key); } function render() { let { activeKey } = state; if(typeof(activeKey) === "undefined") { activeKey = initialKey } return ( <div className={styles.mAnchorTabber}> <div className={styles.header} ref={header}> {list?.map(tabber => ( <div className={classnames(styles.item, { [styles.active]: activeKey === tabber.key })} onClick={() => handleItemClick(tabber)} > {tabber.name} </div> ))} </div> <div className={styles.container} ref={root}> {children} </div> </div> ); } return render(); } export default AnchorTabber;
对应样式(less)
.mAnchorTabber { .header { display: flex; align-items: center; position: sticky; top: 0; height: .len(46) []; box-sizing: border-box; box-shadow: 0 .len(2) [] .len(2) [] .len(1) [] #c4c4c4; background-color: @basecolor; .item { height: 100%; flex-grow: 1; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-weight: 400; font-size: @font-size-base-normal; line-height: .len(20) []; &.active { background-color: @bgc-product-detail; color: @basecolor; } } } }
.len(46) []这个改成对应 px单位即可,本单位是为了移动端适配转换
测试test
对应测试文件
import React from 'react'; import { connect } from 'dva'; import AnchorTabber from '@/components/m/AnchorTabber'; @connect(({ common }) => ({ common, })) class ApplicationsRecord extends React.Component { constructor(props) { super(props); this.state = { list: [ { name: 'test1', key: 'test1', }, { name: 'test2', key: 'test2', }, { name: 'test3', key: 'test3', }, ], }; } render() { const { list } = this.state; const index2Attr = { 0: 'test1', 100: 'test2', 200: 'test3', }; return ( <AnchorTabber list={list}> <ul className="list"> {new Array(1000).fill(null).map((_item, index) => ( <li data-anchor={index2Attr[index]}>{index}</li> ))} </ul> </AnchorTabber> ); } } export default ApplicationsRecord;
到此这篇关于React实现锚点跳转组件附带吸顶效果的示例代码的文章就介绍到这了,更多相关React锚点跳转组件附带吸顶效果内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
利用React-router+Webpack快速构建react程序
目前 React、Webpack 等技术如火如荼,你是不是还在愁苦如何把这些杂乱的知识怎么学习一下,开启一段新的前端开发之路呢?那么这篇将给大家运用示例代码详细的介绍使用React-router和Webpack如何快速构建一个react程序,感兴趣的朋友们下面来一起看看吧。2016-10-10解决React报错Cannot assign to 'current'
这篇文章主要为大家介绍了React报错Cannot assign to 'current' because it is a read-only property的解决方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-12-12封装一个最简单ErrorBoundary组件处理react异常
这篇文章主要介绍了一个处理react异常的ErrorBoundary组件,简单实用,代码详细,对这个组件感兴趣的朋友可以参考下2021-04-04
最新评论