如何检查是否启用了line-clamp?

41
我有一个在中的动态文本。我想使用line-clamp: 2
在这种情况下,最多有2行文本,其余部分被截断。

这适用于以下情况:

display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;

我的问题是:如果内容被截断,应该显示一个工具提示。我如何检测文本是否被截断?
元素的高度是相同的,innerHTML也是相同的...我没有更进一步的想法...

你不能只用 JavaScript 来完成整个工作吗? - Tamás
链接到https://stackoverflow.com/q/7738117/104380 - undefined
4个回答

62
通过javascript检测CSS的line-clamp可以通过比较"clamped"元素的scrollHeightclientHeight来实现。
元素的"真实"高度被overflow: hidden CSS属性裁剪,但是DOM属性scrollHeight将报告完整的高度,而clientHeight报告的是渲染后的高度。

enter image description here

以下示例显示了一个被夹住的文本。
尝试将鼠标悬停在上面,看看是否会记录检测结果。(文本可编辑)

const isTextClamped = elm => elm.scrollHeight > elm.clientHeight

new ResizeObserver(e => {
  console.clear()
  console.log( isTextClamped(e[0].target) )
}).observe(elem);
p {
  width: 200px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  resize: both; /* allowing resize for this demo only */
}
<p contenteditable id='elem' spellcheck="false">
  <strong>Resize me - </strong>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
</p>

这里有一个Codepen,可以实时演示这个。

只為您提供以下與程式設計相關的內容:<3 - Facundo Colombier

29

您可以检查元素的scrollHeight是否超过clientHeight:

function multiLineOverflows() {
    const el = this._element.nativeElement;
    return el.scrollHeight > el.clientHeight;
}

4
这是一个针对NextJS、React、Typescript和Tailwind的解决方案,其中包括一个“阅读更多...”按钮,当文本被压缩时会显示。
代码前的描述:
这是一个React组件,它作为prop获取post(可以是任何其他内容)。 post包含应该显示的内容,带有4行夹紧,直到用户点击“阅读更多...”。
内容引用(使用useRef钩子)保存了对应该显示内容的内容div的引用。 第一个useState钩子保存状态isClamped:如果内容被压缩,则为true,否则为false。 第二个useState保存状态isExpanded:如果用户已单击“阅读更多...”,则为true,否则为false。 然后,useEffect钩子仅在挂载时调用,因为空数组设置,添加事件侦听器以便于窗口大小调整(可能会影响内容行数)。当窗口大小调整时,将contentRef(具有内容的div)scrollHeight与clientHeight进行比较,就像上面的其他答案一样。如果scrollHeight较大,则isClamped将设置为true,否则为false。
现在,在包含内容的div中,如果isExpanded为false(用户还没有单击“阅读更多...”),则className将设置为“line-clamp-4”(将限制内容为4行),否则className将设置为“line-clamp-none”(无夹紧)。
最后,在包含“阅读更多...”文本的div中,如果isClamped为true(因此文本被夹紧),则将显示该文本。
import {useState, useRef, useEffect}

interface PostItemProps {
      post: Post
}

export default function PostItem({post}: PostItemProps){
    
  const contentRef = useRef<HTMLDivElement>(null)
  const [isClamped, setClamped] = useState(false)
  const [isExpanded, setExpanded] = useState(false)

  useEffect(() => {
    // Function that should be called on window resize
    function handleResize() {
      if (contentRef && contentRef.current) {
        setClamped(
          contentRef.current.scrollHeight > contentRef.current.clientHeight
        )
      }
    }

    // Add event listener to window resize
    window.addEventListener('resize', handleResize)

    // Remove event listener on cleanup
    return () => window.removeEventListener('resize', handleResize)
  }, []) // Empty array ensures that it would only run on mount

return (
    <div>
     <div ref={contentRef} className={`${ !exapnded ? 'line-clamp-4' : 'line-clamp-none' }> {post.content} </div>
     </div>
       {isClamped && (
          <div className="flex justify-end">
            <button
              className="font-bold text-title"
              onClick={() => setExpanded(true)}
            >
              See More...
            </button>
          </div>
        )}
    </div>
 )
}

2

基于 getClientRects().length 的简单解决方案对我很有效。

$('.text-inline').each(function() {
  var textLineCount = $(this)[0].getClientRects().length;
  var lineClampValue = $(this).parent().css('-webkit-line-clamp');
  if (textLineCount > lineClampValue) {
    $(this).parent().addClass('cut');
  }
});
.text-block {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.text-block.expand {
  -webkit-line-clamp: initial;
}

.show-text {
  display: none;
}

.cut+.show-text {
  display: initial;
}

.expand+.show-text {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<div class="text-block">
  <span class="text-inline">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore   magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</span>
</div>
<button class="show-text" onclick="$(this).prev().addClass('expand')">Read more</button>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接