【问题标题】:Loading/Appending JS script asynchronously异步加载/附加 JS 脚本
【发布时间】:2016-07-09 15:21:09
【问题描述】:

我正在使用 Laravel 来实现基于主页的模板。不同的页面有不同的JS脚本,所以我创建了一个模板来导入JS脚本:

<!-- jQuery 2.1.3 -->
<script src="{{ URL::asset('plugins/jQuery/jQuery-2.1.4.min.js') }}"></script>

<!-- Bootstrap 3.3.2 JS -->
<script src="{{ URL::asset('js/bootstrap.min.js') }}" type="text/javascript"></script>

<!-- Ajax Page Loading -->
<script>
    function ajax(url) {
        $('.main-content').fadeOut(100); //hide the page
        $('.spinner').show(); // show a spinner
        $.ajax(url, {
            async: true,
            success: function(data) {
                $('#header').html(data[0]); //append received header to header
                $('#content').hide().html(data[1]).fadeIn(500); //show the page again
                $('body').append(data[2]); //append scripts to body
                $('.spinner').hide();
            },
        });
    }
</script>

@yield('extra-scripts') <--- /* HERE is where the scripts will be */

我还使用 AJAX 仅加载内容而不刷新页面。 ajax 函数将用于将任何 url 加载到 div“内容”中。但是,我还需要加载脚本以使页面正常工作。

数据是一个包含三个字段的数组:

  • 0 是标题 html
  • 1 是内容 html
  • 2 是动态添加的脚本

问题是每当我加载页面时,我都会收到此错误:

主线程上的同步 XMLHttpRequest 已被弃用,因为 其对最终用户体验的不利影响。如需更多帮助, 检查https://xhr.spec.whatwg.org/

我不希望脚本加载影响用户体验。必须是异步的。

我已经尝试过的:

  • jQuery.getScript

    • 此解决方案需要我将所有脚本移动到单独的 JS 文件中。这可能会解决它,但我宁愿将它们全部保留在相应的页面中。
  • AjaxPreFilter

    • $.ajaxPrefilter with options.async = true 使脚本在页面之后加载,从而使某些属性未定义且无法正常工作。

【问题讨论】:

    标签: javascript jquery ajax laravel


    【解决方案1】:

    只要您将脚本注入文档正文,此警告就会继续发生。

    我建议使用$.getScript,因为这将正确加载脚本。我真的不明白为什么你希望所有的 javascript 从一开始就在同一个页面中。 无论如何,您可能都希望将它们放在单独的文件中,以便于以后的维护和关注点分离。

    你也可以使用 vanilla javascript:

    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.setAttribute('src','your_script.js');
    head.appendChild(script);
    

    如果您坚持这样做,请尝试将其直接注入文档的 head 而不是 body,看看是否有帮助。

    在更一般的情况下 - 似乎您正在构建单页应用程序 (SPA) - 您是否研究过像 AngularBackbone 等 JS 框架?他们将为您处理所有繁重的工作,并将帮助您更好地扩展您的应用程序。这听起来有点像试图重新发明轮子,作为一个教育过程可能是一件好事,但从长远来看可能不是一个好主意。

    希望这会有所帮助。

    【讨论】:

    • 谢谢亚尼。这实际上是一个教育过程,因为我还不熟悉 Angular 或 Backbone。我可能最终会分离 JS。
    • 我将不得不使用 $.getScript 作为修复和单独的文件。
    • 我可以借此机会问一下加载未使用的附加 JS 是否会影响性能?例如,使用 AJAX 加载脚本进行导航,其中有从上一页加载但未使用的脚本,这很糟糕吗?
    • 在构建 SPA 时这是一种非常常见的做法,所以我会说,除非你有几十个/几百个脚本,否则你应该很好,我不会太担心它。唯一的事情是确保在不需要时不要运行繁重的后台进程(例如 ajax 调用、计时器操作、计算)。因此,如果您的脚本占用大量资源,您可能希望确保它们在不需要时停止运行,具体取决于您所在的页面。
    【解决方案2】:

    您现在所做的并不是最佳做法。如果你想使用 Ajax 加载页面并动态调用 Js 文件,我建议你使用pjax

    看这里:https://github.com/defunkt/jquery-pjax

    由于您使用的是laravel,因此您可以在pjax 中轻松实现它。

    这里有教程:https://laracasts.com/lessons/faster-page-loads-with-pjax

    【讨论】:

    • 问题是我返回了一个包含三个字段的数组数据,我不确定你如何告诉 PJAX 将每个字段放在哪里。
    猜你喜欢
    • 2011-12-04
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    • 2019-06-29
    相关资源
    最近更新 更多