长单词自动换行一直是浏览器中的一个问题。对于中文没有这个问题,每个中文字符之后都可以换行。对于正常的英文也没有这个问题,比如:i love big breasts. 每个代词后面都可以插入换行。但是对于所谓的“长单词”,如200个a,aaaaaaa......,就有了问题,浏览器会认为切断一个本来应该连在一起的单词是不道德的,所以他们拒绝自动截断这种单词换行。于是这出现了一个问题:这个段落所在的元素,或者说容器(container)可能是有一个固定宽度的,比如200px,太长的单词将破环这个格式。
IE中有一个很好用的属性:
word- wrap:break-word;
有了这个属性之后,IE就会在适当的地方,截断长单词,自动换行了。可惜的是,firefox、opera等浏览器却没有这个好用的属性,于是产生了很多解决方案,比如
overflow:hidden;
这个是将超出容器部分的单词隐藏,它基于这样一个认识:超长的单词通常是无意义的,可能是用户的胡乱输入的值,所以,我们仍然让他们在一行内显示,只是隐藏超出容器宽度的部分。这带来一些问题,因为有一些东西是长而有意义的,比如某些密码,比如一个url网址,比如一个文件的序列化后的内容。
于是有了另外一些解决方案,如<wbr />和​和­,在ppk上面有比较详细的介绍 。简单来说,这些解决方案的意思就是:对容器中的html进行处理,在每个字符之后(或每隔数个字符)加入<wbr />标签(告诉浏览器,这里可以换行),或者是​字符(浏览器不可见字符,或让浏览器把一个长单词识别为若干短单词),或者是&sky;(短横线,在不换行的时候不可见,换行的时候显示为短横线,就像英文书籍印刷的时候使用的)。
这些解决方案都有一些问题,最主要的就是改变了容器内部html的内容,如果是纯文本就没有关系,但是如果内部有html内容,html格式的内容会因为插入的字符而混乱。
最新的解决方案是用mozilla系列浏览器的 document.createTreeWalker 方法解决,这个方法接受4个参数,分别是rootNode, whatToShow, filterFunction,entityRefExpansion,其中第二个参数设置为SHOW_TEXT后,可以只遍历文本结点。详细介绍看这里 和这里 。
最后是一个比较完善的解决方案,来自hedger
//aka makeDesignerHappy(dEl);
function breakWord(dEl){
if (!dEl || dEl.nodeType !== 1 ){
return false ;
} else if (dEl.currentStyle && typeof dEl.currentStyle.wordBreak === 'string' ){
//Lazy Function Definition Pattern, Peter's Blog
//From http://peter.michaux.ca/article/3556
breakWord = function (dEl){
//For Internet Explorer
dEl.runtimeStyle.wordBreak = 'break-all' ;
return true ;
}
return breakWord(dEl);
}else if (document .createTreeWalker){
//Faster Trim in Javascript, Flagrant Badassery
//http://blog.stevenlevithan.com/archives/faster-trim-javascript
var trim = function (str) {
str = str.replace(/^\s\s*/ , '' );
var ws = /\s/ ,
i = str.length;
while (ws.test(str.charAt(-- i)));
return str.slice(0 , i + 1 );
}
//Lazy Function Definition Pattern, Peter's Blog
//From http://peter.michaux.ca/article/3556
breakWord = function (dEl){
//For Opera, Safari, and Firefox
var dWalker = document .createTreeWalker(dEl, NodeFilter.SHOW_TEXT, null , false );
var node,s,c = String .fromCharCode('8203' );
while (dWalker.nextNode())
{
node = dWalker.currentNode;
//we need to trim String otherwise Firefox will display
//incorect text-indent with space characters
s = trim( node.nodeValue ) .split('' ).join(c);
node.nodeValue = s;
}
return true ;
}
return breakWord(dEl);
}else {
return false ;
}
}
例子:
//Break All Words
void function (){
var aEl = document .getElementsByTagName('div' );
var dEl,i;
var sName = "break-word" ;
var oReg = new RegExp ('(\\s|^)' + sName + '(\\s|$)' );
for (i= 0 ;dEl = aEl[i];i++ ){
if (dEl.className.match(oReg)){
breakWord(dEl);
}
}
}()
http://stauren.net/log/f39qg7msu.html