页面加载后如何通过jQuery动态插入<script>标签?


101

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

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

但是我在那个变量上有字符串文字错误。然后,我尝试将字符串编码为:

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

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

有人可以让我知道您将如何<script>在页面加载后(最好是通过jQuery)向浏览器动态添加标签?


您能否解释一下通过<script>在文档中添加标签来达到的目的?
尖尖的

@Rocket的答案是最好的,但是如果您确实想从字符串中添加内联脚本,则只需将其传递给eval()函数即可。但是eval()几乎总是使用暗示着有一种更好的方法来做您想做的事情。
尼克

我们正在尝试将第三方广告的加载推迟到页面末尾。这些广告是通过2个脚本标签调用的,所以我想在页面加载后运行一个函数,以动态地将它们投入。
道格

2
并非所有第三方脚本都被设计为可延迟的。如果脚本使用document.write并且在页面加载后调用它,它将破坏该页面。
bobince 2010年

1
为什么不将这些标签导入<iframe>元素?您可以推迟设置<iframe>URL,直到准备就绪为止。
尖尖的

Answers:


103

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

例:

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

2
谢谢,但是那会坚持到DOM吗?我意识到我遗漏了重要信息,我需要将script标签插入DOM中进行评估,这时它将返回第三方广告代码,以在特定<div>中显示在我们的网站上。
道格2010年

1
$.getScript只会通过AJAX加载.js文件并执行。该脚本不需要位于DOM中就可以访问页面上的div。
火箭Hazmat

6
但是,$.getScript()脚本需要位于同一域上,或者远程域和浏览器都需要支持CORS
hippietrail 2012年

14
@hippietrail事实并非如此。它只插入一个普通的ol'script标签,不需要CORS或相同域。例如,我用它来缩短用于加载Google Analytics(分析)的代码,并且加载也很好。实际上,在后台运行的实际jquery代码与GA代码段非常相似。
克里斯·莫斯基尼

39
由于@hippietrail的答案将因其4次投票而引起最多的关注,因此应明确指出他是错误的。正如jQuery文档在其$.ajax注释中强调的那样:“脚本和JSONP请求不受相同的原始策略限制。” 来源。换句话说,$.getScript可以从其他域中提取.js文件,而不仅仅是您自己的.js文件
EleventyOne 2013年

64

请尝试以下操作:

<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


4
+1用于append添加脚本。Append会使内联脚本立即进行评估(正是我所需要的)。谢谢
Gone Coding

1
通过这种方法,我最终在IE8 / 9中遇到很多问题。即堆栈溢出错误。我采用下面的$ .getScript()方法来全面完成这项工作。
zmonteca 2013年

1
是@jcoffland这是在2010年10月编写的:)
Bassem

如果包含此代码的页面是使用AJAX加载的,则浏览器将引发“不赞成在主线程上使用XMLHttpRequest,因为它对最终用户的体验有不利影响”。
Rajshekar Reddy

@Reddy很棒的评论。该版本发布于2010年10月,我确定目前该方法不再是有效/推荐的方法,用户必须自行决定是否继续。
巴森2016年

34

这是使用现代(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');
});

3
或者,您可以编写.attr('src','path_to_your_js_file')
Serhii Maksymchuk,2017年

11

一个更简单的方法是:

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

您也可以使用此表单加载CSS。


6
你可能想避免将字符串</script>中源,虽然,因为它可能会导致解析的问题:stackoverflow.com/questions/236073/...
IX3

2
逃脱最后一个/对我$('head').append('<script src="your.js"><\/script>');
有用

5

从技术上讲,此答案与jcoffland的答案相似或相等。我只是添加了一个查询来检测脚本是否已经存在。我之所以需要它,是因为我在一个Intranet网站上工作,其中包含两个模块,其中一些模块共享脚本或自带脚本,但是这些脚本不需要每次都重新加载。我在生产环境中使用该代码段已有一年多了,它的工作原理像个烟斗。对自己说:是的,我知道,问一个函数是否存在会更正确... :-)

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($('<link / >')。attr('rel','stylesheet')。attr('href','widgets / css / widgets.css'));}
ddlab

2

有一种解决方法听起来更像是一种破解,我同意这不是最优雅的方法,但可以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);
    }
});

只是不要问我为什么:-)这是我经过绝望的几乎随机试验而失败的结果之一。

我没有关于它如何工作的完整建议,但有趣的是,如果将结束标记添加到一行中,它将不起作用。

在这样的时代,我觉得自己已经成功地除以零。


3
如果关闭脚本标记是一个整体,它将不起作用,因为浏览器将其视为脚本的关闭标记,而不是字符串文字。
Gone Coding

1
<\/script>虽然会有效
SP

我认为@TrueBlueAussie的观点是对您的评论的回应:“只是不要问我为什么……但有趣的是,如果将结束标记添加到一行中,它将不起作用。” 他解释了为什么这样做,以便希望得到比“我不知道”更好的答案的任何读者都可以更轻松地找到它。另请参见:javascript.crockford.com/script.html
iX3 2015年

1
根据该链接,@ Sathvik是正确的。Ash的评论似乎是对被删除的回复。
Arlen Beiler

2

例:

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被添加而不是被替换。

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



-4

如果您尝试运行一些动态生成的JavaScript,那么使用会更好eval。但是,JavaScript是一种动态语言,因此您实际上不需要它。

如果脚本是静态的,那么Rocket的getScript-uggesttion是可行的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.