简体   繁体   English

为什么JavaScript循环无限?

[英]Why is this while JavaScript loop infinite?

I hate doing this. 我讨厌这样做。 This is THE small piece to end a large project and my mind is fried... 这是结束一个大型项目的小部分,我的思绪是炒...

Here's the code. 这是代码。 It checks to see if an element is overflowing and resizes the font. 它检查元素是否溢出并调整字体大小。 It is supposed to resize it until it doesn't overflow. 它应该调整大小直到它不溢出。 The condition for the loop seems to be ignored and the browser freezes... I feel that I'm missing something crucial in how jQuery works here. 循环的条件似乎被忽略,浏览器冻结...我觉得我在这里缺少一些关键的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');          
    }

}

Thanks in advance. 提前致谢。

Change: 更改:

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

to: 至:

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

Here's a Working Demo . 这是一个工作演示 When the font size reached 10px, 10*.95 was 9.5 which the browser was rounding up to 10px. 当字体大小达到10px时,10 * .95为9.5,浏览器正在向上舍入到10px。 Thus infinite loop. 因此无限循环。

You need to step through your code in a debugger and actually check your condition values to make sure they are changing how you expect. 您需要在调试器中单步执行代码并实际检查条件值,以确保它们正在改变您的预期。 My guess is _elm.clientHieght and _elm.clientWidth aren't actually changing. 我猜是_elm.clientHieght_elm.clientWidth实际上并没有改变。

var fontSize = $(this).css('fontSize');
fontSize = parseInt(fontSize, ...

The unit you get from font-size is not necessarily (a) pixels, nor (b) the same unit as you put in. font-size获得的单位不一定是(a)像素,也不是(b)与放入的单位相同。

It's not specified what unit is used to return the length, but in many browsers it is currently points. 它没有指定用于返回长度的单位,但在许多浏览器中它当前是点。 Since points are smaller than pixels, the integer length will be longer, so you can quite easily keep on *0.95 ing it forever. 由于点小于像素,整数长度会更长,所以你可以很容易地永远保持*0.95

Even if it were pixels, the browser could round the size up to the nearest pixel, making 95%-size the same size as 100% when you read it back. 即使它是像素,浏览器也可以将大小调整到最近的像素,当你读回它时,95%-size的大小与100%相同。 Or you could hit the minimum-font-size setting and you wouldn't be able to reduce it any more. 或者你可以达到最小字体大小设置,你将无法再减少它。

So instead of reading the current font size back on each step, keep the pixel size you want in a variable and reduce that variable each time. 因此,不要在每一步上读取当前字体大小,而是在变量中保留所需的像素大小,并每次减少该变量。 Then if you reach a predetermined lower bound for the value of that variable, give up. 然后,如果达到该变量值的预定下限,则放弃。

You are probably running into an endless loop because the font size doesn't actually change. 你可能会遇到无限循环,因为字体大小实际上并没有改变。 Eg if the font size found is 10px you will update it to become 9.5px which is probably rounded back to 10px by the browser. 例如,如果找到的字体大小为10px,则会将其更新为9.5px,这可能会被浏览器舍入为10px。 In that case nothing changes and the function will keep running forever. 在这种情况下,没有任何变化,功能将永远运行。

You've got an unrelated problem when you do 当你这样做时,你会遇到一个无关的问题

$('div').fontBefitting()

This will make the text in the first div fit it's box, then make the font size of all the other divs the same as the first. 这将使第一个div中的文本适合它的框,然后使所有其他div的字体大小与第一个相同。 This does not sound like intended behaviour. 这听起来不像预期的行为。 You would hope that it would make each div resize its text and only its text to fit. 你希望它会使每个div调整其文本大小,只调整其文本。

You need to change your code to this: 您需要将代码更改为:

$.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');          
        }
    });
}

You're checking to see if the clientHeight or clientWidth are LESS than the scrollHeight or scrollWidth , and if they are you are REDUCING the font size? 您正在检查clientHeightclientWidth是否比scrollHeightscrollWidth ,如果它们是在减少字体大小? It will never converge under those circumstances. 在这种情况下它永远不会收敛。 You want to INCREASE the font size. 您想要增加字体大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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