简体   繁体   中英

How can I make this jQuery “shrink text” function more efficient? With binary Search?

I've built jQuery function that takes a text string and a width as inputs, then shrinks that piece of text until it's no larger than the width, like so:

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;
    }
}

This works fine, but because I'm calling the function on many pieces of texts, on any browser except Safari 4 and Chrome, it's really slow.

I've tried using a binary search method to make this more efficient, but what I have so far brings up a slow script dialog in my browser:

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;
    }
}

Does anyone have an idea of what I should be doing to make this function as efficient as possible?

Thanks! Simon

I used 2 divs

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

the .englober has a fixed with and overflow:hidden, white-space:nowarp.

Then using jQuery, i resize the text from the .title to fit the .englober with :

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

The problem with your script is probably that the while condition (item_width != ideal) possibly will never abort the loop. It might not be possible to trim the input text to the exact width ideal . In this case your function will loop forever, which will trigger the slow script dialog.

To circumvent this you should stop looping if the displayed text is just small enough (aka. adding more characters would make it too big).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM