追加脚本使用JavaScript来领导 - 怪异的行为 [英] Appending scripts to head using javascript - weird behavior

查看:198
本文介绍了追加脚本使用JavaScript来领导 - 怪异的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解决的问题是一个广告加载脚本,加载广告code。与JSONP,并将其插入到DOM中。

现在有时广告code将包括JavaScript代码,我想它只是将它们移动到头部的问题,他们将运行。在理论工作正常,但是当我做了一个脚本来移动脚本标签我遇到了一些怪异的行为。

头部

所以我写了这个code测试只是脚本移动部件,消除了code的剩余部分作为一个误差源。

我得到相同的结果,如果我有它的动作他们中的一个在div只是两个剧本,如果我有3个脚本它的动作,其中2。在粘贴在它下面的code移动脚本1和3,跳过远程JavaScript基准和最后一个脚本标签。

将是有趣的,至少知道为什么会这样,如果可以解决的。

编辑:澄清一件事,如果我把遥控器jQuery脚本第一和简单的脚本标记的二分之一,将远程脚本标签举至头顶罚款和跳过第二个脚本标签

 <!DOCTYPE HTML>
< HTML和GT;
< HEAD>
<脚本类型=文/ JavaScript的>
//获取DIV ID
功能测试(){
变种TD =的document.getElementById('testId');
VAR脚本= td.getElementsByTagName(脚本);
的console.log(没有脚本转移到头:+ scripts.length);
对于(i = 0; I< scripts.length;我++){
    VAR curScript =脚本[I]
    document.head.appendChild(curScript);
}
}
< / SCRIPT>
< /头>
<身体的onload =测试();>
< D​​IV ID =testId>
    <脚本类型=文/ JavaScript的> VAR firstScript = 1;< / SCRIPT>
    <脚本类型=文/ JavaScript的SRC =htt​​p://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js>< / SCRIPT>
    <脚本类型=文/ JavaScript的> VAR secondScript = 1;< / SCRIPT>
    <脚本类型=文/ JavaScript的> VAR thirdScript = 1;< / SCRIPT>
< / DIV>
< /身体GT;
< / HTML>


解决方案

您正在劳动的一个错误的假设下:没关系任何剧本元素是否在在,它们就不管运行。移动他们,他们已经被添加到DOM后充其量毫无意义,在最坏的情况可能会导致不幸的副作用,如果脚本重新运行在移动时(但我不认为这是)。

至于为什么你看到你所看到的行为,这是因为的 的getElementsByTagName 返回生活 节点列表 。当您移动的脚本,它就会从节点列表删除。因此,考虑你的了四个剧本,你会得到一个节点列表最初包含四个元素,让。长度 4 [0] 是你的第一个脚本。当您移动的脚本出了 DIV 节点列表是因为剧本是不再更新了 DIV ,所以它的长度是现在 3 [0] 指你的第二个脚本(一个装载jQuery的)。

您就可以避免这种行为打断你的循环有两种方式:


  1. 循环落后,从。长度 - 1 0 包容性,或


  2. 转动节点列表到一个数组,这样的元素是不能从你下搬出去。


The problem I'm trying to solve is an ad loading script, that loads the ad code with jsonp and inserts it into the dom.

Now sometimes the ad code will include javascript tags, and i figured it was just a matter of moving them to the head section and they would run. In theory that works fine but when i made a script to move script tags to the head i ran into some weird behavior.

So I wrote this code to test just the script moving part, eliminating the rest of the code as an error source.

I get the same results, if I have just two scripts in the div it moves one of them, if I have 3 scripts it moves 2 of them. In the code pasted below it moves script 1 and 3, skipping the remote javascript reference and the last script-tag.

Would be interesting to at least know why this happens, and if it can be solved.

Edit: To clarify one thing, if i put the remote jquery script first and one of the simple script tags second it will move the remote script tag to the head fine and skip the second script tag.

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
// get div id
function test() {
var td = document.getElementById('testId');
var scripts = td.getElementsByTagName("script");
console.log("No. of scripts to transfer to head: "+scripts.length);
for(i=0;i<scripts.length;i++) {
    var curScript = scripts[i];
    document.head.appendChild(curScript);
}   
}
</script>
</head>
<body onload="test();">
<div id="testId">
    <script type="text/javascript">var firstScript = 1;</script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript">var secondScript = 1;</script>
    <script type="text/javascript">var thirdScript = 1;</script>
</div>
</body>
</html>

解决方案

You're laboring under a false assumption: It doesn't matter whatsoever whether script elements are in the head or body, they get run regardless. Moving them after they've been appended to the DOM is at best pointless, and at worst may cause unfortunate side-effects if the script is re-run when moved (but I don't think it is).

As for why you're seeing the behavior you're seeing, it's because getElementsByTagName returns a live NodeList. When you move a script, it gets removed from the NodeList. So given your four scripts, you'll get back a NodeList initially containing four elements, so .length is 4 and [0] is your first script. When you move that script out of the div, the NodeList is updated because the script is no longer in the div, so its length is now 3 and [0] refers to your second script (the one loading jQuery).

You can avoid having this behavior interrupt your loop in two ways:

  1. Loop backward, from .length - 1 to 0 inclusive, or

  2. Turn the NodeList into an array, so the elements aren't moved out from under you.

这篇关于追加脚本使用JavaScript来领导 - 怪异的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆