PHP页面中JS文本单词数限制功能失效求助
问题:文章内容无法被JS脚本限制为指定单词数
我编写了PHP脚本展示数据库中的文章内容,同时用JS脚本.artlimit.js限制.fullText类的内容只显示5个单词,但实际没有任何效果。
PHP展示代码:
<div> <div class="container"> <?php $articles = getArticle(3); ?> <div class="row borderrowindex"> <?php foreach ($articles as $article): ?> <div class="col-md-4"> <a class="newslink" href="artikel.php?title=<?= urlencode($article['title']) ?>"> <div class="card"> <div class="card-body"> <img class="articlecard-photo" src="assets/img/background.jpeg" alt="Article Image"> <h4 class="card-title text-center"><?= $article['title'] ?></h4> <p class="card-text fullText"><?= $article['article'] ?></p> </div> </div> </a> </div> <?php endforeach; ?> </div> </div> </div> <script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/js/artlimit.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </body>
JS限制脚本(artlimit.js):
document.addEventListener('DOMContentLoaded', function () { const fullTextElements = document.querySelectorAll('.fullText'); const wordLimit = 5; // Adjust the word limit as needed fullTextElements.forEach(element => { let text = element.textContent; let words = text.split(' '); if (words.length > wordLimit) { let truncatedText = words.slice(0, wordLimit).join(' ') + '...'; element.textContent = truncatedText; } }); });
数据库中的文章内容包含HTML标签,示例如下:
<p><span style='font-size:18px;'><strong>Amsterdam</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. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span></p> <p><img alt='' src='/media/images/WhatsApp%20Image%202022-11-10%20at%2008.15.57.jpeg' style='width: 400px; height: 300px;' /></p> <p><img alt='' src='/media/images/WhatsApp%20Image%202022-11-10%20at%2008.56.46.jpeg' style='width: 400px; height: 225px;' /></p>
问题原因
- 文本拆分逻辑失效:脚本用
split(' ')按单个空格拆分文本,但数据库内容包含换行符、连续空格等,这些不会被识别为分隔符,导致大量文本被当成单个单词,words.length统计远小于实际单词数,无法触发截断条件。 - HTML标签导致文本合并:HTML标签(如
</strong>后直接跟文本无空格)会让textContent提取的文本出现无空格连接的情况(比如AmsterdamLorem),进一步干扰单词数统计。 - 替换方式的副作用:即使触发截断,
element.textContent = truncatedText会将原HTML结构全部替换为纯文本,丢失格式,但核心问题是无法触发截断。
解决方案
方案1:修正JS脚本逻辑
改进文本处理方式,先去除HTML标签,再用正则匹配所有空白字符拆分单词:
document.addEventListener('DOMContentLoaded', function () { const fullTextElements = document.querySelectorAll('.fullText'); const wordLimit = 5; fullTextElements.forEach(element => { // 去除所有HTML标签,获取纯文本 let plainText = element.innerHTML.replace(/<[^>]*>/g, ''); // 按任意空白字符拆分,过滤空字符串 let words = plainText.trim().split(/\s+/).filter(word => word.length > 0); if (words.length > wordLimit) { let truncatedText = words.slice(0, wordLimit).join(' ') + '...'; element.innerHTML = truncatedText; } }); });
方案2:PHP端提前处理(推荐)
在PHP层直接处理截断,避免前端的各种问题,同时更易控制:
function truncateArticle($htmlContent, $wordLimit = 5) { // 去除HTML标签,得到纯文本 $plainText = strip_tags($htmlContent); // 拆分单词,过滤空内容 $words = preg_split('/\s+/', trim($plainText), -1, PREG_SPLIT_NO_EMPTY); if (count($words) <= $wordLimit) { return $htmlContent; } // 截断并添加省略号 return implode(' ', array_slice($words, 0, $wordLimit)) . '...'; }
在模板中调用:
<p class="card-text fullText"><?= truncateArticle($article['article'], 5) ?></p>
方案3:保留HTML结构的截断(可选)
如果需要保留部分HTML格式(如加粗),可以用DOMDocument解析处理:
function truncateHtmlArticle($htmlContent, $wordLimit = 5) { $dom = new DOMDocument(); libxml_use_internal_errors(true); $dom->loadHTML(mb_convert_encoding($htmlContent, 'HTML-ENTITIES', 'UTF-8')); libxml_clear_errors(); $xpath = new DOMXPath($dom); $textNodes = $xpath->query('//text()'); $wordCount = 0; $truncated = false; foreach ($textNodes as $node) { $text = trim($node->nodeValue); if (empty($text)) continue; $words = preg_split('/\s+/', $text, -1, PREG_SPLIT_NO_EMPTY); if ($wordCount + count($words) > $wordLimit) { $remaining = $wordLimit - $wordCount; $node->nodeValue = implode(' ', array_slice($words, 0, $remaining)) . '...'; // 删除后续所有节点 $next = $node->nextSibling; while ($next) { $next->parentNode->removeChild($next); $next = $node->nextSibling; } $truncated = true; break; } $wordCount += count($words); } if (!$truncated) return $htmlContent; $result = $dom->saveHTML($dom->getElementsByTagName('body')->item(0)); return preg_replace('/^<body>(.*)<\/body>$/s', '$1', $result); }
调用方式:
<p class="card-text fullText"><?= truncateHtmlArticle($article['article'], 5) ?></p>
内容的提问来源于stack exchange,提问作者John Sure
相关产品推荐
相关产品推荐

