话说博客园首页有个文章列表,大家注意到了吧?好像是废话。布局上马马虎虎过得去,不过细看,偶眼光比咱首都的车检员差得远,还是能发现有违背社会和谐之处:

  各个文章的概要长度七零八落,看上去不太齐整。前几天项目中也碰到这样问题,而且要截的内容可能包含许多RichText。现在没有一个浏览器支持哪种样式,可以将在超出范围内容自动截断并加省略号。我等追求完美之人,怎么能一个substring了之呢?不信邪,研究了大半天,还真搞出了点名堂。现在地皮好贵,文字也得蜗居,不过比较人性化一点,固定的容器显示尽可能多的内容,超过了加省略号。这篇文章就想解决这么点问题,跟不屑的朋友说声Sorry。

  对于留下来的朋友, 也不废话了,直接上代码:先实现只截取文本,不截断标签。

代码
    String.prototype.subtext = function(len) { 
        
var sections = [];
        
var positions = [];

        
var me = this.replace(/<[^>]*>|&nbsp;/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
         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 (--< 1break;
            }
            step = parseInt(step / 2);

            
while (divDes.offsetHeight > sh) {
                divDes.innerHTML = des.subtext(getTextLength() - step - 7+ ellipsis;
                
if (--< 1break;
            }
            step = parseInt(step / 2);
        }
        des = divDes.innerHTML.substr(0, divDes.innerHTML.length - ellipsis.length);
        divDes.innerHTML = des.substr(0des.lastIndexOf(" ")) + ellipsis;
    }

   好像挺麻烦的,没办法,呼唤HTML 5赶紧推广吧。

  这是效果:

  

  昨天朋友(也是程序员)跟我说工作整天重复劳动没意思,又学不到东西。可是据我所见,到处都有可学的东西,这一点东西都要研究这么久。虽然本身价值可能有限(subtext函数应该是比较有用的,还可以.Net后台实现),但至少锻炼了正则替换和算法,这是Copy多少代码也挣不来滴。

posted on 2010-03-18 19:20  小城故事  阅读(1921)  评论(8编辑  收藏  举报