Tengo una etiqueta div con valor de texto dinámico y quiero saber cómo calcular la cantidad de filas en las que se extiende la cadena de acuerdo con el tamaño de fuente y el ancho de div
Por ejemplo:
div { width: 15px fontSize: 12px overflow: hidden display: block overflow-wrap: break-word }y la cadena es: "abcdefghijk"
el resultado en la interfaz de usuario será:
primera fila- "abc" segunda fila- "defg" tercera fila- "hijk"
Entonces, el valor de cálculo esperado debe ser 3 (3 filas).
¿Es posible calcular eso?
Supongo que tendrías que explicitar también la altura de la línea y luego dividir la altura total del div contenedor por la altura de la línea que estableciste...
const input = document.getElementById("text"); const container = document.getElementById("container"); const rows = document.getElementById("rows"); input.addEventListener("input", function handleInputChange(event) { updateRowsCount(event.currentTarget.value); }); function updateRowsCount(text) { writeText(text); computeRows(container); } function writeText(text) { container.innerHTML = text; } function computeRows(container) { const style = window.getComputedStyle(container); const containerHeight = parseFloat(style.height); const lineHeight = parseFloat(style.lineHeight); const rowsCount = Math.ceil(containerHeight / lineHeight); rows.innerHTML = rowsCount; } updateRowsCount(input.value); #sample { display: flex; align-items: flex-start; } #sample > * { margin-right: 2rem; } #container { width: 15px; font-size: 12px; line-height: 1.2; overflow: hidden; display: block; overflow-wrap: break-word; background: pink; } <div id="sample"> <input id="text" value="abcdefghijkl" /> <div id="container"></div> <div id="rows"></div> </div>Demostración de trabajo: https://dojo.telerik.com/EzEjucOF/5
var calculateLineCount = function (element) { var lineHeightBefore = element.css("line-height"), boxSizing = element.css("box-sizing"), height, lineCount; // Force the line height to a known value element.css("line-height", "1px"); // Take a snapshot of the height height = parseFloat(element.css("height")); // Reset the line height element.css("line-height", lineHeightBefore); if (boxSizing == "border-box") { // With "border-box", padding cuts into the content, so we have to subtract // it out var paddingTop = parseFloat(element.css("padding-top")), paddingBottom = parseFloat(element.css("padding-bottom")); height -= (paddingTop + paddingBottom); } // The height is the line count lineCount = height; return lineCount; } $("#lineCount").html("Total number(s) of line : " + calculateLineCount($(".divwrap"))); div { width: 22px; font-size: 12px; overflow: hidden; display: block; overflow-wrap: break-word; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="divwrap"> abcdefghijk </div> <h2 id="lineCount"></h2>Puede obtener los cuadros delimitadores para cada línea a través de Range#getClientRects() .
Si su #container contiene más marcas como <div> s, etc. Los cuadros delimitadores para estos también se agregan a la lista y deben filtrarse.
const input = document.getElementById("text"); const container = document.getElementById("container"); const rows = document.getElementById("rows"); input.addEventListener("input", function handleInputChange(event) { updateRowsCount(event.currentTarget.value); }); function updateRowsCount(text) { container.innerHTML = text; const range = document.createRange(); range.selectNodeContents(container); let rects = range.getClientRects(); // deal with markup; rects = [...rects] // sort them by vertical position, leafnodes before their parents. .sort((a, b) => a.bottom - b.bottom || b.top - a.top) // remove the bounding boxes for nested markup; in this case, the <p> .filter((v, i, a) => !i || v.top >= a[i - 1].bottom); const rowsCount = rects.length; rows.innerHTML = rowsCount; } updateRowsCount(input.value); #sample { display: flex; align-items: flex-start; } #sample > * { margin-right: 2rem; } #container { width: 15px; font-size: 12px; line-height: 1.2; overflow: hidden; display: block; overflow-wrap: break-word; background: pink; } <div id="sample"> <input id="text" value="ab<p>cdefghij</p>kl" /> <div id="container"></div> <div id="rows"></div> </div>