Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

run js function after all scripts on page are fully loaded

I am trying to run a simple javascript function when my page is completely loaded. For example, this function:

<script type="text/javascript">
function changeSize() {
  var el = document.getElementById("my-id");
  el.style.height = "500px";
  };
</script>

My page has a long-loading (seconds) script retrieved from an external URL that renders the main content in the html body.

I am using Bootstrap where the body section of my base.html is:

<body>

  <div class="container-fluid">
    {% block header %}{% endblock %}

    {% block content %}{% endblock %}

    {% block footer %}{% endblock %}

  </div>

  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
</body>

The content block is loaded via an external html file, which is:

{% extends 'base.html' %}

{% block header %}
{% include 'header.html' %}
{% endblock %}

{% block content %}
  <div class="my-class" id="my-id">
        {{ myapp | safe }}
  </div>
{% endblock %}

{% block footer %}
{% include 'footer.html' %}
{% endblock %}

In the 'my-id' element, myapp is rendered via the long-loading js script that, when finished, renders all the content of the page. The external URL route for myapp is retrieved and defined by a python script using Flask.

I have tried window.onload = changeSize;, <body onload="changeSize();">, and I have checked the timing of all stages of document.readyState.

These all trigger my js function when the html is fully loaded, but before the external script for myapp is complete. How do I detect when all elements and scripts are completely done loading?

like image 624
PJW Avatar asked Apr 22 '26 11:04

PJW


1 Answers

I ended up finding a solution using a delay method (adapted from this SO answer).

Put the following in a custom.js file:

function delay() {
    setTimeout(function() {
        changeSize();
    }, 200);
}

if (document.readyState == 'complete') {
    delay();
} else {
    document.onreadystatechange = function () {
        if (document.readyState === "complete") {
            delay();
        }
    }
}

Then load the custom.js in base.html with:

<script type="text/javascript" src="{{ url_for('static', filename='custom.js') }}"></script>

This successfully waits until the long-loading script and related content is fully rendered, then executes the changeSize() function.

like image 91
PJW Avatar answered Apr 24 '26 01:04

PJW