函数如何知道它在DOM中的位置?

时间:2009-05-19 15:47:33

标签: javascript dom

我正在尝试编写一个javascript函数,在调用它的位置将一些DOM节点添加到文档中,如下所示:

...
<div>
  <script type="text/javascript">
    pushStuffToDOMHere(args);
  </script>
</div>
...

我尝试'干净地',不使用div的node id属性或innerHTML字符串操作。为此,我需要知道脚本标记位于文档的哪个位置。 有办法吗?

5 个答案:

答案 0 :(得分:13)

干净利落地说,我不认为你的做法特别干净。给Document一个唯一的id并在DocumentReady事件触发时执行你的javascript是一个更好的主意。

答案 1 :(得分:3)

你有这样一个压倒一切的理由吗?如果不是,使用唯一ID的建议最有意义。而且你总是可以使用像jQuery这样的库来让自己更容易。

但是,以下快速测试表明,如果在函数中使用document.write(),则会将值写入调用函数的位置。

<html>
<head>
   <script type="text/javascript">
           function dosomething(arg){
              document.write(arg);
           }
   </script>
</head>
<body>
<div>The first Div</div>
 <div>The 
    <script type="text/javascript">
           dosomething("Second");
   </script>
      Div
 </div>
 <div>The
        <script type="text/javascript">
           dosomething("Third");
       </script>
      Div
    </div>
   </body>
</html>

但是,问题是,你确定这是你想要做的吗?

答案 2 :(得分:2)

虽然我同意n3rd并投票支持他,但我明白你所说的是你有一个特定的挑战,你不能在html部门添加id,除非通过脚本。

因此,我建议将脚本内联到DOM层次结构中,在这种情况下:

  1. 脚本代码 中添加 ID 。 (是的,脚本标签也可以有ID。)

    • 离。 <script id="specialagent" type="text/javascript">
  2. 在内联脚本函数中添加一行,按ID获取脚本元素。
    • 离。 this.script = document.getElementById('specialagent');
  3. ...另一个获取脚本元素的parentNode。

    • 离。 var targetEl = this.script.parentNode;
  4. 如果可以,请考虑将您的函数重构为自执行函数。

    • 理想情况下,它会立即执行,而无需进行“onload”调用。
    • 见摘要示例,接下来。
  5. 摘要示例:

    <script id="specialagent" type="text/javascript">
    var callMe = function(arg1,arg2,arg3) {
        this.script = document.getElementById('specialagent');
        var targetEl = this.script.parentNode.nodeName=="DIV" && this.script.parentNode;
        //...your node manipulation here...
    }('arg1','arg2','arg3');
    </script>
    

    以下TEST代码在运行时证明该函数已在DOM中确定了它的位置,更重要的是,它的parentNode。测试具有带有id的分区节点,仅用于测试目的。除了测试之外,它们不是识别它们的功能所必需的。

    测试代码:

    <html>
    <head>
    <title>Test In place node creation with JS</title>
    </head>
    <body>
    <div id="one">
        <h2>Child of one</h2>
        <div id="two">
                <h2>Child of two</h2>
                <script id="specialagent" type="text/javascript">
                var callMe = function(arg1,arg2,arg3) {
                    this.script = document.getElementById('specialagent');
                    var targetEl = this.script.parentNode;
                    /*BEGIN TEST*/
                     alert('this.script.id: ' + this.script.id);
                     alert('targetEl.nodeName: ' + targetEl.nodeName + '\ntargetEl.id: '+targetEl.id);
                     alert('targetEl.childNodes.length: ' + targetEl.childNodes.length);
                     var i = 0;
                     while (i < targetEl.childNodes.length) {
                         alert('targetEl.childNodes.'+i+'.nodeName = ' + targetEl.childNodes[i].nodeName);
                         ++i;
                    }
                    /*END TEST - delete when done*/     
                    //...rest of your code here...to manipulate nodes
                }('arg1','arg2','etc');
                </script>
         </div>
     </div>
     </body>
     </html>
    

答案 3 :(得分:0)

不确定你想要实现什么,但是这会在点击时将dom元素传递给函数。然后你可以在函数中使用jquery来做你想做的事情

...
<script type="text/javascript">
    function pushStuffToDOMHere(element)
    {
          $(element).append("<p>Hello</p>"); // or whatever
    }
</script>
<div onclick="pushStuffToDOMHere(this);">

</div>
...

答案 4 :(得分:0)

我的解决方案是对这里发布的(好)答案的反应:

当函数被调用时,它将document.write一个具有唯一id的div。 然后在document.onload上可以很容易地找到div的父节点并附加新的子节点。

我选择这种方法是因为一些独特的限制:除了添加脚本元素之外,我不允许触摸HTML代码。真的,问问老板......

后来想到的另一种方法:

function whereMI(node){
    return (node.nodeName=='SCRIPT')? node : whereMI(node.lastChild);
}
var scriptNode = whereMI(document);

但是,当文件加载完毕之前,像fireBug这样的东西会将自己附加为HTML节点中的最后一个元素,这会失败。