admin管理员组文章数量:1403182
So I am working on a function that resizes font size so the text fills as much of the container as possible across multiple lines without overflow. For instance,
I want the text to cover as much of the 1200px of area within the div without overflowing as possible. This script does this on resize but not on load.
$(document).ready(textFill);
$(window).resize(textFill);
function textFill() {
$(".textFill").each(function() {
var
$text = $(this),
$parent = $text.parent();
var
textW = $text.width(),
textH = $text.height(),
parentW = $parent.width(),
parentH = $parent.height(),
ratio = (parentW + parentH) / (textW + textH);
var
originalSize = parseFloat($text.css('font-size')),
newSize = originalSize * (.9 * ratio);
$text.css("font-size", newSize);
});
}
#container {
width: 400px;
height: 300px;
border: 1px solid blue;
}
.textFill {
display: inline;
}
<script src=".1.1/jquery.min.js"></script>
<div id="container">
<h1 class="textFill">Make this fit as large as possible.</h1>
</div>
So I am working on a function that resizes font size so the text fills as much of the container as possible across multiple lines without overflow. For instance,
I want the text to cover as much of the 1200px of area within the div without overflowing as possible. This script does this on resize but not on load.
$(document).ready(textFill);
$(window).resize(textFill);
function textFill() {
$(".textFill").each(function() {
var
$text = $(this),
$parent = $text.parent();
var
textW = $text.width(),
textH = $text.height(),
parentW = $parent.width(),
parentH = $parent.height(),
ratio = (parentW + parentH) / (textW + textH);
var
originalSize = parseFloat($text.css('font-size')),
newSize = originalSize * (.9 * ratio);
$text.css("font-size", newSize);
});
}
#container {
width: 400px;
height: 300px;
border: 1px solid blue;
}
.textFill {
display: inline;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<h1 class="textFill">Make this fit as large as possible.</h1>
</div>
When I resize, it fills the container, but onload it does not seem to fire.
EDIT: The function does fire upon document ready, however it does not account for the fully loaded dimensions of the parent. Instead it measures the parents height as the height of the text.
Additionally, I am not sure if the resize event is the one I'd like to use, since it should only adjust font size, maybe I should only execute on change of parent dimensions, is that possible?
Here is the fiddle..
Share Improve this question edited Jun 9, 2015 at 17:58 Ruslan López 4,4772 gold badges30 silver badges40 bronze badges asked May 31, 2015 at 23:46 ChrisChris 7674 gold badges8 silver badges22 bronze badges 8- For some reason your function works on the second time it gets called. e.g. if you call your function twice in document.ready it will work. Im working on why it acts like that – A Web-Developer Commented May 31, 2015 at 23:51
- Also works with just a little delay added. Does not need to run twice to work. It seems as if the script is executing to quickly: jsfiddle/nz7h2858/46 – HaukurHaf Commented May 31, 2015 at 23:53
- 3 If you run it without calling the function the text is even smaller. Your function makes it a bit bigger with the first call, then bigger still on the 2nd, around the third call or so it reaches roughly an equilibrium. It has nothing to do with when or how it's called, it's the logic of the function, it takes a few calls to even out, which makes sense because it's based on the "original size" which changes with each call.. – James Montagne Commented May 31, 2015 at 23:55
- 3 Following up on @JamesMontagne ment, you can watch the variables change by repeatedly clicking the button here: jsfiddle/2Lojj87t/1 – Rick Hitchcock Commented Jun 1, 2015 at 0:14
- @JamesMontagne the button fiddle illustrates how it takes multiple firings to reach "equilibrium", I guess my question is why isn't the correct value – Chris Commented Jun 1, 2015 at 6:11
8 Answers
Reset to default 3 +25Your function in the fiddle actually runs the first time, which you can see if you specify a font-size for .textFill
.. say 10px. You'll see that it does scale up to the max width even on the first call.
The main problem is that you re-read the font-size (originalSize
) on every resize event (every time the function is called) and then calculate again with the new size. Only after the max is reached you have the result you expected.
The problem however has been dealt with before and because I don't really deserve any credit for the answer, I'll just link to it here. Make sure to check out the gist that is included in that answer!
It is because of
textH = $text.height()
which returns a different value every time you resize and the text keeps growing in height making the value of newSize
bigger. This is why if you call the function more times like this:
textFill();
textFill();
textFill();
textFill();
textFill();
it will make the text bigger. The solution is to control the height in css.
The "textFill" function did fire on document.ready event. You can simply prove this by adding some CSS style to make it visible, e.g
$text.css({"font-size", newSize, "color": "red"});
I did confuse about the way the "ratio" was calculated. If you just tried to make the "h1" font big enough to fill the outer container, the only thing to consider is to keep enough vertical space to avoid the "h1" overlapping out of the "div" box. So that the ratio could be something like:
var ratio = parentH / textH;
Also there's a magic number of "0.9" in the "newSize" calculation. I have to say I did not know how it goes out :).
Just some thoughts and a plan to do this:
First off, you are fixing the width of the container. Therefore, re-sizing the window does nothing. If your container could change size, you may want to re-size, and there is plenty of examples on how to do that already available. For now, though, you can remove the resize() line. It just adds confusion.
Second, since you are word wrapping, the calculation isn't easy. One word could determine the font size (so it doesn't bee bigger than the container width). You could probably figure this out by setting the font size to the container height and finding out the longest word, than calculating a max font size from that. The other possibility is that the font size will be limited to however many lines the text wraps. You possibly could e up with an initial guess by looking at line spacing and how wide the text is at 1px font size, but you ultimately are going to have to try a few font sizes to see how many lines the text actually wraps into. For that reason, I suggest writing a loop.
You don't want the trials visible, so you will have to learn to make it invisible or move it off screen in such a way that the size is still calculated by the browser but nothing changes in the document or the scrollbars.
Third, I would start with a minimum and maximum guess of font size (1 pixel and the height of the container), then I would pick a value in the middle, try it, find out if it fits in the container (width and height) or not, and if it does, make it the min value, and if it does not, make it the max (if it turns out to be equal, you are done). I would keep doing this until the max and min are within a small value of each other (say, 1%), then I would choose the min and be done with it. I would also put a maximum number of guesses on it (say, 25), and if I didn't get an answer within those, I would also choose the min and be done with it (browsers may not always behave consistently, so this is a "just in case" sort of situation).
Code:
textFill();
function textFill() {
$(".textFill").each(function () {
var
$text = $(this),
$parent = $text.parent();
var
parentW = $parent.width(),
parentH = $parent.height();
var minFontSize = 1;
var maxFontSize = parentH;
for (loop = 0; loop < 25; ++loop) {
var newFontSize = (minFontSize + maxFontSize) / 2;
$text.css("font-size", newFontSize);
var textW = $text.width();
var textH = $text.height();
if (textW > parentW || textH > parentH) {
maxFontSize = newFontSize;
} else {
minFontSize = newFontSize;
}
if ((maxFontSize - minFontSize) * 100 < minFontSize) break;
}
$text.css("font-size", minFontSize);
});
}
fiddle: http://jsfiddle/tncmrya6/
you are calling textFill() function on window resize event only.
if you want to call this function on load you can implement as below.
$(window).load(function() {
textFill()
});
To call your function on both events load and resize events. you can use below snippet.
$(window).on("load resize",function(){
textFill()
})
If I understood well, you're looking to fit text to div by width and height. Maybe you should just remove .9 from calculations. Check this to see if this is what you searched for.
$(document).ready(textFill);
$(window).resize(textFill);
function textFill() {
$(".textFill").each(function() {
var
$text = $(this),
$parent = $text.parent();
var
textW = $text.width(),
textH = $text.height(),
parentW = $parent.width(),
parentH = $parent.height(),
ratio = (parentW + parentH) / (textW + textH);
console.log(ratio);
var
originalSize = parseFloat($text.css('font-size')),
newSize = originalSize * ratio;//HERE'S BIG CHANGE :)
$text.css("font-size", newSize);
});
}
use
window.onload = function() {
textFill();
}
you don't really need specifically to use jQuery to handle stuff that window handles natively.
If you want your script to execute onload you could do this. Works every time.
<script type='text/javascript'>
window.addEventListener('DOMContentLoaded', function () {
textFill(); //Call your function here
});
</script>
本文标签: javascriptFunction doesn39t fire on loadbut works on resizeStack Overflow
版权声明:本文标题:javascript - Function doesn't fire on load, but works on resize - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744354065a2602216.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论