话说博客园首页有个文章列表,大家注意到了吧?好像是废话。布局上马马虎虎过得去,不过细看,偶眼光比咱首都的车检员差得远,还是能发现有违背社会和谐之处:
各个文章的概要长度七零八落,看上去不太齐整。前几天项目中也碰到这样问题,而且要截的内容可能包含许多RichText。现在没有一个浏览器支持哪种样式,可以将在超出范围内容自动截断并加省略号。我等追求完美之人,怎么能一个substring了之呢?不信邪,研究了大半天,还真搞出了点名堂。现在地皮好贵,文字也得蜗居,不过比较人性化一点,固定的容器显示尽可能多的内容,超过了加省略号。这篇文章就想解决这么点问题,跟不屑的朋友说声Sorry。
对于留下来的朋友, 也不废话了,直接上代码:先实现只截取文本,不截断标签。
代码
String.prototype.subtext = function(len) {
var sections = [];
var positions = [];
var me = this.replace(/<[^>]*>| /g, function(m, i) {
sections.push(m);
positions.push(i);
return "";
}).substr(0, len);
for (var i = 0; i < sections.length; i++) {
if (positions[i] > me.length) break;
me = me.substr(0, positions[i]) + sections[i] + me.substr(positions[i], me.length);
}
while (/<\/[^>]*>/.test(sections[i])) {
me += sections[i]; i++;
}
return me;
}
var sections = [];
var positions = [];
var me = this.replace(/<[^>]*>| /g, function(m, i) {
sections.push(m);
positions.push(i);
return "";
}).substr(0, len);
for (var i = 0; i < sections.length; i++) {
if (positions[i] > me.length) break;
me = me.substr(0, positions[i]) + sections[i] + me.substr(positions[i], me.length);
}
while (/<\/[^>]*>/.test(sections[i])) {
me += sections[i]; i++;
}
return me;
}
然后通过offsetHeight判断是否内容是否溢出。一般情况是一个固定高度div做容器,设置了overflow:hidden。有标题有内容,标题可能两行。
代码
function truncateContent(sh) {
var divDes = $('divDes');
var getTextLength = function() { return (divDes.innerText || divDes.textContent).length };
var divTitle = $('divTitle');
if (divTitle.offsetHeight > 25) sh -= 13;
var divDes = $('divDes');
var getTextLength = function() { return (divDes.innerText || divDes.textContent).length };
var divTitle = $('divTitle');
if (divTitle.offsetHeight > 25) sh -= 13;
if (divDes.offsetHeight < sh) return;
var len = getTextLength();
var ellipsis = " ......";
var des = divDes.innerHTML;
while (divDes.offsetHeight > sh) {
len = parseInt(len / 2);
divDes.innerHTML = des.subtext(len);
}
var step = 100, n = 20;
while (step > 1) {
while (divDes.offsetHeight < sh) {
divDes.innerHTML = des.subtext(getTextLength() + step - 7) + ellipsis;
if (--n < 1) break;
}
step = parseInt(step / 2);
while (divDes.offsetHeight > sh) {
divDes.innerHTML = des.subtext(getTextLength() - step - 7) + ellipsis;
if (--n < 1) break;
}
step = parseInt(step / 2);
}
des = divDes.innerHTML.substr(0, divDes.innerHTML.length - ellipsis.length);
divDes.innerHTML = des.substr(0, des.lastIndexOf(" ")) + ellipsis;
}
var len = getTextLength();
var ellipsis = " ......";
var des = divDes.innerHTML;
while (divDes.offsetHeight > sh) {
len = parseInt(len / 2);
divDes.innerHTML = des.subtext(len);
}
var step = 100, n = 20;
while (step > 1) {
while (divDes.offsetHeight < sh) {
divDes.innerHTML = des.subtext(getTextLength() + step - 7) + ellipsis;
if (--n < 1) break;
}
step = parseInt(step / 2);
while (divDes.offsetHeight > sh) {
divDes.innerHTML = des.subtext(getTextLength() - step - 7) + ellipsis;
if (--n < 1) break;
}
step = parseInt(step / 2);
}
des = divDes.innerHTML.substr(0, divDes.innerHTML.length - ellipsis.length);
divDes.innerHTML = des.substr(0, des.lastIndexOf(" ")) + ellipsis;
}
好像挺麻烦的,没办法,呼唤HTML 5赶紧推广吧。
这是效果:
昨天朋友(也是程序员)跟我说工作整天重复劳动没意思,又学不到东西。可是据我所见,到处都有可学的东西,这一点东西都要研究这么久。虽然本身价值可能有限(subtext函数应该是比较有用的,还可以.Net后台实现),但至少锻炼了正则替换和算法,这是Copy多少代码也挣不来滴。