常用的六种布局方式:Flex、Gid、column-count、float、position、表格布局HTML系列:人人都懂的HTML基础知识-HTML教程(1) HTML元素大全(1) HTML
顺晟科技
2021-08-30 10:34:38
281
根据页面容器大小自动装填对话内容。当屏幕中仅能显示一段对话还过大时,缩小字号以适应容器大小。
使用一个隐藏的内容区域元素作为虚拟容器去丈量内容渲染所需要的实际空间,然后通过得到的实际空间去计算分页。
父组件:
<template>
<div
id="view-container"
>
<!-- 虚拟容器 -->
<virtual-content
:index="index"
:sentences="sentences"
/>
<!-- 实际内容 -->
<div
v-for="(sentenceInfo, sliderIndex) of list"
:key="sliderIndex"
:class="[
'slide-page-content',
'swiper-slide',
`swiper-slide-${sliderIndex}`
]"
>
<p
v-for="(item,pIndex) of sentenceInfo"
:key="pIndex"
:style="getPStyle(item,sliderIndex, pIndex)"
>
...
</div>
</div>
...
</template>
虚拟元素组件:
<template>
<div
:id="`nodes-parent-${index}`"
>
<p
v-for="(sentence,sententceIndex) of sentences"
:key="sententceIndex"
>
<br v-if="sentence.empty">
<span
v-else
>{{ sentence.englishSubtitle}}</span>
</p>
</div>
</template>
<style lang="less" scoped>
.slide-page-all{
visibility: hidden;
position:absolute;
top:0;
left:0;
right: 0;
.virtual-content{
font-size: 20px;
line-height: 1.5;
}
}
</style>
注意: 为了保证虚拟容器在实际目标容器前加载,可以将虚拟容器作为和目标容器同级的子组件。
// 增加索引
const addIndexToValue = arr => {
return arr.map((v, i) => {
return {
index: i,
height: v
};
});
};
/** 分页算法【重点】
* arr: 每一段内容所占的实际高度的集合
* max: 目标容器的更大高度
* /
const getPages = (arr, max) => {
if (max <= 0 ) {
return [];
}
const result = [];
const data = addIndexToValue(arr);
let pre = 0;
let tmp = [];
for (let i = 0, len = data.length; i < len; i++) {
const current = pre + data[i].height;
if (current >= max) {
if (tmp.length > 0) {
result.push(tmp);
tmp = [{ ... (data[i] || {}), currentIndex: 0}];
pre = data[i].height;
if (i === data.length - 1) {
result.push(tmp);
}
} else {
result.push([{ ... (data[i] || {}), currentIndex: 0}]);
tmp = [];
}
} else {
tmp.push({ ...(data[i] || {}), currentIndex: tmp.length});
pre = pre + data[i].height;
if (i === data.length - 1) {
result.push(tmp);
}
}
}
return result;
};
// 缓冲值15
const OFFSET = 15;
// 在页面中的实际应用
export const getComputedNode = index => {
const wrap = document.getElementById('view-container');
if (!wrap) {
return [];
}
const parent = document.getElementById(`nodes-parent-${index}`);
const wrapHeight = wrap.clientHeight;
const children = Array.from(parent.children);
const arr = [];
children.reduce((pre, node) => {
const height = node.clientHeight;
pre.push(height);
return pre;
}, arr);
const result = getPages(arr, wrapHeight - OFFSET);
return result;
};
// font-size
public getResizeStyle(sliderIndex, pIndex) {
const swiperPages = this.list[sliderIndex];
if (swiperPages.length === 1) {
// 只有一句话的时候
const { height } = this.list[sliderIndex][pIndex]; // height:自适应时预设的高度
const parentHeight = document.getElementById('view-container').clientHeight; // parentHeight:实际父容器高度
const wordEl = document.querySelector('.virtual-content .word');
if (!wordEl) {
// 元素还未渲染的时候
return '';
}
const fontSizeStr = window.getComputedStyle(wordEl)['font-size'] || '';
const fontSize = parseFloat(fontSizeStr);
// 当预设的高度大于实际父容器高度时,字体要缩小以适应显示
if ( height > parentHeight) {
return `font-size: ${Math.floor(fontSize * parentHeight / height)}px`;
}
return '';
} else {
return '';
}
}
3个一排,小于3个从左往右依次排列。
场景四:内容左,整体居中
实现上面的布局: 在长度长短不一的段落中要保持所有段落的内容居左显示,段落外的一层容器在页面中间显示。
参考资料:
https://zhuanlan.zhihu.com/p/...09
2022-11
19
2022-10
19
2022-10
27
2022-09
22
2022-09
22
2022-09