1、背景
考虑这样一种情况,产品同学希望达到以下功能:
在我们的网页中有一个固定区域,这个区域会用于渲染从后端拉取的含有图片等资源的富文本字符串。
他需要在内容不超过一个最大高度的时候完全显示所有内容,超过最大内容后仅展示最大高度范围内的内容,超出部分隐藏,并通过一个按钮 “展示更多” 来给用户展示更多的选择。
![](https://i-blog.csdnimg.cn/blog_migrate/0839288cb74f9819fb13f593e9984907.png)
在这看似简单的需求当中,其实涉及到了一个难点,那就是怎样动态的监听到内容区域的高度变化?
因为在这里面会含有图片资源,他们在渲染的时候会发起网络请求,等待图片加载完成后触发浏览器重排,该区域的高度被撑开。
因此,内容区域的高度是动态变化,且变化的时间点是未知的,那么怎样知道我们的内容区高度发生了变化呢?
为此我做了以下几种尝试:
- MutationObserver
- IntersectionObserver
- ResizeObserver
- 监听所有资源的 onload 事件
- iframe
2、MutationObserver
MutationObserver 接口提供了监视对 DOM 树所做更改的能力。它被设计为旧的 Mutation Events 功能的替代品,该功能是 DOM3 Events 规范的一部分。
observe(target, options)
这个方法会根据传入的 options 配置,观察 DOM 树中的单个 Node 或者所有的子孙节点的变化。
他一共有七个属性,这里就不一一介绍了,可以通过 MutationObserverInit 来获取相应的介绍.
那么我们要怎么使用这个 API 来监听目标区域的高度变化呢?
1.首先我们要创建对该区域的 dom 根结点引用:
// useRef创建引用
const contentRef = useRef();
// 绑定ref
<div
className="content"
dangerouslySetInnerHTML={
{ __html: details }}
style={
{ maxHeight }}
ref={contentRef}
/>;
2.然后我们需要创建一个 MutationObserver 实例:
const [height, setHeight] = useState(-1);
const [observer, setObserver] = useState<MutationObserver>(null!);
useEffect(() => {
const observer = new MutationObserver((mutationList) => {
if (height !== contentRef.current?.clientHeight) {
console.log("高度