如何编写保留HTML结构的Textlimit文本截断函数
保留HTML结构的文本截断解决方案
问题说明
现有jQuery代码可通过容器的data-word-limit属性截断文本并生成「展开」「收起」按钮,但截断过程中会丢失<strong>等HTML标签结构,需实现保留原有格式的文本截断功能。
解决方案
核心思路是遍历DOM节点而非直接提取纯文本,在计数单词的同时完整保留原有HTML标签结构,确保截断后的内容格式不变。
修改后的完整代码
JavaScript 代码
jQuery(function($) { $(document).ready(function() { const moreLink = '展开全文'; const lessLink = '收起全文'; // 保存每个容器的原始HTML内容 $('.container').each(function() { $(this).data('original-content', $(this).html()); }); // 通用截断逻辑函数 function truncateContainer(container) { const wordLimit = parseInt(container.data('word-limit')); if (isNaN(wordLimit)) return; const contentWrapper = container.find('.paragrapgs').first(); const tempWrapper = $('<div></div>').html(contentWrapper.html()); let wordCount = 0; let truncated = false; const remainingNodes = []; // 递归遍历DOM节点,计数单词并分割内容 function traverseNodes(node) { if (truncated) { remainingNodes.push(node.cloneNode(true)); return; } if (node.nodeType === Node.TEXT_NODE) { const text = node.textContent.trim(); if (!text) return; const words = text.split(/\s+/); if (wordCount + words.length <= wordLimit) { wordCount += words.length; } else { const take = wordLimit - wordCount; // 截断当前文本节点并添加省略号 node.textContent = words.slice(0, take).join(' ') + '...'; wordCount += take; truncated = true; // 剩余文本转为节点存入剩余列表 if (words.slice(take).length > 0) { remainingNodes.push(document.createTextNode(' ' + words.slice(take).join(' '))); } } } else if (node.nodeType === Node.ELEMENT_NODE) { // 遍历元素节点的子节点 const children = Array.from(node.childNodes); for (let i = 0; i < children.length; i++) { traverseNodes(children[i]); if (truncated) break; } } } traverseNodes(tempWrapper[0]); if (truncated) { // 拼接截断后的内容和剩余内容 const remainingContent = $('<div></div>').append(remainingNodes).html(); const truncatedContent = ` ${tempWrapper.html()} <span class="morecontent"> ${remainingContent} <a href="#" class="morelink">${moreLink}</a> </span> `; contentWrapper.html(truncatedContent); } } // 初始化所有容器的截断状态 $('.container').each(function() { truncateContainer($(this)); }); // 展开全文点击事件 $(document).on('click', '.morelink', function(e) { e.preventDefault(); const container = $(this).closest('.container'); container.html(container.data('original-content')); container.find('.paragrapgs p:last').append(` <a href="#" class="lesslink">${lessLink}</a>`); }); // 收起全文点击事件 $(document).on('click', '.lesslink', function(e) { e.preventDefault(); const container = $(this).closest('.container'); $(this).remove(); truncateContainer(container); }); }); });
HTML 代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <div class="container" data-word-limit="90"> <div class="paragrapgs"> <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam <strong>nonumy eirmod tempor</strong> invidunt ut labore et dolore magna...</p> <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam...</p> <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam...</p> </div> </div>
关键改进点
- DOM节点遍历:递归处理文本节点和元素节点,避免直接提取纯文本导致标签丢失
- 精准单词计数:按空格分割文本节点内容,确保单词计数准确
- 内容分割逻辑:达到限制时截断当前文本节点,同时保留剩余内容的完整DOM结构
- 逻辑复用:收起操作直接调用初始化截断逻辑,保证代码一致性
内容的提问来源于stack exchange,提问作者Dilschad
相关产品推荐
相关产品推荐

