Рекомендуемый способ найти текущий скрипт? - PullRequest
9 голосов
/ 13 ноября 2010

Я пишу сценарий, который должен добавить элементы DOM на страницу в том месте, где расположен сценарий (подход, подобный виджету).Каков наилучший способ сделать это?

Вот методы, которые я рассматриваю:

  1. Включите элемент с id = "Locator" прямо над сценарием.Проблемы:
    • Мне не нравится дополнительная разметка
    • Если я повторно использую виджет на странице, несколько элементов будут иметь одинаковый идентификатор "Локатор".Я думал о добавлении строки в сценарий для удаления идентификатора, который когда-то использовался, но все же ...
  2. Добавить идентификатор в сценарий.Проблемы:
    • , даже если он работает, атрибут id недопустим для элемента скрипта
    • та же проблема, что и выше, у нескольких элементов будет одинаковый идентификатор, если я повторно использую скрипт вpage.
  3. Используйте getElementsByTagName ("script") и выберите последний элемент.До сих пор это работало для меня, просто кажется немного тяжелым, и я не уверен, что это надежно (если подумать об отложенных скриптах)
  4. document.write: не элегантно, но, похоже, делаетjob.

  5. [Редактировать] Основываясь на ответе idealmachine, я подумываю над еще одним вариантом:

    • Включить в тег сценария атрибут дляпример цели = "табифицировать".
    • Используйте getElementsByTagName ("script"), чтобы получить все сценарии.
    • Прокручивайте скрипты и проверяйте атрибут goal = "tabify", чтобы найти мой скрипт.
    • Удалите атрибут цели, если на странице есть еще один виджет.
  6. [Изменить] Еще одна идея, также вдохновленная ответами на данный момент:

    • Используйте getElementsByTagName ("script"), чтобы получить все сценарии.
    • Прокручивайте сценарии и проверяйте innerHTML, чтобы найти мой сценарий.
    • В конце сценария удалите тег сценария, если на странице есть другой виджет.

Ответы [ 8 ]

4 голосов
/ 10 июня 2011

Работает с несколькими копиями одного и того же кода на странице, а также с динамически вставленным кодом:

<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>
3 голосов
/ 23 сентября 2015

Из коробки: document.currentScript (не поддерживается IE)

2 голосов
/ 13 ноября 2010

Я работал на OnlyWire , который предоставляет в качестве основного сервиса виджет для размещения на вашем сайте.

Мы используем трюк var scripts = document.getElementsByTagName("script"); var thisScript = scripts[scripts.length - 1];, и он, кажется, работает довольноЧто ж.Затем мы используем thisScript.parentNode.insertBefore(ga, thisScript); для вставки в дерево DOM того, что нам нужно.

Я не уверен, что понимаю, почему вы считаете это "тяжелым" решением ... оно не включает итерациюэто чисто кросс-браузерное решение, которое прекрасно интегрируется.

1 голос
/ 13 ноября 2010

Либо document.write, либо выбор последнего элемента сценария будет работать для синхронно загруженных сценариев на большинстве веб-страниц.Тем не менее, есть некоторые варианты, о которых вы можете подумать, что вы не учитываете асинхронную загрузку:

  • Добавление div с class="Locator" перед сценарием.Преимущество классов HTML в том, что дубликаты не недопустимы.Конечно, чтобы обработать случай с несколькими виджетами, вы захотите изменить имя класса элемента, когда закончите добавлять элементы HTML, чтобы вы не добавляли их дважды.(Обратите внимание, что элемент также может быть членом нескольких классов; это список, разделенный пробелами.)

  • Проверка src каждого элемента сценария может обеспечитьэтот код отслеживания ( например, устаревший код отслеживания Google Analytics) и другие сценарии, загруженные в самом конце страницы, не будут препятствовать нормальной работе сценария при использовании асинхронной загрузки.Опять же, чтобы обработать случай с несколькими виджетами, вам может потребоваться удалить элементы скрипта, когда закончите с ними ( т.е. , когда на страницу добавлен нужный код).


Последний комментарий, который я сделаю (хотя вы, возможно, уже знаете об этом), заключается в том, что при кодировании виджета вам нужно , чтобы объявить все ваши переменные с помощью var и приложить все вашикод внутри: (JSLint может помочь проверить это)

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

Это называется «самореализующейся функцией» и гарантирует, что переменные, используемые в вашем скрипте, не будут мешать остальной части веб-страницы.

1 голос
/ 13 ноября 2010

Независимо от того, добавляете ли вы тег <script> или <div class="mywidget">, вы добавляете что-то в разметку.Лично я предпочитаю последнее, так как сам скрипт добавляется только один раз.Слишком много скриптов в теле страницы может замедлить время загрузки страницы.

Но если вам нужно добавить тег скрипта, где будет виджет, я не вижу, что не так с использованием document.write()разместить div.

0 голосов
/ 10 августа 2017

Также вы можете добавить индивидуальное имя скрипта внутри них.

  • либо внутри какого-то js-script

     dataset['my_prefix_name'] = 'someScriptName'
    
  • или внутри HTML - в теге

     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
    }
 }
0 голосов
/ 10 мая 2017

Во многих случаях это работает хорошо (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; 
      }

 }
0 голосов
/ 06 мая 2011

Я только что нашел другой метод, который, кажется, отвечает на мой вопрос:

Как получить доступ к родительскому Iframe из javascript

Встраивание скрипта в iframe позволяет найти егов любое время, поскольку скрипт всегда сохраняет ссылку на свое собственное окно.

Я голосую за этот лучший подход, так как он всегда будет работать независимо от того, сколько раз вы добавляете скрипт на страницу (например, виджет).Пожалуйста, комментируйте.

Что подтолкнуло меня к тому, чтобы в первую очередь рассмотреть iframes, был эксперимент, который я провел для создания гаджета Google.

...