2

textfill何百もの div で名前が付けられた以下の jQuery 関数を使用します。基本的に、テキストのフォントサイズが最大になるように、内側のテキストのサイズを囲んでいる div に合わせてサイズ変更します。したがって、長いテキストは短いテキストよりも小さくなりますが、div からオーバーフローしないように最大のフォント サイズになります。

; (function($) {
    /**
    * Resizes an inner element's font so that the inner element completely fills the outer element.
    * @version 0.1
    * @param {Object} Options which are maxFontPixels (default=40), innerTag (default='span')
    * @return All outer elements processed
    * @example <div class='mybigdiv filltext'><span>My Text To Resize</span></div>
    */
    $.fn.textfill = function(options) {
        var defaults = {
            maxFontPixels: 40,
            innerTag: 'span'
        };
        var Opts = jQuery.extend(defaults, options);
        return this.each(function() {
            var fontSize = Opts.maxFontPixels;
            var ourText = $(Opts.innerTag + ':visible:first', this);
            var maxHeight = $(this).height();
            var maxWidth = $(this).width();
            var textHeight;
            var textWidth;
            do {
                ourText.css('font-size', fontSize);

                textHeight = ourText.height();
                textWidth = ourText.width();
                fontSize = fontSize - 1;
            } while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
            var pos = (maxHeight-textHeight)/2;
            ourText.css('top', pos +'px');
        });
    };
})(jQuery);

次のような何百もの div でこのスクリプトを実行するためです。

<div class="textDiv"><span>text appears here</span></div>

同時に以下を使用します。

$('.textDiv').each(function() { $(this).textfill({ maxFontPixels: 28 })});  

div の量にもよりますが、40 秒から 70 秒かかります。より速く実行できるようにコードを調整する必要があります。過去 2 時間試してみましたが、高速に実行できないようです。誰か助けてくれませんか?

編集:

コメントからいくつかの入力を取得し、コードを次のように変更しました。

var items = document.getElementsByClassName("textDiv");
for (var i = items.length; i--;) {
    $(items[i]).textfill({ maxFontPixels: 28 });
}

少し速くなったように見えますが、それでも非常に遅いです。

4

2 に答える 2

1

$('.textDiv').each(function() { $(this).textfill({ maxFontPixels: 28 })});

関数の使い方が間違っています。すべての (適切な) プラグインは既に jQuery コレクションで動作しておりeach、呼び出し時にプラグインを配置する必要がないように組み込み済みです。やるだけ

$('.textDiv').textfill({ maxFontPixels: 28 });

しかし、それはあなたの実際の問題ではないと思います。ループは非常に高速で、数百のアイテムでも数秒かかりません。問題は

            ourText.css('font-size', fontSize);
            textHeight = ourText.height();
            textWidth = ourText.width();

ブラウザによる完全なリフローが必要なため、ループ内 (実際には 2 つのネストされたループ内)。この部分への呼び出しを最小限に抑える必要があります。たとえば、ある種の二分探索 ( bisection ) を使用したり、フォント サイズに近似する補間メトリック (文字数を面積で割ったものなど) を適用したりして、良い開始値。

それに加えて、他のマイナーな最適化があるかもしれません:

  • キャッシュ$(this)
  • $(Opts.innerTag + ':visible:first', this);非常に複雑なセレクターのように見えます。それは本当に必要ですか、隠し要素を期待していますか? そのようなエクストラをオプションに移動し$(this).children().first()、デフォルトで使用します。
  • あなたのCSSについてはよくわかりませんが、divのサイズをどのように設定しますか(maxHeight/として取得しますmaxWidth)?内部のフォントサイズを変更する際のリフロー コストを削減するために、追加overflow:hiddenが役立ちます。
于 2013-04-06T12:44:57.770 に答える
0

明らかに、ボトルネックは最内ループです (次は最内ループの親などです)。

フォントサイズを調べるために「二分法」を使用しないのはなぜですか?:

200 div の場合:


Bisect ソリューション (リファクタリングが必要):

http://jsfiddle.net/nx2n2/8/

Time: ~700

現在の解決策:

http://jsfiddle.net/pXL5z/3/

Time: ~1400

最も重要なコード:

        var change = Math.ceil(fontSize / 2);
        while(true) {
            change = Math.ceil(change / 2);

            var prev = fontSize;
            do {
                fontSize = fontSize - change;
                ourText.css('font-size', fontSize);

                textHeight = ourText.height();
                textWidth = ourText.width();
            } while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);

            change = Math.ceil(change / 2);            
            while (textHeight < maxHeight && textWidth < maxWidth) {
                fontSize = fontSize + change;
                ourText.css('font-size', fontSize);

                textHeight = ourText.height();
                textWidth = ourText.width();
            }

            var current = fontSize;
            if(prev == current) {
                break;
            }
        }

        // this is because you subtract after change in your original solution
        // only for 'compatibility' with original solution
        fontSize = fontSize - 1;
于 2013-04-06T12:38:48.473 に答える