利用 MutationObserver 实现 react-fast-marquee 溢出滚动效果
前言
在公司的项目需求中,需要公告栏内容小于指定宽度时,不能滚动,溢出时才显示滚动效果。然后使用react-fast-marquee
时,发现通过 ref 没法获取到内容。
问题复现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import { useEffect, useRef } from "react"; import Marquee from "react-fast-marquee";
import "./App.css";
function App() { const containerRef = useRef < HTMLDivElement > null; const marqueeRef = useRef(null);
useEffect(() => { console.log(marqueeRef.current); debugger; }, [marqueeRef]);
return ( <div className="marquee-container" ref={containerRef}> <Marquee ref={marqueeRef}> <span className="content">12</span> </Marquee> </div> ); }
export default App;
|
没办法获取marqueeRef
,那就没法操作 dom,得到元素的宽度进行判断。所以不可行。虽然可以通过 setTimeout 滞后获取,但是请教同事后,得到一个使用 MutationObserver 来实现的方案,而且 MutationObserver 之前刚好学过还写了篇文章,能用上项目里就很有 b 格。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| import React, { useEffect, useRef, useState } from "react"; import Marquee from "react-fast-marquee";
import "./App.css"; import classNames from "classnames";
function App() { const containerRef = useRef < HTMLDivElement > null; const contentRef = useRef < HTMLSpanElement > null;
const [scrollable, setScrollable] = useState(false);
useEffect(() => { if (!containerRef.current) { return; }
const observer = new MutationObserver(() => { if (containerRef.current && contentRef.current) { if (contentRef.current.offsetWidth > containerRef.current.offsetWidth) { setScrollable(true); } } });
observer.observe(containerRef.current, { childList: true, });
return () => observer.disconnect(); }, [containerRef]);
return ( <div className="marquee-container" ref={containerRef}> <Marquee play={scrollable}> <span className="content" ref={contentRef}> 12 </span> </Marquee> </div> ); }
export default App;
|
样式
1 2 3
| .marquee-container { max-width: 200px; }
|
内容溢出时滚动 s