2015-06-03 70 views
1

如何用jQuery截斷文本,但保留HTML? 嘗試使用以下代碼,但不幸的是不會返回HTML格式。如何用jQuery截斷文本,但保持HTML格式?

var truncate = function() { 
    $('p.truncated').text(function(index, oldText) { 
    if (oldText.length > 20) { 
     return '...' + oldText.substr(-25); 
    } 
    return oldText; 
    }); 
} 

如果您運行該代碼段,您將看到我正在尋找的內容。

var truncate = function() { 
 
    $('p.truncated').text(function(index, oldText) { 
 
    if (oldText.length > 20) { 
 
     return '...' + oldText.substr(-25); 
 
    } 
 
    return oldText; 
 
    }); 
 
} 
 

 
truncate(); 
 

 

 

 

 
var truncate2 = function() { 
 
    $("p.truncated2").each(function() { 
 
    //var theContent = $(this).text(); 
 
    var theContent = $(this).html(); 
 
    var n = theContent.substr(-25); 
 
    $(this).html('...' +n); 
 
    }); 
 

 
} 
 

 
truncate2();
p { 
 
    margin: 0 0 30px 0; 
 
    display: block; 
 
    padding: 5px; 
 
} 
 
streak { 
 
    color: green; 
 
} 
 
double { 
 
    color: orange; 
 
} 
 
p span { 
 
    color: grey; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
How to make something like this... 
 
<p class="sheet"> 
 
    <streak>start</streak> 
 
    <streak>1</streak> 
 
    <streak>2</streak> 
 
    <double>3</double> 
 
    <double>4</double> 
 
    <span>5</span> 
 
    <span>6</span> 
 
    <streak>7</streak> 
 
    <streak>8</streak> 
 
    <double>9</double> 
 
    <double>10</double> 
 
    <streak>end</streak> 
 
</p> 
 
...becomes something like this with jquery? 
 
<p> 
 
    ... 
 
    <span>6</span> 
 
    <streak>7</streak> 
 
    <streak>8</streak> 
 
    <double>9</double> 
 
    <double>10</double> 
 
    <streak>end</streak> 
 
</p> 
 
<hr />Here is a try with jquery but it return text without html elements. 
 
<p class="truncated"> 
 
    <streak>start</streak> 
 
    <streak>1</streak> 
 
    <streak>2</streak> 
 
    <double>3</double> 
 
    <double>4</double> 
 
    <span>5</span> 
 
    <span>6</span> 
 
    <streak>7</streak> 
 
    <streak>8</streak> 
 
    <double>9</double> 
 
    <double>10</double> 
 
    <streak>end</streak> 
 
</p> 
 
The second try 
 
<p class="truncated2"> 
 
    <streak>start</streak> 
 
    <streak>1</streak> 
 
    <streak>2</streak> 
 
    <double>3</double> 
 
    <double>4</double> 
 
    <span>5</span> 
 
    <span>6</span> 
 
    <streak>7</streak> 
 
    <streak>8</streak> 
 
    <double>9</double> 
 
    <double>10</double> 
 
    <streak>end</streak> 
 
</p> 
 
How can I keep html elements?

回答

1

你一定想先拆分子元素。

var truncate = function() { 
 
    var $elem = $('p.truncated'); 
 
    var html = $elem.html().split(/>\s*</); 
 
    
 
    if(html.length > 5) 
 
    html = "... <" + html.slice(-6).join('> <'); 
 
    
 
    $elem.html(html); 
 
} 
 
truncate();
p { 
 
    margin: 0 0 30px 0; 
 
    display: block; 
 
    padding: 5px; 
 
} 
 
streak { 
 
    color: green; 
 
} 
 
double { 
 
    color: orange; 
 
} 
 
p span { 
 
    color: grey; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<p class="truncated"> 
 
    <streak>start</streak> 
 
    <streak>1</streak> 
 
    <streak>2</streak> 
 
    <double>3</double> 
 
    <double>4</double> 
 
    <span>5</span> 
 
    <span>6</span> 
 
    <streak>7</streak> 
 
    <streak>8</streak> 
 
    <double>9</double> 
 
    <double>10</double> 
 
    <streak>end</streak> 
 
</p>

+0

謝謝塞繆爾,如果長度值優越,它就會失敗。例如,如果我將6改爲12. if(html.length> 12); html =「... <」+ html.slice(-12).join('><'); – Paul

+0

您可以隨時進行檢查以查看分割後有多少元素,並避免切分超過該值。答案只是向你展示這個概念。 –

+0

這是真的。謝謝:) – Paul

0

伴侶,取代你

var theContent = $(this).html(); 

var theContent = $(this).outerHTML(); 
+0

當人們downvote?請問你爲什麼留言? –

2

如果你想保持計數字符數,你可以使用range對象也。你設置你想要刪除的範圍,它也會刪除節點。所以你操縱文字,但你保持html標籤。

var truncate = function() { 
 
    var range_all = document.createRange(); 
 
    range_all.selectNodeContents(document.getElementsByClassName('truncated')[0]); 
 
    if (range_all.endOffset > 20) { 
 
    range_all.setEnd(document.getElementsByClassName('truncated')[0], range_all.endOffset - 12); 
 
    range_all.deleteContents(); 
 
    $('p.truncated').html('... ' + $('p.truncated').html()); 
 
    } 
 

 
} 
 

 
truncate(); 
 

 

 

 

 
var truncate2 = function() { 
 
    $("p.truncated2").each(function() { 
 
    //var theContent = $(this).text(); 
 
    var theContent = $(this).html(); 
 
    var n = theContent.substr(-25); 
 
    $(this).html('...' + n); 
 
    }); 
 

 
} 
 

 
truncate2();
p { 
 
    margin: 0 0 30px 0; 
 
    display: block; 
 
    padding: 5px; 
 
} 
 
streak { 
 
    color: green; 
 
} 
 
double { 
 
    color: orange; 
 
} 
 
p span { 
 
    color: grey; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
How to make something like this... 
 
<p class="sheet"> 
 
    <streak>start</streak> 
 
    <streak>1</streak> 
 
    <streak>2</streak> 
 
    <double>3</double> 
 
    <double>4</double> 
 
    <span>5</span> 
 
    <span>6</span> 
 
    <streak>7</streak> 
 
    <streak>8</streak> 
 
    <double>9</double> 
 
    <double>10</double> 
 
    <streak>end</streak> 
 
</p> 
 
...becomes something like this with jquery? 
 
<p> 
 
    ... 
 
    <span>6</span> 
 
    <streak>7</streak> 
 
    <streak>8</streak> 
 
    <double>9</double> 
 
    <double>10</double> 
 
    <streak>end</streak> 
 
</p> 
 
<hr />If text is longer than 25 character, select until 12th and delete selection. Then add '...' at the beginning. 
 
<p class="truncated"> 
 
    <streak>start</streak> 
 
    <streak>1</streak> 
 
    <streak>2</streak> 
 
    <double>3</double> 
 
    <double>4</double> 
 
    <span>5</span> 
 
    <span>6</span> 
 
    <streak>7</streak> 
 
    <streak>8</streak> 
 
    <double>9</double> 
 
    <double>10</double> 
 
    <streak>end</streak> 
 
</p> 
 
The second try 
 
<p class="truncated2"> 
 
    <streak>start</streak> 
 
    <streak>1</streak> 
 
    <streak>2</streak> 
 
    <double>3</double> 
 
    <double>4</double> 
 
    <span>5</span> 
 
    <span>6</span> 
 
    <streak>7</streak> 
 
    <streak>8</streak> 
 
    <double>9</double> 
 
    <double>10</double> 
 
    <streak>end</streak> 
 
</p> 
 
How can I keep html elements?

2

這是任何CMS或博客,其中傳情應出示開始的一篇文章的一個經典難題:通常解決的辦法是要麼剝離其標籤文字和削減在精確計數或保持標籤,但近似切,因爲代碼會被計太...

這是我的一種方式,同時滿足exigences(保留標籤和在精確計數切)建議:

function cutKeepingTags(elem, count) { 
    var matches = $(elem).html().match(/([^<])*(<.*>)?(.*)/), 
    // To be more clear, let's "rename" what we get: 
    textBefore = matches[1] || '', 
    children = matches[2] || '', 
    textAfter = matches[3] || ''; 
    if (textBefore.length <= count) { 
    // cool, already that's end! 
    return textBefore.substr(count); 
    } 
    if ($(elem).text().length == textBefore.length + textAfter.length) { 
    /* (remember that .text() returns the concatenation of all text nodes found 
     deeply in the element) 
     If equal there is no child (or there are children but no text in them), 
     so we can simply keep children and text enough after children: 
    */ 
    return textBefore + chidren + textAfter.substr(count - textBefore.length); 
    } 
    // Otherwise we must loop through children to get more text: 
    var grabText = textBefore; 
    $(elem).children().each(function() { 
    // Get text from current child: 
    grabText += cutKeepingTags(this, count - grabText.length); 
    if (grabText.length == count) { 
     // We already got text enough: 
     return grabText; 
    } 
    }); 
    // No more child and count not reached, return what we got. 
    return grabText; 
} 

未經測試!


編輯:
終於得到了實用的解決方案:你找到它here on Code Review