简体   繁体   中英

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 .

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).

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.

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. DOMRect s can only be obtained for elements, not text alone, so we first need to wrap all the words in span s.

Note that each time this code runs, it will overwrite the contents of the #page element. 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. 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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