如何使这个jQuery“缩小文本”功能更有效?使用二进制搜索?

时间:2009-05-28 00:19:46

标签: javascript jquery

我构建了一个jQuery函数,它接受一个文本字符串和一个宽度作为输入,然后收缩那段文本,直到它不大于宽度,如下所示:

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

这很好用,但因为我在很多文本上调用了这个功能,除了Safari 4和Chrome之外的任何浏览器,它都很慢。

我尝试使用二进制搜索方法来提高效率,但到目前为止我在浏览器中显示了一个缓慢的脚本对话框:

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

有没有人知道我应该做些什么才能使这项功能尽可能高效?

谢谢!西蒙

2 个答案:

答案 0 :(得分:1)

您的脚本问题可能是while条件(item_width != ideal)可能永远不会中止循环。可能无法将输入文本修剪为精确宽度ideal。在这种情况下,您的函数将永远循环,这将触发慢速脚本对话框。

为了避免这种情况,你应该停止循环,如果显示的文字足够小(也就是说,添加更多的字符会使它太大)。

答案 1 :(得分:1)

我使用了2个div

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

.englober有一个固定的with和overflow:hidden,white-space:nowarp。

然后使用jQuery,我调整.title中的文本大小以适应.englober:

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