I'm developing a Classic ASP page that pulls some content from a database and creates a Read more link after the first 100 characters as follows;
<div class="contentdetail"><%=StripHTML(rspropertyresults.Fields.Item("ContentDetails").Value)%></div>
<script type="text/javascript">
$(function() {
var cutoff = 200;
var text = $('div.contentdetail').text();
var rest = $('div.contentdetail').text().substring(cutoff);
if (text.length > 200) {
var period = rest.indexOf('.');
var space = rest.indexOf(' ');
cutoff += Math.max(Math.min(period, space), 0);
}
var visibleText = $('div.contentdetail').text().substring(0, cutoff);
$('div.contentdetail')
.html(visibleText + ('<span>' + rest + '</span>'))
.append('<a title="Read More" style="font-weight:bold;display: block; cursor: pointer;">Read More…</a>')
.click(function() {
$(this).find('span').toggle();
$(this).find('a:last').hide();
});
$('div.contentdetail span').hide();
});
</script>
However, the script obviously just cuts the text off after 100 characters. Preferably I would like it to keep on writing text until the first period or space, for example. Is this possible to do?
Thank you.
I'm developing a Classic ASP page that pulls some content from a database and creates a Read more link after the first 100 characters as follows;
<div class="contentdetail"><%=StripHTML(rspropertyresults.Fields.Item("ContentDetails").Value)%></div>
<script type="text/javascript">
$(function() {
var cutoff = 200;
var text = $('div.contentdetail').text();
var rest = $('div.contentdetail').text().substring(cutoff);
if (text.length > 200) {
var period = rest.indexOf('.');
var space = rest.indexOf(' ');
cutoff += Math.max(Math.min(period, space), 0);
}
var visibleText = $('div.contentdetail').text().substring(0, cutoff);
$('div.contentdetail')
.html(visibleText + ('<span>' + rest + '</span>'))
.append('<a title="Read More" style="font-weight:bold;display: block; cursor: pointer;">Read More…</a>')
.click(function() {
$(this).find('span').toggle();
$(this).find('a:last').hide();
});
$('div.contentdetail span').hide();
});
</script>
However, the script obviously just cuts the text off after 100 characters. Preferably I would like it to keep on writing text until the first period or space, for example. Is this possible to do?
Thank you.
Share Improve this question edited Oct 22, 2009 at 11:24 doubleplusgood asked Oct 22, 2009 at 10:31 doubleplusgooddoubleplusgood 2,55611 gold badges45 silver badges65 bronze badges 1- Maybe I got your question wrong, but you do know of the String.indexOf() function which returns the index of the first occurence of a certain substring (or -1 if the part was not found). Example: alert("foobar".indexOf("b")) alerts "3" as the index of "b". Maybe you can use this to truncate the string at the desired position? – BMBM Commented Oct 22, 2009 at 10:38
3 Answers
Reset to default 4var cutoff = 100;
var text = $('div.contentdetail').text();
var rest = text.substring(cutoff);
if (text.length > cutoff) {
var period = rest.indexOf('.');
var space = rest.indexOf(' ');
cutoff += Math.max(Math.min(period, space), 0);
}
// Assign the rest again, because we recalculated the cutoff
rest = text.substring(cutoff);
var visibleText = $('div.contentdetail').text().substring(0, cutoff);
EDIT: shortened it a bit. EDIT: Fixed a bug EDIT: QoL improvement
How about:
var text= $('div.contentdetail').text();
var match= text.match( /^(.{100}([^ .]{0,20}[ .])?)(.{20,})$/ );
if (match!==null) {
var visibleText = match[1];
var textToHide = match[3];
...do replacement...
}
The {0,20}
will look forward for a space or period for up to 20 characters before giving up and breaking at exactly 100 characters. This stops an extremely long word from breaking out of the length limitation. The {20,}
at the end stops a match being made when it would only hide a pointlessly small amount of content.
As for the replacement code, don't do this:
.html(visibleText + ('<span>' + textToHide + '</span>'))
This is inserting plain-text into an HTML context without any escaping. If visibleText
or textToHide
contains any <
or &
characters you will be mangling them, perhaps causing a XSS security problem in the process.
Instead create the set the text()
of the div and the span separately, since that's the way you read the text in the first place.
Here is a fairly simple approach to getting endings at the word level, and shooting for about your given limit in characters.
var limit = 100,
text = $('div.contentdetail').text().split(/\s+/),
word,
letter_count = 0,
trunc = '',
i = 0;
while (i < text.length && letter_count < limit) {
word = text[i++];
trunc += word+' ';
letter_count = trunc.length-1;
}
trunc = $.trim(trunc)+'...';
console.log(trunc);