Truncation width function does not work when passing integer
I'm trying to create a generic function that I can call from multiple places to crop long text recursively to fit a predefined pixel width - using jquery.
Here is the code ...
function constrain(text, original, ideal_width){
var ideal = parseInt(ideal_width);
$('span.temp_item').remove();
var temp_item = ('<span class="temp_item" style="display:none">'+ text +'</span>');
var item_length = text.length;
$(temp_item).appendTo('body');
var item_width = $('span.temp_item').width();
if (item_width > ideal) {
var smaller_text = text.substr(0, (item_length-1));
return constrain(smaller_text, original);
} else if (item_length != original) {
return (text + '…');
} else if (item_length == original) {
return text;
}
}
If I run the function like this:
$('.service_link span:odd').each(function(){
var item_text = $(this).text();
var original_length = item_text.length;
var constrained = constrain(item_text, original_length,'175');
$(this).html(constrained);
});
The text is not cut off. I've also tried 175 without quotes.
If I define var ideal = 175; inside a function, then it works. Why is function 175 not working? I did a parseInt on it if it was a string.
Also, this truncation code slows down a bit on older machines - any hints to speed it up?
Thanks!
a source to share
Great stuff here. I used Phil Carter's function. I just wanted the newline with & hellip to be truncated to the same width as the rest.
I just quickly added another time-width search and recursive call. Some cleaning can be used, but it works. here is a new time:
while(item_width > ideal) {
var smaller_text = text.substr(0, (item_length-1));
return constrain(smaller_text, original, ideal_width, counter);
}
if (item_length != original) {
new_text=text+'…';
$('span.temp_item').remove();
var temp_item = ('<span class="temp_item" style="display:none">'+ new_text +'</span>');
$(temp_item).appendTo('body');
var item_width_new = $('span.temp_item').width();
if(item_width_new>ideal){
var smaller_text = text.substr(0, (item_length-1));
return constrain(smaller_text, original, ideal_width, counter);
}
else {
return new_text;
}
} else if (item_length == original) {
return text;
}
}
a source to share
TOTAL WE FIND
So, I decided that your iteration over the lorum ipsum text in 5 gaps, taking 16 seconds, was too long, so I figured out how to speed it up. and I have it up to 0.4 seconds.
function constrain(text, original, ideal_width, counter){
var ideal = parseInt(ideal_width);
$('span.temp_item').remove();
var temp_item = ('<span class="temp_item" style="display:none">'+ text +'</span>');
var item_length = text.length;
$(temp_item).appendTo('body');
var item_width = $('span.temp_item').width();
if(counter == 0) {
//work out some ranges
var temp_item = ('<span class="temp_item_i" style="display:none">i</span>');
$(temp_item).appendTo('body');
var i_width = $('span.temp_item_i').width();
var max_i = Math.round((ideal_width / i_width) + 1);
var temp_item = ('<span class="temp_item_m" style="display:none">M</span>');
$(temp_item).appendTo('body');
var m_width = $('span.temp_item_m').width();
var max_m = Math.round((ideal_width / m_width) + 1);
text = text.substr(0, (max_i - max_m));
var item_length = text.length;
}
counter++;
while(item_width > ideal) {
var smaller_text = text.substr(0, (item_length-1));
return constrain(smaller_text, original, ideal_width, counter);
}
if (item_length != original) {
return (text + '…');
} else if (item_length == original) {
return text;
}
}
$(document).ready(function() {
var d = new Date();
var s = d.getTime();
$('.service_link').each(function(){
var item_text = $(this).text();
var original_length = item_text.length;
var constrained = constrain(item_text, original_length, 175, 0);
$(this).html(constrained);
});
var e = d.getTime()
alert('Time Taken: ' + ((e - s)/1000));
});
Basically on first run it determines how many lowercase strings and how many upper Ms fit into the space, and then limits the length of the text before that, this greatly reduces the number of iterations.
Hope this helps.
a source to share