12

我正在编写一个脚本,该脚本需要在脚本所在的位置(类似小部件的方法)向页面添加 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 以找到我的脚本。
    • 在脚本结束时,删除脚本标签,以防页面中有另一个小部件。
4

9 回答 9

6

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

于 2015-09-23T12:40:18.630 回答
4

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

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

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

于 2010-11-13T11:13:20.023 回答
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>
于 2011-06-10T11:18:42.377 回答
1

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

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

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


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

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

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

于 2010-11-13T12:53:53.967 回答
1

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

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

于 2010-11-13T11:26:23.517 回答
0

我刚刚找到了另一种似乎可以回答我的问题的方法:

如何从 javascript 访问父 iframe

将脚本嵌入 iframe 允许随时定位它,因为脚本始终保持对自己窗口的引用。

我认为这是最好的方法,因为无论您将脚本添加到页面多少次(想想小部件),它都将始终有效。欢迎您发表评论。

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

于 2011-05-06T06:21:14.627 回答
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'])
}
于 2020-03-11T17:17:34.507 回答
0

您也可以在其中添加单个脚本的名称。

  • 要么在一些js 脚本中

     dataset['my_prefix_name'] = 'someScriptName'
    
  • 或在HTML中 - 在 <script> 标记中

     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
    }
 }
于 2017-08-10T17:40:08.627 回答
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; 
      }

 }
于 2017-05-10T15:29:32.913 回答