有没有一种自动控制HTML文档中孤立单词的方法?

19
我想知道是否有一种方法可以通过CSS和/或Javascript(或其他替代建议)自动控制HTML文件中的孤立单词。所谓“孤立单词”是指出现在段落末尾新行上的单个单词。例如:“这个段落以一个不理想的孤立单词结尾。”相反,最好的方式是将段落分为两部分:“这个段落不再以不理想的孤立单词结尾。”虽然我知道我可以通过在最后两个单词之间放置HTML不间断空格( )来手动更正这个问题,但我想知道是否有一种自动化的方法,因为手动调整这样的问题对于跨多个文件的大块文本而言很快变得乏味。顺便说一下,CSS2.1属性orphans(和widows)仅适用于整行文本,即使是HTML页面的打印也是如此(更不用说这些属性在大多数主流浏览器中都不被支持)。
许多专业的页面布局应用程序(例如Adobe InDesign)可以通过在孤行出现的地方自动添加不间断空格来自动消除孤行。那么HTML是否有类似的解决方案呢?

不,没有自动化的方式来控制那个。 - Pointy
2
除了@ShawnChin提到的jQuery插件之外,其他都可以。 :-) - Pointy
可能是Widow/Orphan Control with JavaScript?的重复问题。 - davidcondrey
你为什么从未选择过这个问题的答案? - pixelfairy
6个回答

27
您可以通过使用不间断空格 ( ) 替换句子中最后两个单词之间的空格来避免孤立单词。
有一些插件可以实现这一功能,例如 jqWidon't这个 jQuery 片段
对于流行的框架也有相应的插件(如 Django 的 Typogrify 和 WordPress 的 Widon't),它们基本上实现了相同的功能。

“ ”方法的问题在于,如果在窄屏幕上,可能会出现倒数第二行只有一个单词,而最后一行有两个单词的情况,这看起来会更糟糕。 - clayRay

5
我知道您想要 JavaScript 的解决方案,但如果有人找到这个页面并需要电子邮件的解决方案(因为 Javascript 不可用),我决定发布我的解决方案。使用 CSS 属性 white-space: nowrap。所以我的做法是在最后两个或三个单词(或者任何我想要“换行”的位置)周围加上一个 span 标签,并添加一个内联 CSS 样式(请记住,我处理的是电子邮件,根据需要制作一个类):
<td>
    I don't <span style="white-space: nowrap;">want orphaned words.</span>
</td>

在流体/响应式布局中,如果正确处理,最后几个单词将断成第二行,直到有足够的空间使这些单词在一行上显示。

关于white-space属性的更多信息请参阅此链接:http://www.w3schools.com/cssref/pr_text_white-space.asp

编辑:2015年12月19日-由于Outlook不支持该功能,我已经在句子的最后两个单词之间添加了一个非断行空格&nbsp;。它是更少的代码,并且在任何地方都得到支持。

编辑:2018年2月20日-我发现Outlook应用程序(iOS和Android)不支持&nbsp;实体,所以我必须结合两种解决方案,例如:
<td>
    I don't <span style="white-space:nowrap;">want&nbsp;orphaned&nbsp;words.</span>
</td>

3
简而言之,不行。这是多年来让印刷设计师发疯的事情,但HTML无法提供这种级别的控制。
如果您绝对需要,并且理解速度影响,可以尝试此处的建议: 使用jQuery检测换行符? 那是我能想象到的最好的解决方案,但这并不意味着它是一个好的解决方案。

2

我看到有第三方插件建议,但自己做会更简单。如果你只想用一个不间断空格替换最后一个空格字符,那几乎是微不足道的:

    const unorphanize = (str) => {
        let iLast = str.lastIndexOf(' ');
        let stArr = str.split('');
        stArr[iLast] = '&nbsp;';
        return stArr.join('')
}

我想这可能会错过一些独特的情况,但对于我所有的使用情况都有效。需要注意的是,你不能仅仅把输出结果插入到文本中,你必须要设置 innerHTML = unorphanize(text) 或者其他解析方式。


1
如果你想不使用jQuery自己处理它,可以编写一个javascript代码片段来替换文本,前提是你愿意做出一些假设:
  1. 句子总是以句号结尾。
  2. 你总是想用&nbsp;替换最后一个单词前面的空格。

假设你有这个HTML(在我的浏览器上样式为在“end”之前中断……如有必要,请调整宽度):

<div id="articleText" style="width:360px;color:black; background-color:Yellow;">
    This is some text with one word on its own line at the end.
    <p />
    This is some text with one word on its own line at the end.
</div>

你可以创建这个 JavaScript 并将其放在页面末尾:
<script type="text/javascript">
    reformatArticleText();
    function reformatArticleText()
    {
        var div = document.getElementById("articleText");
        div.innerHTML = div.innerHTML.replace(/\S(\s*)\./g, "&nbsp;$1.");
    }
</script>

正则表达式简单地查找所有实例(使用标志)的空格字符(\S)后跟任意数量的非空格字符(\s),然后是一个句号。它创建了对非空格字符的反向引用,您可以在替换文本中使用它。
您可以使用类似的正则表达式来包括其他结束标点符号。

谢谢您的建议!我喜欢JavaScript的简单优雅;然而,当测试您的代码时,似乎没有得到期望的结果。我将我的测试上传到以下链接:[http://littleblackkitten.com/orphan-test.html] 浏览器似乎用不间断空格替换了最后一个字母,而不是最后一个空格。我做错了什么吗?您在测试代码时是否获得了成功的结果?再次感谢您的帮助! - Josh M. Lenius
1
那个正则表达式实际上会破坏一些以html元素结尾的东西(例如,如果您在文章末尾有一个图像标签)。请使用此处的正则表达式替换它,以避免弄乱内部html:http://justinhileman.info/article/a-jquery-widont-snippet/ - bobthecow
观察在此页面控制台运行此代码的结果。document.body.innerHTML = document.body.innerHTML.replace(/\S(\s*)\./g, "&nbsp;$1."); - Bryan Downing

0
如果第三方JavaScript是一种选择,可以使用typogr.js,这是一个JavaScript“typogrify”实现。这个特定的过滤器被称为Widont,毫不意外。
<script src="https://cdnjs.cloudflare.com/ajax/libs/typogr/0.6.7/typogr.min.js"></script>
<script>
document.body.innerHTML = typogr.widont(document.body.innerHTML);
</script>
</body>

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