【问题标题】:How to dynamically insert a <script> tag via jQuery after page load?如何在页面加载后通过 jQuery 动态插入 <script> 标签?
【发布时间】:2011-04-20 22:46:05
【问题描述】:

我在让它工作时遇到问题。我首先尝试将我的脚本标签设置为字符串,然后在页面加载后使用 jquery replaceWith() 将它们添加到文档中:

var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);

但是我在那个 var 上遇到了字符串文字错误。然后我尝试对字符串进行编码,例如:

var a = '&left;script type="text/javascript"&gt;some script here&lt;\/script&gt;';

但将其发送到replaceWith() 只会将该字符串输出到浏览器。

有人可以告诉我你将如何在页面加载后动态添加&lt;script&gt; 标记到浏览器中,最好是通过 jQuery?

【问题讨论】:

  • 您能解释一下通过在文档中添加&lt;script&gt; 标签来实现的目的吗?
  • @Rocket 的答案是最好的,但如果您确实想从字符串中添加内联脚本,那么您只需将其传递给 eval() 函数即可。但是使用eval() 几乎总是表明有更好的方法来做你想做的事情。
  • 我们正在尝试将第 3 方广告的加载推迟到页面末尾。这些广告是通过 2 个脚本标签调用的,所以我想在页面加载后运行一个函数,将它们动态地抛出。
  • 并非所有第三方脚本都设计为可延迟的。如果脚本使用document.write 并且您在页面加载后调用它,它将破坏页面。
  • 为什么不在&lt;iframe&gt; 元素中导入这些标签?您可以推迟设置&lt;iframe&gt; URL,直到您准备好。

标签: javascript jquery script-tag javascript-injection


【解决方案1】:

您可以将脚本放入单独的文件中,然后使用$.getScript 加载并运行它。

例子:

$.getScript("test.js", function(){
    alert("Running test.js");
});

【讨论】:

  • 谢谢,但这会将其粘贴到 DOM 中吗?我意识到我遗漏了重要的信息,即我需要将脚本标签插入到 DOM 中,进行评估,此时它会返回第 3 方广告代码以显示在我们网站的特定
    中。
  • $.getScript 将通过 AJAX 加载一个 .js 文件并执行它。该脚本无需位于 DOM 中即可访问页面上的 div。
  • 但是对于$.getScript(),脚本需要在同一个域中,或者远程域和浏览器都需要支持CORS
  • @hippietrail 这实际上不是真的。它只是插入一个普通的 ol' 脚本标签,不需要 CORS 或同域。例如,我用它来缩短加载谷歌分析的代码,它加载得很好。实际上,在幕后运行的实际 jquery 代码与 GA sn-p 非常相似。
  • 由于@hippietrail 的回答将以其 4 次赞成票吸引最多的关注,因此应该明确指出他是不正确的。正如 jQuery 文档在其 $.ajax 中强调的那样:“脚本和 JSONP 请求不受同源策略限制。” source。换句话说,$.getScript 可以从其他域中提取 .js 文件,而不仅仅是您自己的域
【解决方案2】:

尝试以下方法:

<script type="text/javascript">
// Use any event to append the code
$(document).ready(function() 
{
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.src = "http://scriptlocation/das.js";
    // Use any selector
    $("head").append(s);
});

http://api.jquery.com/append

【讨论】:

  • +1 用于使用append 添加脚本。附加甚至会导致内联脚本立即评估(正是我需要的)。谢谢
  • 我最终在 IE8/9 中使用这种方法遇到了很多问题。即堆栈溢出错误。我使用下面的 $.getScript() 方法来全面完成这项工作。
  • 是的@jcoffland 这是写于 2010 年 10 月的 :)
  • 如果包含此代码的页面使用 AJAX 加载,浏览器将抛出“主线程上的同步 XMLHttpRequest 已弃用,因为它对最终用户的体验有不利影响”警告。
  • @Reddy 很棒的评论。这是在 2010 年 10 月发布的,我确定现在这种方法不再是有效/推荐的方法,用户必须自行决定。
【解决方案3】:

这是使用现代(2014)JQuery 的正确方法:

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .appendTo('head');
})

或者如果你真的想替换一个 div 你可以这样做:

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .replaceAll('#someelement');
});

【讨论】:

  • 或者 .text('some script here') 你可以写 .attr('src', 'path_to_your_js_file')
  • 非常感谢@jcoffland 这个语法对我很有用。
【解决方案4】:

更简单的方法是:

$('head').append('<script type="text/javascript" src="your.js"></script>');

你也可以使用这个表单来加载css。

【讨论】:

  • 您可能希望避免将字符串 &lt;/script&gt; 放入源代码中,因为它可能会导致解析问题:stackoverflow.com/questions/236073/…
  • 转义最后一个 / 对我有用:$('head').append('&lt;script src="your.js"&gt;&lt;\/script&gt;');
【解决方案5】:

这个答案在技术上类似于或等于 jcoffland 的答案。 我刚刚添加了一个查询来检测脚本是否已经存在。 我需要这个,因为我在一个有几个模块的 Intranet 网站上工作,其中一些模块是共享脚本或自带的,但这些脚本不需要每次都重新加载。我在生产环境中使用这个 sn-p 已经一年多了,它就像一个魅力。对自己的评论:是的,我知道,询问函数是否存在会更正确...... :-)

if (!$('head > script[src="js/jquery.searchable.min.js"]').length) {
    $('head').append($('<script />').attr('src','js/jquery.searchable.min.js'));
}

【讨论】:

  • 顺便说一句。我对样式表做同样的事情: if (!$('head > link[href="widgets/css/widgets.css"]').length) {$('head').append($('').attr('rel','stylesheet').attr('href','widgets/css/widgets.css'));}
【解决方案6】:

这里有一个更清晰的方法——不需要 jQuery——它添加一个脚本作为 &lt;body&gt; 的最后一个子节点:

document.body.innerHTML +='<script src="mycdn.js"><\/script>'

但如果你想添加加载脚本使用Rocket Hazmat's method

【讨论】:

    【解决方案7】:

    例子:

    var a = '<script type="text/javascript">some script here</script>';
    $('#someelement').replaceWith(a);
    

    它应该工作。我尝试过这个;同样的结果。但是当我使用这个时:

    var length = 1;
    var html = "";
    for (var i = 0; i < length; i++) {
        html += '<div id="codeSnippet"></div>';
        html += '<script type="text/javascript">';
        html += 'your script here';
        html += '</script>';
    }
    $('#someElement').replaceWith(a);
    

    这对我有用。

    编辑:我忘记了#someelement(顺便说一句,由于约定,我可能想使用#someElement

    这里最重要的是 +=,所以 html 被添加而不是被替换。

    如果不起作用,请发表评论。我想帮你!

    【讨论】:

      【解决方案8】:

      有一种解决方法听起来更像是一种 hack,我同意这不是最优雅的方法,但 100% 有效:

      说你的 AJAX 响应类似于

      <b>some html</b>
      <script>alert("and some javscript")
      

      请注意,我故意跳过了结束标记。然后在加载上述内容的脚本中,执行以下操作:

      $.ajax({
          url: "path/to/return/the-above-js+html.php",
          success: function(newhtml){
              newhtml += "<";
              newhtml += "/script>";
              $("head").append(newhtml);
          }
      });
      

      只是不要问我为什么 :-) 这是我在绝望的几乎随机试验和失败后得出的结果之一。

      我对它的工作原理没有完整的建议,但有趣的是,如果你在一行中附加结束标记,它将无法工作。

      在这样的时候,我觉得我已经成功地被零除了。

      【讨论】:

      • 如果结束脚本标签是一体的,它将不起作用,因为浏览器将其视为脚本的结束标签而不是字符串文字。
      • &lt;\/script&gt; 仍然有效
      • 我认为@TrueBlueAussie 的观点是为了回应您的评论“别问我为什么……但有趣的是,如果您在一行中附加结束标签,它将不起作用。”他解释了原因,以便任何想要比“我不知道”更好的答案的读者更容易找到它。另见:javascript.crockford.com/script.html
      • @Sathvik 是正确的,根据该链接。 Ash 的评论似乎是对已被删除的评论的回复。
      【解决方案9】:

      如果您尝试运行一些动态生成的 JavaScript,使用eval 会稍微好一些。但是,JavaScript 是一种动态语言,您真的不需要它。

      如果脚本是静态的,那么 Rocket 的 getScript-suggestion 就是要走的路。

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签