views:

2293

answers:

3

I'm trying to use jquery to write a fast function that calculates the pixel width of a string on a html page, then truncates the string until it reaches an ideal pixel width...

However it's not working (the text doesn't truncate)...

Here is the code I have:

    function constrain(text, original, ideal_width){

 var temp_item = ('<span class="temp_item" style="display:none;">'+ text +'</span>');
 $(temp_item).appendTo('body');
 var item_width = $('span.temp_item').width();
 var ideal = parseInt(ideal_width);
 var smaller_text = text;

 while (item_width > ideal) {
  smaller_text = smaller_text.substr(0, (smaller_text-1));
  $('.temp_item').html(text);
  item_width = $('span.temp_item').width();
 }

 var final_length = smaller_text.length;

 if (final_length != original) {
  return (smaller_text + '&hellip;');
 } else {
     return text;
 }
}

Here's how I'm calling it from the page:

    $('.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);
});

Any ideas on what I'm doing wrong? If there is a way to do it faster (ie bubble sort), that would be great too.

Thanks!

+2  A: 

On this line:

smaller_text = smaller_text.substr(0, (smaller_text-1));

you may have intended

smaller_text = smaller_text.substr(0, (smaller_text.length-1));

Does that solve the problem?

DDaviesBrackett
A: 

Thanks, I got it working - but it only works on the first item and stops, does this have to do with the way I'm declaring variables?

here's the current code:

    function constrain(text, original, ideal_width){

 var temp_item = ('<span class="temp_item" style="display:none;">'+ text +'</span>');
 $(temp_item).appendTo('body');
 var item_width = $('span.temp_item').width();
 var ideal = parseInt(ideal_width);
 var smaller_text = text;

 while (item_width > ideal) {
  smaller_text = smaller_text.substr(0, (smaller_text.length-1));
  $('.temp_item').html(smaller_text);
  item_width = $('span.temp_item').width();
 }

 var final_length = smaller_text.length;

 if (final_length != original) {
  return (smaller_text + '&hellip;');
 } else {
     return text;
 }
}
novon
I don't see anything obviously wrong with declarations that'd cause it to fail on subsequent items. You're sure your selector is applying to multiple items?(also, please don't forget to mark my answer as a solution if you think it deserves it =) )
DDaviesBrackett
It works fast in Safari - but takes too long in firefox... any way to make the while statement more efficient?
novon
BTW - I got it working on all by moving the :var temp_item = ('<span class="temp_item" style="display:none;">'+ text +'</span>'); $(temp_item).appendTo('body');To the outside of the function... but the speed issue in firefox and slower browsers still lingers!Thanks for the help so far
novon
A: 

Hi, now it works fine! The function takes the text to check, the ideal_width in pixel and the class name for the css. If the ideal_width is less than the text width it truncs and adds the hellip otherwise it returns the text unmodified. Simple and works! :-)

function constrain(text, ideal_width, className){

    var temp_item = ('<span class="'+className+'_hide" style="display:none;">'+ text +'</span>');
    $(temp_item).appendTo('body');
    var item_width = $('span.'+className+'_hide').width();
    var ideal = parseInt(ideal_width);
    var smaller_text = text;

    if (item_width>ideal_width){
        while (item_width > ideal) {
            smaller_text = smaller_text.substr(0, (smaller_text.length-1));
            $('.'+className+'_hide').html(smaller_text);
            item_width = $('span.'+className+'_hide').width();
        }
        smaller_text = smaller_text + '&hellip;'
    }
    $('span.'+className+'_hide').remove();
    return smaller_text;
}
Angelo N.