简体   繁体   English

JavaScript根据div的高宽将长字符串拆分成数组

[英]JavaScript split long string into array based on div height and width

I have a long string that I am trying to display a div .我有一个很长的字符串,我试图显示一个div

My Target:我的目标:

I am trying to split that large string into array on the basis of the number of words that I can display in div (decided on the basis of width and height).我试图根据我可以在 div 中显示的字数(根据宽度和高度决定)将该大字符串拆分为数组。

Code:代码:

    data1 = data1.split(" "); // data1 is the original string, here I am obtaining words
    const len = data1.length;

    const wordcount = 105; // 105 is hard-coded that I am tying to automate 105 means div will have only 105 words and below I am storing 105 words in page array at each index 
    let page = []
    for (let i = 0; i < (len / wordcount); i++) {
        page.push(data1.slice(wordcount * i, wordcount * (i + 1)).join(" "))
    }

I have added the code below when I am displaying text from page[0] and page[1] page[0] has properly filled the div but not page[1] , Problem is that I can't figure out how to decide word count for each index of the page so that it completely fill the div box.我加入的时候,我从显示的文本下面的代码page[0]page[1] page[0]已经正确填写股利而不是page[1]问题是,我无法弄清楚如何决定词对页面的每个索引进行计数,使其完全填满 div 框。

I am trying to create a custom text reader that is why I am doing this.我正在尝试创建一个自定义文本阅读器,这就是我这样做的原因。

 let data = "dfgdfgdf gdfg dfsdfsdfsdfs dfsdfsdf dfgdfgdfgdfgd fgdfgdfgdfg d fg df g dfg df gdf g dfgdfg dfgdfgdfdfgdfgdf gdfg dfsdfsdfsdfs dfsdfsdf dfgdfgdfgdfgd fgdfgdfgdfg d fg df g dfg df gdf g dfgdfg dfgdfgdfdfgdfgdf gdfg dfsdfsdfsdfs dfsdfsdf dfgdfgdfgdfgd fgdfgdfgdfg d fg df g dfg df gdf g dfgdfg dfgdfgdf" let width = $('#box').width() let height = $('#box').height() // now based on above width and height I am trying to create a function that will tell how many words I can use to split text it can be same words on each index or variable - this what I am unable to think let wordcount = 8; // let say I get 8 from some algo let data1 = data.split(" "); const len = data1.length; let page = [] for (let i = 0; i < (len / wordcount); i++) { page.push(data1.slice(wordcount * i, wordcount * (i + 1)).join(" ")) } $("#data").text(page[0]+"") $("#data1").text(page[1]+"")
 .abc { border: 1px solid red; width: 130px; height: 105px; white-space: wrap; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="abc" id="box"> <p id="data"></p> </div> <div class="abc"> <p id="data1"></p> </div>

To do this, you need to compare the bottom property of DOMRect s obtained with Element#getBoundingClientRect , taking padding into account.为此,您需要比较使用Element#getBoundingClientRect获得的DOMRectbottom属性,同时考虑padding DOMRect s can only be obtained for elements, not text alone, so we first need to wrap all the words in span s. DOMRect只能为元素获取,不能单独获取文本,因此我们首先需要将span的所有单词都包裹起来。

Note that each time this code runs, it will overwrite the contents of the #page element.请注意,每次运行此代码时,它都会覆盖#page元素的内容。 If you want to calculate pagination without doing that, you'll need to clone the element and render an invisible ( opacity: 0 ) version with the same width and height.如果您想在这样做的情况下计算分页,则需要克隆该元素并渲染一个具有相同宽度和高度的不可见 ( opacity: 0 ) 版本。 I haven't done that here to keep things relatively simple.为了让事情相对简单,我没有在这里这样做。

 // utils const mod = (n, modulus) => ((n % modulus) + modulus) % modulus const last = arr => arr.slice(-1)[0] // elements const page = document.querySelector('#page') const paginator = document.querySelector('#paginator') const pageCount = document.querySelector('#page-count') // best to set these in the JS to make sure the values line up when calculating distance from bottom const [paddingY, paddingX] = [20, 15] page.style.padding = [paddingY, paddingX].map(n => `${n}px`).join(' ') // main logic const createWordSpans = text => text .split(/(\\s+)/) .map((str, idx) => { if (!str) return null if (idx % 2) { return document.createTextNode(str) } else { const span = document.createElement('span') span.textContent = str return span } }) .filter(Boolean) // note that this rewrites the content of the element const paginateByBoundingElement = parent => text => { parent.textContent = '' const { bottom } = parent.getBoundingClientRect() const pages = [[]] for (const node of createWordSpans(text)) { parent.appendChild(node) if (node.nodeType === Node.ELEMENT_NODE) { const rect = node.getBoundingClientRect() if (rect.bottom + paddingY > bottom) { pages.push([node.textContent]) parent.textContent = '' parent.appendChild(node) } else { last(pages).push(node.textContent) } } else { last(pages).push(node.data) } } return pages.map(page => page.join('')) } // getContent() just returns a string - see below const pages = paginateByBoundingElement(page)(getContent()) page.textContent = pages[0] pageCount.textContent = pages.length paginator.addEventListener('input', e => { if (!e.currentTarget.value.length) return const newPageIdx = mod((parseInt(e.currentTarget.value) || 0) - 1, pages.length) const humanFriendly = String(newPageIdx + 1) page.textContent = pages[newPageIdx] page.dataset.page = humanFriendly e.currentTarget.value = humanFriendly }) function getContent() { return `In the northern ocean there is a fish, called the Kun, many thousand li in size. This Kun changes into a bird, called the Peng, whose back is many thousand li in breadth. With a mighty effort it rises, and its wings obscure the sky like clouds.\\n\\nAt the equinox, this bird prepares to start for the southern ocean, the Celestial Lake. And in the Record of Marvels we read that when the Peng flies southwards, the water is smitten for a space of three thousand li around, while the bird itself mounts upon a typhoon to a height of ninety thousand li, for a flight of six months' duration.\\n\\nJust so are the motes in a sunbeam blown aloft. For whether the blue of the sky is its real colour, or only the result of distance without end, the effect to the bird looking down would be just the same as to the motes.` }
 * { box-sizing: border-box; } #page { width: 12em; height: 15em; border: 5px solid #ddd; white-space: pre-wrap; position: relative; } #page::after { content: attr(data-page); color: #ccc; position: absolute; right: 5px; bottom: 5px; } #paginator { font-size: 1em; width: 3em; }
 <div id="page" data-page="1"></div> <br> <label>Page <input id="paginator" type="number" step="1" value="1"> of <span id="page-count">1</span></label>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM