找到当前脚本的推荐方法?

时间:2010-11-13 11:04:03

标签: javascript dom document.write getelementsbytagname

我正在编写一个脚本,需要将DOM元素添加到页面,脚本所在的位置(类似于窗口小部件的方法)。 这样做的最佳方式是什么?

以下是我正在考虑的技术:

  1. 在脚本正上方包含一个id =“Locator”的元素。问题:
    • 我不喜欢额外的标记
    • 如果我在页面中重用小部件,则多个元素将具有相同的“定位符”ID。我在考虑在脚本中添加一行来删除曾经使用过的id,但仍然......
  2. 向脚本添加ID。问题:
    • 即使它似乎有效,但id属性对脚本元素
    • 无效
    • 与上述相同的问题,如果我在页面中重复使用脚本,则几个元素将具有相同的ID。
  3. 使用getElementsByTagName(“script”)并选择最后一个元素。到目前为止,这对我有用,它看起来有点沉重,我不确定它是否可靠(考虑延迟脚本)
  4. document.write:不优雅,但似乎可以胜任。

  5. [编辑]根据idealmachine的回复,我正在考虑另外一个选择:

    • 在脚本标记中包含一个属性,例如goal =“tabify”。
    • 使用getElementsByTagName(“script”)获取所有脚本。
    • 遍历脚本并检查goal =“tabify”属性以查找我的脚本。
    • 如果页面中有另一个小部件,请删除目标属性。
  6. [编辑]另一个想法,也受到目前为止的回复的启发:

    • 使用getElementsByTagName(“script”)获取所有脚本。
    • 遍历脚本并检查innerHTML以查找我的脚本。
    • 在脚本结束时,如果页面中有另一个小部件,请删除脚本标记。

9 个答案:

答案 0 :(得分:4)

这适用于页面上相同代码的多个副本以及动态插入的代码:

<script type="text/javascript" class="to-run">
(function(self){
    if (self == window) {
        var script = document.querySelector('script.to-run');
        script.className = '';
        Function(script.innerHTML).call(script);
    } else {
        // Do real stuff here. self refers to current script element.
        console.log(1, self);
    }
})(this);
</script>

答案 1 :(得分:3)

开箱即用:document.currentScript (IE不支持)

答案 2 :(得分:2)

我曾为OnlyWire工作,它提供了一个可放置在您网站上的小部件作为其主要服务。

我们使用var scripts = document.getElementsByTagName("script"); var thisScript = scripts[scripts.length - 1];技巧,似乎效果很好。然后我们使用thisScript.parentNode.insertBefore(ga, thisScript);在DOM树中插入我们想要的任何内容。

我不确定我理解为什么你认为这是一个“沉重”的解决方案......它不涉及迭代,它是一个完美集成的纯粹的跨浏览器解决方案。

答案 3 :(得分:1)

无论是删除<script>标记还是<div class="mywidget">,都会在标记中添加内容。就个人而言,我更喜欢后者,因为脚本本身只添加一次。页面正文中的脚本太多可能会减慢页面加载时间。

但是如果您需要在窗口小部件的位置添加脚本标记,我不会发现使用document.write()放置div有什么问题。

答案 4 :(得分:1)

document.write或选择最后一个脚本元素将适用于大多数网页中同步加载的脚本。但是,我可以想到一些您不考虑允许异步加载的选项:

  • 在脚本之前添加div class="Locator"。 HTML类的优点是重复项无效。当然,要处理多个小部件的情况,您需要在添加HTML元素时更改元素的类名,这样就不会添加它们两次。 (请注意,元素也可以是多个类的成员;它是以空格分隔的列表。)

  • 检查每个脚本元素的src可以确保跟踪代码(例如 Google Analytics遗留跟踪代码)和页面最后加载的其他脚本不会使用异步加载时,防止脚本正常工作。同样,要处理多个小部件的情况,您可能需要在完成它们时删除脚本元素(即。,当所需的代码已添加到页面时)。


我将做出的最后一条评论(尽管您可能已经意识到这一点)是,在编写小部件时,需要使用var声明所有变量并将所有变量括起来代码:( JSLint可以帮助检查这个)

(function(){
    ...
})();

这被称为“自执行功能”,它将确保脚本中使用的变量不会干扰网页的其余部分。

答案 5 :(得分:0)

我刚刚发现了另一种似乎回答我问题的方法:

How to access parent Iframe from javascript

将脚本嵌入到iframe中可以随时找到它,因为脚本始终保持对自己窗口的引用。

我将此投票作为最佳方法,因为无论您将脚本添加到页面多少次(想想小部件),它都会一直有效。欢迎您发表评论。

是什么促使我首先考虑iframe是我为构建Google小工具所做的实验。

答案 6 :(得分:0)

在很多情况下,这项工作很好(hud.js是scipt的名称):

var jsscript = document.getElementsByTagName("script"); 
for (var i = 0; i < jsscript.length; i++) { 
      var pattern = /hud.js/i; 
      if ( pattern.test( jsscript[i].getAttribute("src") ) )
      {
         var parser = document.createElement('a');
         parser.href = jsscript[i].getAttribute("src");
         host = parser.host; 
      }

 }

答案 7 :(得分:0)

您还可以在其中添加个人脚本的名称。

  • js-script

     dataset['my_prefix_name'] = 'someScriptName'
    
  • HTML 内 - &lt; script&gt;标签

     data-my_prefix_name='someScriptName'
    

然后通过循环遍历 document.scripts 数组来搜索合适的数组:

 ... function(){
    for (var i = 0, n = document.scripts.length; i < n; i++) {
        var prefix = document.scripts[i].dataset['my_prefix_name']
        if (prefix == 'whatYouNeed') 
           return prefix
    }
 }

答案 8 :(得分:0)

我永远都没有访问过Internet Explorer,但这应该几乎可以在任何地方工作:

<script src="script.js"
    data-count="30"
    data-headline="My headline"
    onload="uniqueFunctionName(this)"
    defer
    ></script>

和在script.js中:

window.uniqueFunctionName = function (currentScript) {
   var dataset = currentScript.dataset
   console.log(dataset['count'])
   console.log(dataset['headline'])
}