一、监听DOM元素的API
要监听字体大小并根据其变化调整高度,可以使用以下方法:
1. 使用 ResizeObserver
ResizeObserver
是一个现代浏览器支持的 API,用于监听 DOM 元素的尺寸变化。通过监听字体大小变化(会影响元素高度),可以动态调整高度。
实现代码
attached() {
const paragraphInstance = this.ref('paragraph');
const paragraphElement = paragraphInstance.el; // 获取 DOM 元素
// 创建 ResizeObserver 实例
const resizeObserver = new ResizeObserver(() => {
const computedStyle = window.getComputedStyle(paragraphElement);
const fontSize = parseFloat(computedStyle.fontSize); // 获取字体大小
const newHeight = fontSize * 1.5; // 假设高度为字体大小的1.5倍
paragraphElement.style.height = `${newHeight}px`; // 动态设置高度
console.log('字体大小:', fontSize, '调整后高度:', newHeight);
});
// 开始观察
resizeObserver.observe(paragraphElement);
// 在组件销毁时断开观察器(可选)
this.resizeObserver = resizeObserver; // 保存以便销毁时使用
},
detached() {
// 断开 ResizeObserver
this.resizeObserver?.disconnect();
}
2. 通过 MutationObserver
检测样式变化
如果 ResizeObserver
不满足需求,可以使用 MutationObserver
,监测 style
属性变化,从而捕获字体大小的调整。
实现代码
attached() {
const paragraphInstance = this.ref('paragraph');
const paragraphElement = paragraphInstance.el;
const observer = new MutationObserver(() => {
const computedStyle = window.getComputedStyle(paragraphElement);
const fontSize = parseFloat(computedStyle.fontSize);
const newHeight = fontSize * 1.5;
paragraphElement.style.height = `${newHeight}px`;
console.log('字体大小:', fontSize, '调整后高度:', newHeight);
});
observer.observe(paragraphElement, {
attributes: true, // 监听属性变化
attributeFilter: ['style'], // 限定监听的属性
});
this.mutationObserver = observer;
},
detached() {
// 停止监听
this.mutationObserver?.disconnect();
}
3. 基于 window.getComputedStyle
的定时轮询(备选方案)
如果对性能要求不高,或者需要兼容不支持上述方法的浏览器,可以定期轮询检查字体大小是否变化。
实现代码
attached() {
const paragraphInstance = this.ref('paragraph');
const paragraphElement = paragraphInstance.el;
this.checkFontSize = setInterval(() => {
const computedStyle = window.getComputedStyle(paragraphElement);
const fontSize = parseFloat(computedStyle.fontSize);
const newHeight = fontSize * 1.5;
paragraphElement.style.height = `${newHeight}px`;
console.log('字体大小:', fontSize, '调整后高度:', newHeight);
}, 500); // 每500ms检查一次
},
detached() {
// 清除定时器
clearInterval(this.checkFontSize);
}
选择方案
- 优先使用
ResizeObserver
:性能好,专注于尺寸变化。 MutationObserver
:适合监测样式属性变化,但要限制监听范围,避免性能问题。- 轮询:简单易实现,但性能可能较低,仅作为备选方案。
二、实现页面高度随字体变化自适应
以上方法无法实现随着字体变化高度的完美变化,总会存在点问题
所以我们在this.nextTick()
调用更新高度的方法updateSwiperHeight
// 父组件
updateHeight() {
this.nextTick(() => {
this.updateSwiperHeight();
});
}
// 更新高度的方法
updateSwiperHeight(data = {}) {
const isLilac = this.data.get('styleVarient') === 'lilac';
// 取row-content的高度给cos-swiper-content
const rowContentEl = this.ref(`swiperItem_${data.index || 0}`)?.el.querySelector('.cos-row');
const swiperEl = this.ref('swiper')?.el.querySelector('.cos-swiper-content');
if (!rowContentEl || !swiperEl) {
return;
}
// lilac样式下顶部有15px外间距
swiperEl.style.height = `${rowContentEl.clientHeight + (isLilac ? 15 : 0)}px`;
}
三、整合代码
1、在字体所在组件(子组件)监听字体变化
attached() {
const paragraphInstance = this.ref('paragraph');
const paragraphElement = paragraphInstance.el;
// ResizeObserver 监听字体变化后,更新高度
const resizeObserver = new ResizeObserver(() => {
this.fire('update-height'); // 触发父组件更新
});
resizeObserver.observe(paragraphElement);
}
detached() {
this.resizeObserver?.disconnect();
}
2、在swiper高度所在组件(父组件)绑定方法
// 模版部分
<template>
<div>
<p>父组件的 swiperHeight:{{ swiperHeight }}</p>
<child-component swiper-height="{{ swiperHeight }}" on-update-height="updateHeight" />
</div>
</template>
// 逻辑部分
updateHeight() {
this.nextTick(() => {
this.updateSwiperHeight();
});
}
// 更新高度的方法
updateSwiperHeight(data = {}) {
const isLilac = this.data.get('styleVarient') === 'lilac';
// 取row-content的高度给cos-swiper-content
const rowContentEl = this.ref(`swiperItem_${data.index || 0}`)?.el.querySelector('.cos-row');
const swiperEl = this.ref('swiper')?.el.querySelector('.cos-swiper-content');
if (!rowContentEl || !swiperEl) {
return;
}
// lilac样式下顶部有15px外间距
swiperEl.style.height = `${rowContentEl.clientHeight + (isLilac ? 15 : 0)}px`;
}