gpt4 book ai didi

html - 将 HTML 拆分为虚拟页面

转载 作者:太空宇宙 更新时间:2023-11-04 00:54:59 24 4
gpt4 key购买 nike

我有很长的内容(包含 imgaes、列表、div、文本等的多个内容...)。我想将此内容作为虚拟 PDF 页面显示给用户。我不想生成 PDF,只是将此 HTML 内容显示为具有相同页眉/页脚的页面(由宽度/高度定义)。它应该如下图所示,正如您在第一页上看到的那样,我想拆分该文本并在下一页显示:

This is how it should looks like

我在 React 上开发这个应用程序。我不知道这个内容会是什么,每次渲染都会不同(根据用户事件有不同的内容)。

你对如何做到这一点有什么建议吗? (CSS 解决方案,或 JS,或者我不知道一些 React 库 ...)

最佳答案

这是一个简单但有效的实现。

我们的想法是将 html 装载到屏幕外的 div 中,该 div 的尺寸与我们尝试呈现的页面相同。

然后遍历此屏幕外 div 的元素(即 children 来自已解析的 html)并使用 getBoundingClientRect 查询 dom找到第一个溢出的元素。

然后我们从屏幕外的 div 中删除溢出元素之前的所有元素,并将它们缓存在一个数组中。

重新开始一个新 block ,直到屏幕外的 div 中没有更多元素。

使它适应 React 只是使用 dangerouslySetInnerHTML 的问题包含每个页面的 html 内容。

(display flex 只是为了强制元素流动,但任何布局都可以,只要它在 offscreenDiv 和页面中是相同的)

function generateRandomContent() {
var alph = "abcdefghijklmnopqrstuvwxyz";
var content = "";
// we will generate 100 random elements displaying their index to keep track of what's happening
for (var i = 0; i < 100; i++) {
var type = parseInt(Math.random() * 2, 10);
switch (type) {
case 0: // text, generates and random p block
content = content + "<p>" + i + " ";
var numWords = 10 + parseInt(Math.random() * 50, 10);
for (var j = 0; j < numWords; j++) {
var numLetters = 2 + parseInt(Math.random() * 15, 10);
if (j > 0) {
content = content + " ";
}
for (var k = 0; k < numLetters; k++) {
content = content + alph[parseInt(Math.random() * 26, 10)];
}

}
content = content + "</p>";
break;
case 1: // colored div, generates a div of random size and color
var width = 30 + parseInt(Math.random() * 20, 10) * 10;
var height = 30 + parseInt(Math.random() * 20, 10) * 10;
var color = "rgb(" + parseInt(Math.random() * 255, 10) + ", " + parseInt(Math.random() * 255, 10) + ", " + parseInt(Math.random() * 255, 10) + ")";
content = content + '<div style="width: ' + width + 'px; height: ' + height + 'px; background-color: ' + color + '">' + i + '</div>';
break;

}
}
return content;
}

function getNodeChunks(htmlDocument) {
var offscreenDiv = document.createElement('div');
offscreenDiv.className = 'page';
offscreenDiv.style.position = 'absolute';
offscreenDiv.style.top = '-3000px';
offscreenDiv.innerHTML = htmlDocument;
offscreenDiv.display = 'flex';
offscreenDiv.flexWrap = 'wrap';
document.body.appendChild(offscreenDiv);
offscreenRect = offscreenDiv.getBoundingClientRect();
// console.log('offscreenRect:', offscreenRect);
var chunks = [];
var currentChunk = []
for (var i = 0; i < offscreenDiv.children.length; i++) {
var current = offscreenDiv.children[i];
var currentRect = current.getBoundingClientRect();
currentChunk.push(current);
if (currentRect.bottom > (offscreenRect.bottom)) {
// current element is overflowing offscreenDiv, remove it from current chunk
currentChunk.pop();
// remove all elements in currentChunk from offscreenDiv
currentChunk.forEach(elem => elem.remove());
// since children were removed from offscreenDiv, adjust i to start back at current eleme on next iteration
i -= currentChunk.length;
// push current completed chunk to the resulting chunklist
chunks.push(currentChunk);
// initialise new current chunk
currentChunk = [current];
offscreenRect = offscreenDiv.getBoundingClientRect();
}
}
// currentChunk may not be empty but we need the last elements
if (currentChunk.length > 0) {
currentChunk.forEach(elem => elem.remove());
chunks.push(currentChunk);
}
// offscreenDiv is not needed anymore
offscreenDiv.remove();
return chunks;
}

function appendChunksToPages(chunks) {
var container = document.getElementsByClassName('root_container')[0];
chunks.forEach((chunk, index) => {
// ex of a page header
var header = document.createElement('div');
header.innerHTML = '<h4 style="margin: 5px">Page ' + (index + 1) + '</h4>';
container.appendChild(header);
var page = document.createElement('div');
page.className = 'page';
chunk.forEach(elem => page.appendChild(elem));
container.appendChild(page);
});
}

// generateRandom content outputs raw html, getNodeChunks returns
// an array of array of elements, the first dimension is the set of
// pages, the second dimension is the set of elements in each page
// finally appendChunks to pages generates a page for each chunk
// and adds this page to the root container
appendChunksToPages(getNodeChunks(generateRandomContent()));
 
.page {
border: 1px solid;
display: flex;
flex-wrap: wrap;
height: 700px;
width: 50%;
margin-bottom: 20px;
}
<div class="root_container"></div>

关于html - 将 HTML 拆分为虚拟页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54980382/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com