网页中超长文字的断行问题

这个应该是比较常见的问题了,通常是连续的一长串无空格的半角字符所引起的,比如比较长的超链接就很有可能把你的页面撑开。网上常见的解决办法就是使用css属性 break-word:break-all; ,但是这个只对IE浏览器有效。

下面介绍一种办法,可以保证各浏览器的兼容。

<wbr>标记,它的作用是建议浏览器在这个标记处可以断行,只是建议而不是必定会在此处断行,还要根据整行文字长度而定。因此只要在连续的文字中间适当的插入若干<wbr>标记就能解决断行问题。

我最初看到这个解决办法是在Gmail的代码中,它是这么实现的:(All rights reserved by Google.)

JS实现

function HtmlEscapeInsertWbrs(str, n, chars_to_break_after,
                              chars_to_break_before)
{
    var out = '';
    var strpos = 0;
    var spc = 0;
    for (var i = 1; i < str.length; ++i) {
        var prev_char = str.charAt(i - 1);
        var next_char = str.charAt(i);
        if (IsSpace(next_char)) {
            spc = i;
        } else {
            if (i - spc == n
            || chars_to_break_after.indexOf(prev_char) != -1
            || chars_to_break_before.indexOf(next_char) != -1)
            {
                out += HtmlEscape(str.substring(strpos, i))
                      + '<wbr>';
                strpos = i;
                spc = i;
            }
        }
    }
    out += HtmlEscape(str.substr(strpos));
    return out;
}
/////
function IsSpace(ch)
{
    return (" trn".indexOf(ch) >= 0);
}
function HtmlEscape(str){
    return
        str.replace(/&/g,"&amp;").replace(/</g,"&lt;")
        .replace(/>/g,"&gt;").replace(/\"/g,"&quot;");
}

说明: 函数已经帮你处理了Html敏感的符号(&<>),用了这个函数并不是说字符串显示的时候就会在某个点断行,只是在其中设置了可能的断行点(<wbr>)标记,在显示宽度不够的时候的情况下才指示浏览器做出断行。


用法: 参数说明
str: 你要处理的原始字符串
n: 每行最多多少个字符
chars_to_break_after: 一个字符串,比如"-:_",就会在这些字符后面发生断行(如果有断行必要) 如果不需要特别设置,那么使用空字符串 ""就行了

chars_to_break_before: 功能类似于上面这个, 没有特殊需要就设置成 "" 就可以了

函数是JavaScript的实现, 我根据这个做了一个PHP的实现,它工作得很好。

PHP实现

/*
 * support UTF-8 only,
 * ** the function return HTML Format string **
 */
function HtmlEscapeInsertWbrs($str, $n=10,
         $chars_to_break_after='',$chars_to_break_before='')
{
    $out = '';
    $strpos = 0;
    $spc = 0;
    $len = mb_strlen($str,'UTF-8');
    for ($i = 1; $i < $len; ++$i) {
      $prev_char = mb_substr($str,$i-1,1,'UTF-8');
      $next_char = mb_substr($str,$i,1,'UTF-8');
      if (_u_IsSpace($next_char)) {
        $spc = $i;
      } else {
        if ($i - $spc == $n
         || mb_strpos( $chars_to_break_after,
            $prev_char,0,'UTF-8' ) !== FALSE
         || mb_strpos( $chars_to_break_before,
            $next_char,0,'UTF-8')  !== FALSE )
          {
            $out .= HtmlEscape(
                mb_substr($str,$strpos, $i-$strpos,'UTF-8')
                       ) . '<wbr>';
            $strpos = $i;
            $spc = $i;
          }
      }
    }
    $out .= HtmlEscape(
             mb_substr($str,$strpos,$len-$strpos,'UTF-8')
               );
    return $out;
}
/////
function _u_IsSpace($ch)
{
  return mb_strpos(" trn",$ch,0,'UTF-8') !== FALSE;
}
function HtmlEscape($s)
{
  return htmlspecialchars($s);
}

同样,该函数会对传入的字符串中的特殊字符做转义处理(htmlspecialchars()),因此传入的字符串必须是原始的(未经htmlspecialchars()处理过的),函数返回后的结果可以直接在网页中输出。
参数使用方法跟上面的JS版本类似,我就不罗唆了。

你可以改写成其他语言的,到时候也记得发给我一份 :)

14 条评论 »

  1. loz said,

    2006/9/27 @ 13:25

    网站要求用户可以选择文字大小,当文字扩大的时候,在插入wbr的地方可能已经超出。
    解决的办法就是每个字符后边加入WBR,可是这样又让文件内容增加了1倍!
    目前没有好的办法解决。

  2. Nukq said,

    2006/9/27 @ 17:32

    每个字符后加<wbr>,长的可就不止一倍了 -.-b

    实际上不换行的情况大都是连续的半角字符(比如网址)引起的,而汉字基本没什么影响。像每隔20个字符插入<wbr>已经能解决大多数的问题。

    文字放大问题: 任何网站,文字变大时,变很大时,布局都会变形,在这个情形下,是否能自动、美观换行已经没什么意义了。

  3. tjutxt said,

    2006/12/11 @ 14:25

    搜索“超长文字的断行”找到了这里,收获不小啊!谢谢了。
    看了下你开发的米胖,输入框提示做的很是精致,能不能讲讲这方面的技术方面,我刚刚起步学AJAX,谢谢了!

  4. Nukq said,

    2006/12/11 @ 16:16

    to tjutxt:

    很高兴这些技术心得能够帮到你 :)

    关于输入框自动提示的功能,我已经发邮件给你了,有兴趣的话可以交流交流。

  5. tjutxt said,

    2006/12/11 @ 23:13

    3Q,
    个人认为加一个双击事件,比如我输入了“s”,根据提示选择后,又想选别的,这是双击下输入框就可以再次显示提示层了,只是一小建议。好像跟在这帖子后有些跑题,哈哈。

  6. Nukq said,

    2006/12/12 @ 00:43

    你是说双击后显示上次补全的候选列表?

  7. tjutxt said,

    2006/12/12 @ 08:46

    对啊,如果再次查询不增加服务器负担嘛。

  8. Nukq said,

    2006/12/12 @ 12:08

    呵呵,设置“机关”过多对用户会造成困惑,还是尽量简洁一点 :)

    服务器负担这个不用太担心,因为每次查询都会在客户端做缓存,第二次查询相同关键词就不需要再次远程链接服务器了。

  9. tjutxt said,

    2006/12/12 @ 13:01

    又长知识了,^_^

  10. tangzurui said,

    2007/3/28 @ 15:40

    可不可以给我发一个关于输入框自动提示的功能,小妹感激不尽!!

  11. tangzurui said,

    2007/3/28 @ 15:41

    我的邮箱tangzurui@163.com

  12. 深谷 said,

    2007/9/18 @ 18:45

    我想弄一个输入框自动提示的功能,麻烦!QQ:275801476 。非常感谢!

  13. Nukq said,

    2007/9/18 @ 19:05

    很抱歉,不会提供输入框自动提示的实现.

  14. zoloft generic said,

    2007/12/1 @ 01:00

    zoloft generic...

    news...

RSS feed for comments on this post · TrackBack URI

发表看法

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word