How to avoid infinite cycle in function / call that reduces letter size?

2

I've created this small jQuery extension that aims to reduce the size of text by setting% css% of CSS based on% of its container%.

The operation is simple, find the current font size and remove a pixel, then apply a new CSS definition for the element in question:

;(function ($) {

    $.fn.fitWidth = function( options ) {

        var opts = $.extend({
            min: "11"
        }, options );

        var tamanho = parseInt(this.css('font-size'));

        if (tamanho > opts.min) {
            return this.css({
                'font-size': tamanho-1        
            });
        }
    };
}( jQuery ));

However, there is a problem:

If the letter indicated by the user, or until the default minimum value is not low enough to avoid font-size , calling this extension will cause an infinite loop:

$('#wrap span').each(function(){
    var $this = $(this),
        overflow = $this[0].scrollWidth > $this.width() ? true : false;

    if (overflow) {
        while (overflow) {
            $this.fitWidth({"min":'1'});
            overflow = $this[0].scrollWidth > $this.width() ? true : false;
        }
    }
});

With letter minimum to 11 for example, we will have an infinite loop.

Example for 1 JSFiddle , but beware of changing the value to test, an infinite loop of JavaScript may cause the browser to stop working.

Question:

How can I change the extension or call of it, in order to avoid infinite cycles?

    
asked by anonymous 23.12.2013 / 16:25

1 answer

2

The first idea that comes to me is to limit the while to the current size in pixels, as follows:

$('#wrap span').each(function(){
    var $this = $(this),
        overflow = $this[0].scrollWidth > $this.width() ? true : false;

    if (overflow) {
        var size = parseInt($this.css('font-size'));
        while (overflow && size-- > 1) {
            $this.fitWidth({"min":'1'});
            overflow = $this[0].scrollWidth > $this.width() ? true : false;
        }
    }
});

I updated the example in jsfiddle .

Obviously it would be good to make a value treatment. And in case you can not recover an integer or be in another unit, you could limit yourself to a maximum number that, although less elegant, would avoid locking the browser or the flap.

Alternatively, the function added to jQuery could encapsulate full logic, simplifying use:

;(function ($) {

    $.fn.fitWidth = function( options ) {

        var opts = $.extend({
            min: "11"
        }, options );

        this.each(function() {

            var $this = $(this);
            var tamanho = parseInt($this.css('font-size'));

            var overflow = $this[0].scrollWidth > $this.width() ? true : false;
            while (overflow && tamanho > opts.min && tamanho-- > 1) {
                $this.css({
                    'font-size': tamanho
                });
                overflow = $this[0].scrollWidth > $this.width() ? true : false;
            }

        });
        return this;

    };
}( jQuery ));

The usage gets simpler and the function encapsulated:

$('#wrap span').fitWidth({"min":'1'}); 

See another version on jsfiddle .

    
23.12.2013 / 16:47