【问题标题】:jQuery getScript not working, or I'm using it wrongjQuery getScript 不工作,或者我用错了
【发布时间】:2019-01-15 20:51:16
【问题描述】:

我无法让 jquery 的 $.getScript 工作。这是一个测试文件,demo.html:

<!DOCTYPE html>

<script src="/xyz/scripts/jquery-1.11.0.min.js"></script>
<script>
    function wow() { return 3; }
</script>

<h1>Demo</h1>

<script>
    console.log(wow);
    console.log(wow());
</script>

当我在 Windows 10 上的 Chrome 中浏览到此内容时,控制台中会显示以下内容:

Navigated to https://example.org/xyz/tools/demo.html
demo.html:11 ƒ wow() { return 3; }
demo.html:12 3

这是正确的。

然后我将函数定义移动到一个名为 myModule.js 的文件中:

function wow() { return 3; }

并创建demo2.html,即demo.html,其中函数定义被getScript调用替换:

<!DOCTYPE html>

<script src="/xyz/scripts/jquery-1.11.0.min.js"></script>
<script>
    $.getScript("myModule.js");
</script>

<h1>Demo</h1>

<script>
    console.log(wow);
    console.log(wow());
</script>

这次我明白了

Navigated to https://example.org/xyz/tools/demo2.html
demo2.html:11 Uncaught ReferenceError: wow is not defined
at demo2.html:11

我是否误解了 $.getScript 的用途或使用方式?

附录

为了响应将我的 console.log 调用包装在 $.ready 包装器中的建议,我尝试了以下方法:

<!DOCTYPE html>

<script src="/xyz/scripts/jquery-1.11.0.min.js"></script>
<script>
    $.getScript("myModule.js");
</script>

<h1>Demo</h1>

<script>
$.ready(function() {
    console.log(wow);
    console.log(wow());
});
</script>

这次我没有收到错误消息但是,wow 和 wow() 的值也没有写入控制台。

【问题讨论】:

  • 这是因为getScript 是异步的。你的console.logs 在getScript 完成之前执行。
  • 那有什么好处呢?不那么不屑一顾,我确实看到有一个回调函数的参数,可以执行页面中的其余代码,但是如果我使用 getScript 加载十几个模块或更多模块,每个模块都有自己的成功回调,在我开始运行这些模块要支持的代码之前,我需要其中的许多?
  • 为什么你觉得你需要使用getScript而不是&lt;script src=?
  • 对于“加载许多脚本并等待它们”的场景,请查看this question。
  • @freedomn-m 和 Kevin B:我正在尝试使用 getScript,以便脚本可以加载自己的依赖项,而不是让客户端 HTML 页面知道它们是什么。换句话说,就是封装,隐藏实现细节。

标签: jquery getscript


【解决方案1】:

$.getscript

https://api.jquery.com/jquery.getscript/

这是一个简写的Ajax函数,相当于:

$.ajax({
  url: url,
  dataType: "script",
  success: success
});

所以$.getscript 进行异步调用,所以您的代码相当于:

  • $.getscript - 开始加载脚本
  • console.log(wow) - 找不到它,因为脚本尚未加载
  • ...完成加载脚本

您可以在脚本加载后使用回调来执行代码:

$.getScript("myModule.js", function() {
    console.log(wow);
    console.log(wow());
});

【讨论】:

  • 我确实看到了那个回调参数,但它的实用性似乎仅限于我只加载一个外部脚本文件的情况,这是一种特殊情况。
  • 好的,从问题中不清楚。由于它是$.ajax 的快捷方式,它还返回一个 Promise,因此您可以确定它们何时全部加载。
  • 啊!我不得不查找承诺,然后我终于在stackoverflow.com/questions/11803215/… 找到了一个我没有搜索过的解决方案。我会给出有效的答案。谢谢!
【解决方案2】:

对getScript() 的调用是一个异步操作,它不会阻止执行其余的javascript。你有两个选择:

1) 将需要getScript() 内容的脚本包装在$(document).ready() 中,以延迟执行,直到所有内容都加载完毕。

2) 将回调作为第二个参数传递给getScript。如果getScript() 成功,就会执行这个回调。

【讨论】:

  • 我知道解决方案 2,但它仅适用于仅加载一个外部模块的特殊情况,因此我认为它是一个弱解决方案。但是现在我将对 console.log() 的调用包装在 $.ready(function() { ... });包装器,虽然现在我没有收到任何错误,但我也没有将任何内容写入控制台。我用 alert 替换了 console.log 仍然没有运气。
  • 我已将更新后的代码附加到我的原始帖子中以供参考。
【解决方案3】:

getScript is asynchronous method,所以你需要像这样在回调中访问它的变量:

$.getScript( "ajax/test.js", function( data, textStatus, jqxhr ) {
  console.log( data ); // Data returned
  console.log( textStatus ); // Success
  console.log( jqxhr.status ); // 200
  console.log( "Load was performed." );
});

你的 console.log(wow);在脚本完全加载之前执行。

【讨论】:

    【解决方案4】:

    感谢@freedomn-m,他在回复后续评论中提到了 Promises,我在How to include multiple js files using jQuery $.getScript() method 看到了之前讨论 $.when().done() 的帖子。这导致脚本有效:

    <!DOCTYPE html>
    
    <script src="/xyz/scripts/jquery-1.11.0.min.js"></script>
    <script>
        $.when(
            $.getScript("myModule.js")
        ).done(function() {
            console.log(wow);
            console.log(wow());
        });
    </script>
    
    <h1>Demo</h1>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多