Почему этот цикл JavaScript бесконечен? - PullRequest
2 голосов
/ 13 сентября 2011

Я ненавижу это делать.Это маленький кусочек, чтобы закончить большой проект, и мой разум зажарен ...

Вот код.Он проверяет, не переполнен ли элемент, и не изменяет ли размер шрифта.Предполагается изменить его размер, пока он не переполнится.Условие для цикла, кажется, игнорируется, и браузер зависает ... Я чувствую, что мне не хватает чего-то важного в том, как работает jQuery.

$.fn.fontBefitting = function() {
    var _elm = $(this)[0];
    var _hasScrollBar = false; 
    while ((_elm.clientHeight < _elm.scrollHeight) || (_elm.clientWidth < _elm.scrollWidth)) {
        var fontSize = $(this).css('fontSize');
        fontSize = parseInt(fontSize.substring(0,fontSize.length-2))*0.95;
        $(this).css('fontSize',fontSize+'px');          
    }

}

Заранее спасибо.

Ответы [ 6 ]

4 голосов
/ 13 сентября 2011

Изменение:

 fontSize = parseInt(fontSize.substring(0,fontSize.length-2))*0.95;

на:

 fontSize = parseInt(fontSize.substring(0,fontSize.length-2))-1;

Вот вам Рабочая демонстрация .Когда размер шрифта достиг 10px, 10 * .95 был 9.5, а браузер округлял до 10px.Таким образом, бесконечный цикл.

3 голосов
/ 13 сентября 2011

Вам нужно пройтись по коду в отладчике и фактически проверить значения условий, чтобы убедиться, что они меняются так, как вы ожидаете.Я думаю, _elm.clientHieght и _elm.clientWidth на самом деле не меняются.

1 голос
/ 13 сентября 2011

У вас есть не связанные проблемы, когда вы делаете

$('div').fontBefitting()

Это позволит сделать текст в первом элементе div соответствующим его размеру, а затем сделать размер шрифта всех остальных элементов div таким же, как и в первом. Это не похоже на предполагаемое поведение. Вы бы надеялись, что это заставит каждый div изменить свой текст и соответствовать только его тексту.

Вам нужно изменить свой код на это:

$.fn.fontBefitting = function() {
    /* $.fn.* runs on a jQuery object. Make sure to return it for chaining */
    return this.each(function() {
        var fontSize = parseInt($(this).css('fontSize'));
        while (this.clientHeight < this.scrollHeight ||
               this.clientWidth < this.scrollWidth) {
            fontSize--;
            $(this).css('fontSize', fontSize + 'px');          
        }
    });
}
1 голос
/ 13 сентября 2011

Возможно, вы работаете в бесконечном цикле, потому что размер шрифта фактически не меняется. Например. если найденный размер шрифта составляет 10px, вы обновите его до 9.5px, который, вероятно, будет округлен до 10px браузером. В этом случае ничего не изменится, и функция будет работать вечно.

1 голос
/ 13 сентября 2011
var fontSize = $(this).css('fontSize');
fontSize = parseInt(fontSize, ...

Единица, которую вы получаете из font-size, не обязательно (а) пиксели и (б) не та же самая единица измерения, что и вы.

Не указано, какая единица измерения используется для возвратадлина, но во многих браузерах это в настоящее время точки.Так как точки меньше пикселей, целочисленная длина будет больше, поэтому вы можете без проблем продолжать *0.95 всегда.

Даже если бы это были пиксели, браузер мог бы округлить размер до ближайшегопикселей, что делает 95% размера того же размера, что и 100%, когда вы читаете его обратно.Или вы можете установить минимальный размер шрифта и больше не сможете его уменьшить.

Поэтому вместо того, чтобы читать текущий размер шрифта на каждом шаге, оставьте нужный размер в пикселях.переменная и уменьшать эту переменную каждый раз.Затем, если вы достигнете заранее определенной нижней границы для значения этой переменной, откажитесь.

0 голосов
/ 13 сентября 2011

Вы проверяете, являются ли clientHeight или clientWidth МЕНЬШЕ, чем scrollHeight или scrollWidth, и если это так, вы СОКРАЩАЕТЕ размер шрифта? Он никогда не сойдется при таких обстоятельствах. Вы хотите увеличить размер шрифта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...