2009-05-28 11 views
0

J'ai construit fonction jQuery qui prend une chaîne de texte et une largeur en entrée, puis se rétracte ce morceau de texte jusqu'à ce qu'il n'y a pas de plus grand que la largeur, comme ceci:Comment rendre cette fonction "shrink text" de jQuery plus efficace? Avec la recherche binaire?

function constrain(text, ideal_width){ 
    var temp = $('.temp_item'); 
    temp.html(text); 
    var item_width = temp.width(); 
    var ideal = parseInt(ideal_width); 
    var smaller_text = text; 
    var original = text.length; 

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

    var final_length = smaller_text.length; 
    if (final_length != original) { 
     return (smaller_text + '…'); 
    } else { 
     return text; 
    } 
} 

Cela fonctionne bien, mais parce que je J'appelle la fonction sur beaucoup de morceaux de textes, sur n'importe quel navigateur sauf Safari 4 et Chrome, c'est vraiment lent.

J'ai essayé d'utiliser une méthode de recherche binaire pour le rendre plus efficace, mais ce que j'ai tellement apporte beaucoup une boîte de dialogue de script lent dans mon navigateur:

function constrain(text, ideal_width){ 
    var temp = $('.temp_item'); 
    temp.html(text); 
    var item_width = temp.width(); 
    var ideal = parseInt(ideal_width); 

    var lower = 0; 
    var original = text.length; 
    var higher = text.length; 

    while (item_width != ideal) { 

     var mid = parseInt((lower + higher)/2); 
     var smaller_text = text.substr(0, mid); 
     temp.html(smaller_text); 
     item_width = temp.width(); 

     if (item_width > ideal) { 

      // make smaller to the mean of "lower" and this 
      higher = mid - 1; 

     } else { 

      // make larger to the mean of "higher" and this 
      lower = mid + 1; 

     } 
    } 

    var final_length = smaller_text.length; 
    if (final_length != original) { 
     return (smaller_text + '…'); 
    } else { 
     return text; 
    } 
} 

Quelqu'un at-il une idée de ce que je devrait faire pour rendre cette fonction aussi efficace que possible?

Merci! Simon

+0

Pouvez-vous décrire votre but? Il me semble qu'il serait plus facile de placer le texte dans un bloc de largeur fixe avec overflow: hidden. – Joel

+0

@Joel La raison pour laquelle je veux faire ceci est que le texte qui déborde a une ellipse (...) qui y est ajoutée. – Simon

Répondre

1

Le problème avec votre script est probablement que la condition while(item_width != ideal) n'annulera peut-être jamais la boucle. Il se peut qu'il ne soit pas possible d'ajuster le texte d'entrée à la largeur exacte ideal. Dans ce cas, votre fonction bouclera pour toujours, ce qui déclenchera la boîte de dialogue de script lent.

Pour contourner cela, vous devez arrêter de faire une boucle si le texte affiché est juste assez petit (alias ajouter plus de caractères le rendrait trop grand).

+0

Merci sth. Je vais essayer! – Simon

1

J'ai utilisé 2 divs

<div class="englober"> 
<div class="title"></div> 
</div> 

le .englober a un fixe avec et overflow: hidden, white-space: NoWarp.

Ensuite, en utilisant jQuery, je redimensionner le texte de la .title pour adapter la .englober avec:

while ($(".title").width() > $(".englober").width()) 
{ 
    var dFontsize = parseFloat($(".title").css("font-size"), 10); 
    $(".title").css("font-size", dFontsize - 1); 
} 
Questions connexes