как функция узнает, где она находится в DOM? - PullRequest
3 голосов
/ 19 мая 2009

Я пытаюсь написать функцию javascript, которая добавляет несколько узлов DOM к документу в том месте, где он был вызван, например:

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

Я пытаюсь сделать это «чисто», без использования свойства id узла div или манипулирования строк innerHTML. для этого мне нужно знать, где в документе находится тег script. есть ли способ сделать это?

Ответы [ 5 ]

13 голосов
/ 19 мая 2009

Говоря чисто, я не думаю, что ваш подход особенно чист. Намного лучше дать div уникальный идентификатор и выполнить ваш javascript при возникновении события DocumentReady.

3 голосов
/ 19 мая 2009

У вас есть первостепенная причина, чтобы сделать это таким образом? Если нет, то предложение использовать уникальный идентификатор имеет смысл. И вы всегда можете использовать такую ​​библиотеку, как 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 голосов
/ 21 мая 2009

Хотя я согласен с n3rd и проголосовал за него, я понимаю, что вы говорите, что у вас есть конкретный вызов, когда вы не можете добавить идентификатор в разделы html, кроме как по сценарию.

Таким образом, это было бы моим предложением для включения сценария, осведомленного о его месте в иерархии DOM, в этом случае:

  1. Добавьте id к вашему тегу сценария . (Да, у тегов сценария тоже могут быть идентификаторы.)

    • ех. <script id="specialagent" type="text/javascript">
  2. Добавьте одну строку в вашу встроенную функцию скрипта, которая получает элемент скрипта по id.
    • ех. this.script = document.getElementById('specialagent');
  3. ... И еще один, который получает parentNode элемента скрипта.

    • ех. var targetEl = this.script.parentNode;
  4. Подумайте о реструктуризации вашей функции в функцию, которая выполняет себя, если вы можете.

    • В идеале он выполняется немедленно, без необходимости вызова onload.
    • см. Краткий пример, следующий.

КРАТКИЙ ПРИМЕР:

<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. Тест имеет узлы деления с идентификатором, только для целей теста. Они не нужны для функции, чтобы идентифицировать их, кроме как для тестирования.

ТЕСТ-КОД:

<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>
0 голосов
/ 20 мая 2009

Мое решение - это набор (хороших) ответов, опубликованных здесь:

при вызове функции она будет document.write div с уникальным идентификатором. затем в document.onload родительский узел div можно легко найти и добавить новые дочерние узлы.

Я выбрал этот подход из-за некоторых уникальных ограничений: мне не разрешается трогать HTML-код, кроме добавления элементов скрипта. действительно, спроси моего босса ...

другой подход, который позже пришел в голову:

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

хотя, это должно завершиться неудачей, когда такие вещи, как fireBug, добавляются в качестве последнего элемента в узле HTML до завершения загрузки документа.

0 голосов
/ 19 мая 2009

Не совсем уверен, что вы пытаетесь достичь, но это передало бы элемент dom в функцию при нажатии. Затем вы можете использовать jquery в функции, чтобы делать то, что вы хотели, так что

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

</div>
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...