Function does not fire on load, but does work when resized

So I'm working on a function that changes the font size so that the text fills as much of the container on multiple lines as possible without overflow. For example,

I want the text to cover as much of the 1200px area in the div as possible without overflow. This script does it on resize , but not on upload.

$(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.com/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>
      

Run codeHide result


When I resize it fills the container, but it won't start.

EDIT: The function fires when the document is ready, but does not take into account the fully loaded dimensions of the parent. Instead, it measures the height of the parents as the height of the text.

Also, I'm not sure if the resize event is the one I would like to use as it should only adjust the font size, maybe I should only do when changing parent dimensions, is it possible?

Here is a fiddle ..

+3


source to share


8 answers


Your function in the script is executed for the first time, and you can see if you specify the font size for .textFill

.. let's say 10px. You will see it scaled to its maximum width even on the first call.

The main problem is that you re-read the font size ( originalSize

) in every resize event (every time you call the function) and then calculate the new size again. Only after reaching the maximum will you get the expected result.



The problem, however, was covered earlier, and because I really don't deserve any credit for the answer, I just link here . Don't forget to check out the gist that is included in this answer!

+3


source


This is due

textH = $text.height()

      

which returns a different value each time it is resized and the text keeps growing, making the value newSize

larger. This is why if you call the function for more time, for example:



     textFill();
     textFill();
     textFill();
     textFill();
     textFill();

      

this will make the text bigger. The solution is to control the height in css.

+1


source


The textFill function has fired the document.ready event. You can just prove it by adding some CSS style to make it visible, like

$text.css({"font-size", newSize, "color": "red"});

      

I am confused about how the "coefficient" was calculated. If you're just trying 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 overlapping the "h1" from the "div" box. So that the ratio could be something like this:

var ratio = parentH / textH;

      

Also in the "newSize" layout there is a magic number "0.9". I have to say I didn't know how it was going :).

+1


source


Just some thoughts and a plan to do this:

First, you fix the width of the container. Therefore, overriding the window does nothing. If your container can be resized, you might want to resize, and there are many examples of how to make this available already. For now, you can remove the resize () line. It just adds to the confusion.

Secondly, since you are word wrap, the calculation is not easy. One word can determine the size of the font (so it won't grow larger than the width of the container). You could probably figure this out by setting the font size to the height of the container and finding out the longest word than calculating the maximum font size. Another possibility is that the font size will be limited only by the number of lines that wraps around the text. You could probably come up with an initial guess by looking at the line spacing and width of text with a font size of 1px, but you end up having to try multiple font sizes to see how many lines the text actually inserts. For this reason, I suggest writing a loop.

You don't want the tests to be visible, so you'll have to learn how to make it invisible or move it off the screen so that the size is still calculated by the browser, but nothing changes in the document or scrollbars.

Third, I would start with a minimum and maximum guess about the font size (1px and the height of the container), then I would choose the value in the middle, try it, find out if it fits in the container (width and height) or not, and if it is so, make it the minimum value, and if not, make it max (if it turns out to be equal, you're done). I would keep doing this until max and min are in a small value of each other (say 1%), then I would select min and do with it. I would also put the maximum number of guesses on it (say 25), and if I didn't get the answer in them, I would also select min and do with it (browsers may not always behave consistently, so this is "just case "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.net/tncmrya6/

+1


source


you only call textFill () function on window resize event.

if you want to call this function on load you can implement as below.

$(window).load(function() {

  textFill()

});

      

To call the function on both events, load and resize the events. you can use below snippet.

$(window).on("load resize",function(){

  textFill()

})

      

0


source


If I understood well, you want the text to fit the div in width and height. Maybe you should just remove .9 from calculations. Check out this one to see what exactly you were looking 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 BIG CHANGE :)

$text.css("font-size", newSize);

});
}

      

0


source


use

window.onload = function() {
    textFill();
}

      

you don't need to specifically use jQuery to handle files that are processed natively.

0


source


If you want your script to do onload you could do that. Works every time.

<script type='text/javascript'>
window.addEventListener('DOMContentLoaded', function () { 
    textFill(); //Call your function here
});

</script>

      

0


source







All Articles