【问题标题】:run js function after all scripts on page are fully loaded在页面上的所有脚本完全加载后运行 js 函数
【发布时间】:2019-07-29 12:01:15
【问题描述】:

当我的页面完全加载时,我正在尝试运行一个简单的 javascript 函数。比如这个函数:

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

我的页面有一个从外部 URL 检索的长时间加载(秒)脚本,该脚本在 html 正文中呈现主要内容。

我正在使用 Bootstrap,其中我的 base.html 的正文部分是:

<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>

内容块是通过外部html文件加载的,即:

{% 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 %}

'my-id' 元素中,myapp 通过长时间加载的 js 脚本呈现,该脚本在完成后呈现页面的所有内容。 myapp 的外部 URL 路由由使用 Flask 的 python 脚本检索和定义。

我试过window.onload = changeSize;&lt;body onload="changeSize();"&gt;,我检查了document.readyState所有阶段的时间。

这些都在html完全加载时触发我的js函数,但在myapp的外部脚本完成之前。如何检测所有元素和脚本何时完全加载完毕?

【问题讨论】:

  • 脚本标签在哪里?您的脚本应该在外部源之后执行。
  • 长加载脚本的html中没有特定的脚本标签。它只能通过内容块中的myapp 调用。我可以使用 DevTools Network 选项卡将脚本识别为以 autoload.js?... 开头的脚本。在所有其他元素都完成后,它会继续加载。
  • 你能改变“myapp”或它加载的脚本吗?添加回调功能以通知您的页面已完成。一个例子是 google maps api developers.google.com/maps/documentation/javascript/tutorial &lt;script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&amp;callback=initMap"&gt;&lt;/script&gt; 其中initMap 是您页面上的一个函数。

标签: javascript jquery html css


【解决方案1】:

我最终找到了使用延迟方法的解决方案(改编自 this SO 答案)。

将以下内容放入custom.js 文件中:

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

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

然后将custom.js 加载到base.html 中:

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

这会成功等待长加载脚本和相关内容完全渲染,然后执行changeSize()函数。

【讨论】:

  • 如果您只是想将函数的运行推到event loop 的后面,您可以使用0setTimeout(function(){ ... },0) 的持续时间来执行此操作。无需添加额外的 200 毫秒。
【解决方案2】:

我不确定外部脚本是如何加载的。如果它们使用特殊库加载,则需要等待回调,然后调用您的 App 初始化。

不过你可以看看DOMContentLoaded 事件。如果我是对的,它也会有所帮助。

document.addEventListener("DOMContentLoaded", function(event) {
  console.log("DOM fully loaded and parsed");
});

【讨论】:

  • 在长时间运行的脚本完成之前,DOM 已完全加载和解析。
猜你喜欢
  • 2022-11-26
  • 2015-09-28
  • 2017-06-14
  • 2017-09-02
  • 1970-01-01
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
相关资源
最近更新 更多