首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用JS计算CSS有限div中的字符

如何用JS计算CSS有限div中的字符
EN

Stack Overflow用户
提问于 2021-03-05 16:43:13
回答 1查看 168关注 0票数 1

我有以下CSS:

代码语言:javascript
复制
html {
  --lh: 18px;
}

.line-10 {
  --max-lines: 10;

  max-width: 100%;
  max-height: calc(var(--lh) * var(--max-lines));
  overflow: hidden;
}

并想在div中数一下字符数:

代码语言:javascript
复制
const div = document.createElement('div')
div.classList.add('line-10')
div.innerHTML = longHtml
const _createdHTML = div.innerHTML
const _createdTxt = _createdHTML.replace(/<[^>]*>/g, '')
console.log('_createdTxt', _createdTxt.length)

但我得到的是整个longHtml,而不是受到CSS的限制。有办法解决吗?

案例A的当前解决方案(每div有1大段文字):

代码语言:javascript
复制
const maxLines = 10
const fullTxtLen = html.replace(/<[^>]*>/g, '').length
const fullLineLen = 150 // or whatever fits into initial div

if (fullTxtLen / fullLineLen > maxLines) {
  const totalLines = fullTxtLen / fullLineLen
  const reduceIn = totalLines / maxLines
  const final = fixHtml(html.substring(0, parseInt(html.length / reduceIn)))

  return {
    html: final,
    len: final.replace(/<[^>]*>/g, '').length // i.e. this is the answer on visible char count
  }
}

function fixHtml (html) {
  const div = document.createElement('div')
  div.innerHTML = html
  return (div.innerHTML)
}

此解决方案的问题:

与引入更多的border.

  • reduced和/或<br />相比,
  1. 更不可靠,因为每一行的fullLineLen都不一样,因为div的右
  2. 字符长度是以文本字符而不是html字符

表示的。

常见问题

需要保留多少字符,输入示例和预期输出

这取决于div的大小。输入示例: 1)第1段中的第1段和第2段中的第2段;2)第1段中的第1段;预期输出-可见字符计数。

EN

回答 1

Stack Overflow用户

发布于 2021-03-06 22:53:54

如果我们将字符串中的字符逐渐复制到屏幕外的div中,其最大高度(+1px)与div相同,intersectionObserver将在它刚进入屏幕顶部时通知我们。这是在复制最后一行之后的第一个字符时发生的。

我们必须让系统有一个空间,它可以告诉我们这样的一个观察,所以复制必须以比特进行。这个片段一次复制一个单词,所以在大多数系统中,它最多可以以每秒60个字的速度计数。

有一些不确定性--我们所说的“可见字符”意味着什么?这个系统意味着什么?在一个系统中,在可见部分中精确地有10条线,并且没有滚动,计数是准确的(例如,Word或Notepad++)。

在滚动时,很有可能只显示了上线和底线中的部分字符(有时并不是很明显),所以系统和人类认为是可见的和应该被计算的可能有所不同。从这个问题上还不清楚预期的结果应该是什么。这个片段在滚动的情况下做的最好,通过计数在顶部滚动的字符来调整整个计数。

在Windows 10上在Edge/Chrome上进行测试,在IOS 14.4上测试Safari。请注意,在Chrome的开发工具模拟器上,它不能很好地工作(数了几个字符),因为intersectionObserver的仿真似乎有点滞后。

代码语言:javascript
复制
<head>
<style>

html {
  --lh: 18px;
}

* {
  margin: 0;
}

.line-10, .workSpaceDiv {
  margin: 0 20px;
  --max-lines: 10;
  max-width: 100%;
  max-height: calc(var(--lh) * var(--max-lines));
  overflow-y: scroll;
}

.workSpaceDiv {
  position: absolute;
  --maxh:  calc(var(--lh) * (var(--max-lines) + 1));
  max-height: var(--maxh);
  transform: translateY(calc(2px - var(--maxh)));
  height: auto;
  display: none;
}

.clickme, .info {
  padding: 10px;
}

.infoblock {
  padding: 20px;
}

</style>
</head>
<body>
  <div class="workSpaceDiv"></div>
  <div class="infoblock">
    <button class="clickme" onclick="countChs(div);">Click me to count the visible characters</button>
    <span class="info"> Number of visible characters: </span><span class="count"></span>
  </div>

<script>
  const div = document.createElement('div');
  div.classList.add('line-10');
  document.body.appendChild(div);

  const longHtml = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Mi in nulla posuere sollicitudin. Sed nisi lacus sed viverra tellus in. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Enim lobortis scelerisque fermentum dui faucibus. Varius duis at consectetur lorem donec massa sapien faucibus et. Libero enim sed faucibus turpis in eu mi bibendum. Eleifend donec pretium vulputate sapien nec sagittis aliquam malesuada bibendum. Nulla aliquet enim tortor at auctor. Mattis pellentesque id nibh tortor. Ullamcorper sit amet risus nullam eget felis. In ornare quam viverra orci sagittis eu. Pellentesque habitant morbi tristique senectus. Amet cursus sit amet dictum sit amet justo. Sit amet nulla facilisi morbi tempus. Dolor sit amet consectetur adipiscing elit duis tristique sollicitudin nibh. Facilisi morbi tempus iaculis urna id volutpat lacus laoreet. Mi in nulla posuere sollicitudin aliquam ultrices. Diam quis enim lobortis scelerisque fermentum dui faucibus in ornare. Sed augue lacus viverra vitae congue eu. Et malesuada fames ac turpis egestas integer eget aliquet nibh. Ipsum faucibus vitae aliquet nec ullamcorper. Felis bibendum ut tristique et egestas quis ipsum suspendisse ultrices. Ac felis donec et odio pellentesque diam volutpat commodo. Mauris a diam maecenas sed. Facilisis sed odio morbi quis commodo odio aenean sed. Lorem mollis aliquam ut porttitor leo a. Vivamus at augue eget arcu dictum varius duis. Nisi porta lorem mollis aliquam ut. Habitant morbi tristique senectus et netus et malesuada fames ac. Tempus iaculis urna id volutpat lacus laoreet non curabitur. Sed risus pretium quam vulputate dignissim suspendisse in. Malesuada fames ac turpis egestas maecenas pharetra. Malesuada fames ac turpis egestas maecenas. Urna nunc id cursus metus aliquam eleifend mi in. Convallis posuere morbi leo urna molestie at elementum. Facilisis leo vel fringilla est ullamcorper eget nulla facilisi. Nulla pharetra diam sit amet nisl suscipit. Posuere morbi leo urna molestie at. Risus pretium quam vulputate dignissim. Arcu dui vivamus arcu felis bibendum ut tristique et. Varius duis at consectetur lorem donec massa sapien faucibus et. Id eu nisl nunc mi ipsum faucibus vitae aliquet. Congue mauris rhoncus aenean vel elit scelerisque mauris. Nulla at volutpat diam ut venenatis tellus in. Tellus cras adipiscing enim eu turpis egestas pretium aenean pharetra. Leo integer malesuada nunc vel risus. Tortor at auctor urna nunc id cursus metus aliquam eleifend. Felis bibendum ut tristique et egestas quis ipsum. A condimentum vitae sapien pellentesque habitant morbi. Purus non enim praesent elementum facilisis leo vel fringilla. Sagittis purus sit amet volutpat consequat mauris nunc. Sed tempus urna et pharetra pharetra massa massa. Vitae proin sagittis nisl rhoncus mattis rhoncus. Non curabitur gravida arcu ac tortor dignissim convallis. Dolor sit amet consectetur adipiscing elit. Dignissim enim sit amet venenatis urna cursus. Neque ornare aenean euismod elementum nisi quis eleifend quam. Tortor at auctor urna nunc id cursus metus aliquam eleifend. Curabitur gravida arcu ac tortor dignissim convallis aenean. Neque viverra justo nec ultrices dui sapien eget mi.`;

  const createdTxt = longHtml.replace(/<[^>]*>/g, '');
  div.innerHTML = createdTxt;

  const workSpaceDiv = document.querySelector('.workSpaceDiv');
  const info = document.querySelector('.info');
  const count = document.querySelector('.count');

  let nextCh, lastWordSize, stopCount, scrolledChs, firstTime, scrolled, allChs;

  function countChsIn() {
    stopCount = false;
    nextCh = 0;
    lastWordSize = 0;

    observer.observe(workSpaceDiv);
    requestAnimationFrame(nextChFill);

    function nextChFill() {
      if (stopCount) return;
      lastWordSize = 0;
      let i, ch;
      for (i = 0; i < 10; i++) {
        ch = allChs.charAt(nextCh);
        workSpaceDiv.innerHTML = workSpaceDiv.innerHTML + ch;
        nextCh++;
        lastWordSize++;
        if ((!((/[a-zA-Z]/).test(ch))) || (nextCh >= allChs.length)) { break; }
      }

      if (nextCh < allChs.length) requestAnimationFrame(nextChFill);
      else { finish(); }

    }
  }

  function finish() {
    observer.disconnect(workSpaceDiv);
    workSpaceDiv.style.height = 'auto';
    workSpaceDiv.innerHTML = '';
    if (firstTime) {
      firstTime = false;
      stopCount = false;
      scrolledChs = nextCh - lastWordSize -1;
      workSpaceDiv.style.transform = 'translateY(calc(1px - (var(--maxh) + ' + scrolled + 'px' + ')))';
      workSpaceDiv.style.maxHeight = 'calc(var(--maxh) + ' + scrolled + 'px' + ')';
      requestAnimationFrame(countChsIn);
    }
    else {
      workSpaceDiv.style.transform = 'translateY(calc(2px - var(--maxh)))';
      workSpaceDiv.style.display = 'none';
      count.innerHTML = nextCh - lastWordSize - 1 - scrolledChs;
      stopCount = true;
    }
  }

  function overlap(entries) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        finish();
      }
    });
  }

  let observer = new IntersectionObserver(overlap);
  
  function countChs(el) {
    allChs = el.innerHTML;
    scrolled = el.scrollTop;
    firstTime = !(scrolled <= 0);

    count.innerHTML = '...counting...';

    workSpaceDiv.style.display = 'block';
    workSpaceDiv.style.innerHTML = '';
    workSpaceDiv.style.height = 'auto';

    if (firstTime) {
      workSpaceDiv.style.transform = 'translateY(calc(2px - ' + scrolled + 'px' + '))';
      workSpaceDiv.style.maxHeight = scrolled + 'px';
    }
    else {
      workSpaceDiv.style.transform = 'translateY(calc(2px - var(--maxh)))';
      workSpaceDiv.style.maxHeight = 'var(--maxh)';
    }
    scrolledChs = 0;
    requestAnimationFrame(countChsIn);
  }
</script>
</body>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66496383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档