我在一个跨度中有一个动态文本。我想使用
line-clamp: 2
。
在这种情况下,最多有。 2 行文本,其余部分被
…
截断。
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
我的问题:如果内容被截断,应该显示工具提示。如何检测文字是否被夹住?
元素的高度是相同的,
innerHTML
是相同的......我没有进一步的想法......
通过比较“clamped”元素的 line-clamp
和
scrollHeight
可以通过 javascript 检测 CSS clientHeight
。
元素的“真实”高度由
overflow: hidden
CSS 属性裁剪,但 DOM 属性 scrollHeight 将报告 完整高度,而 clientHeight 报告 rendered 高度。
下面的示例显示了夹紧的文本。
尝试将其悬停以查看是否记录了检测。 (文字可编辑)
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>
👉 这是一个
Codepenfunction multiLineOverflows() {
const el = this._element.nativeElement;
return el.scrollHeight > el.clientHeight;
}
代码前的说明:
这是一个以 prop 形式发布的 React 组件(也可以是其他任何东西)。该帖子包含我们应该显示的内容,包含 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) lines),否则 className 将被设置为“line-clamp-none”(无钳位)。
最后,如果 isClamped 为 true,则包含“阅读更多...”的 div 中将显示(因此文本被夹紧)。
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={`${ !isExpanded ? '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>
)
}
$('.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>