8

假设script脚本运行时文档中的最后一个元素* 是当前正在运行的脚本是否安全?

例如,我想创建一个脚本,该脚本可以放在页面正文的任何​​位置,并在同一位置显示一个元素。我正在做这样的事情:

function getCurrentScriptElement() {
    var scripts = document.getElementsByTagName('script');
    return scripts[scripts.length - 1];
}

var script = getCurrentScriptElement();
var view = document.createElement('span');

/* Put stuff in our view... */

script.parentNode.insertBefore(view, script);

假设脚本在文档正文中,这是否“安全”?该getCurrentScriptElement函数是否总是返回正在运行的脚本?如果没有,怎么办?

我想在不将脚本绑定到特定 id 属性或类似属性的情况下执行此操作,我希望它只是位置性的。


我在这里创建了一个示例来引入这个脚本。一个答案表明,其他脚本可能会创建这样的示例会中断的条件。是否可以在此示例中添加其他脚本来破坏它?


有人建议其他具有deferasync属性的脚本可以打破这一点。谁能举例说明这样的脚本如何工作?

据我了解,defer意味着首先加载 DOM,然后运行带有defer标签的脚本。出现在另一个脚本元素上的属性将如何defer影响 的行为getCurrentScriptElement

async,据我了解,这意味着开始获取该脚本并同时继续解析 DOM,不要等待……但是当它到达我的脚本时,它仍然应该停止并等待,对吗?

我看不出任何一个会如何影响它,谁能提供一个例子?


*出于这个问题的目的,我只对外部脚本感兴趣。

** 不是script整个文档中的最后一个script元素,而是文档运行时的最后一个元素。文档的其余部分不应该加载,对吧?

4

3 回答 3

5

这不是绝对的保证。看看这个 JSFiddle:http: //jsfiddle.net/jAsek/

<!DOCTYPE html>
<title>Test case</title>
<div>
    <p>At the start</p>
    <script id="first">
        var scr1 = document.createElement("script");
        scr1.setAttribute("id", "early");
        document.body.appendChild(scr1);
    </script>
    <p>After the first script</p>
    <script id="second">
        function getCurrentScriptElement() {
            var scripts = document.getElementsByTagName('script');
            return scripts[scripts.length - 1];
        }

        alert(getCurrentScriptElement().id);
    </script>
    <p>At the end</p>
</div>

此处警报报告“早期”注入脚本的 id,而不是当前正在运行的脚本“第二”的 id。

内部脚本和外部脚本之间没有实际区别。

于 2013-01-19T01:54:08.870 回答
1

我认为这根本不是一个安全的假设,因为浏览器执行 javascript 代码的方式取决于许多事情(比如头部是否有其他脚本元素,如果它们是外部的等)。

您应该只要求人们使用具有自定义 id 或类的虚拟元素。这样,您还可以在一个页面上多次执行您所做的任何事情,而无需多次运行脚本。

这也是使用小部件时所做的事情,例如 Google 的 +1 按钮。

另一种方法是document.write在脚本执行时用于编写附加内容。但是,这不会替换脚本标记,而只是在其后添加一些内容。

于 2013-01-19T01:03:52.997 回答
1

如果您的目标是 IE, 您可能希望使用90% 的浏览器当前支持的 document.currentScript 并回退到 document.scripts[document.scripts.length-1]

function writeHere(element)
{
 var sc = document.currentScript || document.scripts[document.scripts.length-1] ;  
 sc.parentNode.insertBefore(element, sc);
 // or in jquery $(sc).before($(element));
}

注意:我没有document.scripts[document.scripts.length-1]彻底测试,但它应该在大多数情况下工作(但不是在 Alohci 示例中)。
这是对 IE 的修复,所以谁在乎 :)

于 2018-10-18T08:36:24.197 回答