锚点实现自动滚动

818 阅读1分钟

“我正在参加「掘金·启航计划」”

主要用到了overflow-anchor这个属性,介绍如下:

overflow-anchor: auto | none

overflow-anchor:auto是初始声明,表示浏览器自己决定滚动锚定的行为,通常表现为执行滚动锚定;

overflow-anchor:none则表示禁止滚动锚定的行为。

详细介绍参考:www.zhangxinxu.com/wordpress/2…

当碰到需要插入到内容自动滚动时,这个属性就很好用,实现的效果如下:

具体实现如下:

首先定义一个div当作最外层的盒子,然后里面放上p标签当文本内容,并且在最下面放一个空的div,当做我们的锚点

<div className={styles.scroll}>
  <p><p>
  <div className={styles.anchor}></div>
<div>
.scroll {
  height: 300px;
  display: inline-block;
  overflow-y: scroll;
  border:1px solid #ccc;
  padding:16px;
  box-sizing: border-box;
  min-width: 87.4px;
  & * {   //给盒子下的所有元素都overflow-anchor都设置为none
   overflow-anchor: none;
  }
  .anchor{
    height: 1px; //注意:锚点必须要有高度才会生效
    overflow-anchor: auto; //单独把锚点的overflow-abchor设置为anto
  }
}

到这里还没有完全结束,我们需要手动触发一下滚动,才会生效。这里我选的是当外层div的scrollHeight比div的height大时触发,有更好的方法欢迎补充

let scrollBox = document.querySelect('.scroll')
if(scrollBox.scrollHeight>scrollBox.height){
  document.querySelect('.anchor').scrollIntoView()
}

最后付上react写的demo完整代码

import { PageContainer } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import styles from './index.less';
import {useState,useEffect} from 'react'
import {useRef,RefAttributes} from 'react';
const HomePage: React.FC = () => {
  const data = useModel('global');
  console.log(data,'datasss')
  const [infoData, setInfoData] = useState([])
  const listBox = useRef<HTMLDivElement>(null)
  const anchor = useRef<HTMLDivElement>(null)
  useEffect(()=>{
    setInterval(()=>{
      if(listBox.current&&anchor.current){
        if(listBox.current.scrollHeight>listBox.current.clientHeight){
          anchor.current.scrollIntoView()
        }
      }
      setInfoData((data)=>{
        let newData = [...data];
        newData.push(`树上有${newData.length}只鸟`)
        return newData
      })
    },1000)
  },[])
  useEffect(()=>{
    setTimeout(()=>{
      anchor.current?.scrollIntoView()

    },10000)
  },[anchor])
  return (
    <PageContainer ghost>
    <div className={styles.scroll} ref={listBox}>
    {infoData.map((item,index)=>{
      return <p key={index}>{item}</p>
                  })}
      <div className={styles.anchor} ref={anchor}></div>
  </div>
  </PageContainer>
    );
};
export default HomePage;
.container {
  padding-top: 80px;

}
.scroll {
  height: 300px;
  display: inline-block;
  overflow-y: scroll;
  border:1px solid #ccc;
  padding:16px;
  box-sizing: border-box;
  min-width: 87.4px;
  & * {
    overflow-anchor: none;
  }
  .anchor{
    height: 1px;
    overflow-anchor: auto;
  }
}