【问题标题】:Get row count of a string inside a div获取div内字符串的行数
【发布时间】:2021-12-30 09:16:34
【问题描述】:

我有一个带有动态文本值的 div 标签,我想了解如何根据字体大小和 div 宽度计算字符串展开的行数

例如:

div {
 width: 15px
 fontSize: 12px
 overflow: hidden
 display: block
 overflow-wrap: break-word
}

字符串是:“abcdefghijk”

UI 中的结果将是:

第一行-“abc” 第二行 - “defg” 第三行-“hijk”

所以预期的计算值应该是 3(3 行)。

可以计算吗?

http://jsfiddle.net/b6upgdqz/15/

【问题讨论】:

  • 不在服务器端(无论如何都不可靠),结果会因客户端而异
  • 为什么第一行有3个字,第二、三行有4个字?
  • @JayragPareek jsfiddle.net/b6upgdqz/15
  • 是的,这可以做到。删除文本,一次放回一个字符,然后查看元素的高度。如果它改变了,你就会有一个新行。

标签: javascript css node.js reactjs


【解决方案1】:

我想您还必须明确行高,然后将包含 div 的总高度除以您设置的行高...

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>

【讨论】:

    【解决方案2】:

    工作演示: 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>

    【讨论】:

      【解决方案3】:

      您可以通过Range#getClientRects()获取每一行的边界框。

      如果您的#container 包含更多标记,例如&lt;div&gt;s 等。这些的边界框也会添加到列表中,需要过滤掉。

      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>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-09
        • 1970-01-01
        • 1970-01-01
        • 2014-09-01
        • 1970-01-01
        相关资源
        最近更新 更多