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

时间:2021-10-23 08:13:06

I'm trying to write a javascript function that adds some DOM nodes to the document in the place it was called, like this:

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

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

i try to do it 'cleanly', without using node id property of the div, or innerHTML string manipulation. for that I need to know where in the document the script tag is located. is there a way to do it?

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

5 个解决方案

#1


Talking about cleanly, I don't think your approach is particularly clean. It is a much better idea to give the div a unique id and execute your javascript when the DocumentReady-event fires.

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

#2


Do you have an overriding reason for doing it this way? If not the suggestion to use a unique id makes the most sense. And you can always use a library like jQuery to make this even easier for yourself.

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

However, the following quick test shows that if you use document.write() in the function then it writes the value into the place where the function was called from.

但是,以下快速测试表明,如果在函数中使用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>

But, again the question, are you sure this is what you want to do?

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

#3


Although I agree with n3rd and voted him up, I understand what you are saying that you have a specific challenge where you cannot add an id to the html divisions, unless by script.

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

So this would be my suggestion for inlining a script aware of its place in the DOM hierarchy, in that case:

所以这就是我的建议,即在这种情况下内联一个知道它在DOM层次结构中的位置的脚本:

  1. Add an id to your script tag. (Yes, script tags can have ids, too.)

    在脚本标记中添加ID。 (是的,脚本标签也可以有ID。)

    • ex. <script id="specialagent" type="text/javascript">
    • 恩。

  2. Add one line to your inline script function that gets the script element by id.
    • ex. this.script = document.getElementById('specialagent');
    • 恩。 this.script = document.getElementById('specialagent');

  3. 在内联脚本函数中添加一行,通过id获取脚本元素。恩。 this.script = document.getElementById('specialagent');

  4. ...And another that gets the script element's parentNode.

    ...另一个获取脚本元素的parentNode。

    • ex. var targetEl = this.script.parentNode;
    • 恩。 var targetEl = this.script.parentNode;

  5. Consider restructuring your function to a self-executioning function, if you can.

    如果可以,请考虑将函数重构为自执行函数。

    • Ideally it executes immediately, without the necessity for an 'onload' call.
    • 理想情况下,它会立即执行,而无需进行“onload”调用。

    • see summary example, next.
    • 参见摘要示例,接下来。

SUMMARY EXAMPLE:

<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>

The following TEST code, when run, proves that the function has identified its place in the DOM, and, importantly, its parentNode. The test has division nodes with an id, only for the purpose of the test. They are not necessary for the function to identify them, other than for testing.

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

TEST CODE:

<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>

#4


Not really sure what your trying to achieve but this would pass the dom element to the function when clicked. You could then use jquery in the function to do what you wanted like so

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

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

</div>
...

#5


my solution is a compbination of the (good) answers posted here:

我的解决方案是这里发布的(好)答案的组合:

as the function is called, it will document.write a div with a unique id. then on document.onload that div's parent node can be easily located and appended new children.

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

I chose this approach because some unique restrictions: I'm not allowed to touch the HTML code other than adding script elements. really, ask my boss...

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

another approach that later came to mind:

后来想到的另一种方法:

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

although, this should fail when things like fireBug append themselves as the last element in the HTML node before document is done loading.

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

#1


Talking about cleanly, I don't think your approach is particularly clean. It is a much better idea to give the div a unique id and execute your javascript when the DocumentReady-event fires.

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

#2


Do you have an overriding reason for doing it this way? If not the suggestion to use a unique id makes the most sense. And you can always use a library like jQuery to make this even easier for yourself.

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

However, the following quick test shows that if you use document.write() in the function then it writes the value into the place where the function was called from.

但是,以下快速测试表明,如果在函数中使用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>

But, again the question, are you sure this is what you want to do?

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

#3


Although I agree with n3rd and voted him up, I understand what you are saying that you have a specific challenge where you cannot add an id to the html divisions, unless by script.

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

So this would be my suggestion for inlining a script aware of its place in the DOM hierarchy, in that case:

所以这就是我的建议,即在这种情况下内联一个知道它在DOM层次结构中的位置的脚本:

  1. Add an id to your script tag. (Yes, script tags can have ids, too.)

    在脚本标记中添加ID。 (是的,脚本标签也可以有ID。)

    • ex. <script id="specialagent" type="text/javascript">
    • 恩。

  2. Add one line to your inline script function that gets the script element by id.
    • ex. this.script = document.getElementById('specialagent');
    • 恩。 this.script = document.getElementById('specialagent');

  3. 在内联脚本函数中添加一行,通过id获取脚本元素。恩。 this.script = document.getElementById('specialagent');

  4. ...And another that gets the script element's parentNode.

    ...另一个获取脚本元素的parentNode。

    • ex. var targetEl = this.script.parentNode;
    • 恩。 var targetEl = this.script.parentNode;

  5. Consider restructuring your function to a self-executioning function, if you can.

    如果可以,请考虑将函数重构为自执行函数。

    • Ideally it executes immediately, without the necessity for an 'onload' call.
    • 理想情况下,它会立即执行,而无需进行“onload”调用。

    • see summary example, next.
    • 参见摘要示例,接下来。

SUMMARY EXAMPLE:

<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>

The following TEST code, when run, proves that the function has identified its place in the DOM, and, importantly, its parentNode. The test has division nodes with an id, only for the purpose of the test. They are not necessary for the function to identify them, other than for testing.

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

TEST CODE:

<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>

#4


Not really sure what your trying to achieve but this would pass the dom element to the function when clicked. You could then use jquery in the function to do what you wanted like so

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

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

</div>
...

#5


my solution is a compbination of the (good) answers posted here:

我的解决方案是这里发布的(好)答案的组合:

as the function is called, it will document.write a div with a unique id. then on document.onload that div's parent node can be easily located and appended new children.

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

I chose this approach because some unique restrictions: I'm not allowed to touch the HTML code other than adding script elements. really, ask my boss...

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

another approach that later came to mind:

后来想到的另一种方法:

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

although, this should fail when things like fireBug append themselves as the last element in the HTML node before document is done loading.

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