Какой самый простой тег с параметрами

#javascript #script-tag

#javascript #скрипт-тег

Вопрос:

Я хочу включить тег script, одновременно предоставляя ему параметр. Это то, что я придумал до сих пор

  1. Укажите параметр для URL скрипта (недостатки: генерирует несколько файлов JS)

     <script src="http://example.com/something.js?P=123" type="text/javascript"></script>
      
  2. Скрыть параметр в теге script (минусы: такой же, как # 1)

     <script src="http://example.com/scripts/123/something.js" type="text/javascript"></script>
      
  3. Способ Google Analytics (недостатки: некрасивый, сложный, глобальные переменные)

     <script type="text/javascript" charset="utf-8">
      var _something = _something || 123;
      (function() {
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.src = 'http://example.com/something.js';
        var ss = document.getElementsByTagName('script')[0];
        ss.parentNode.insertBefore(s, ss);
      })();
    </script>
      

Ответ №1:

Лучше всего определять вещи (функции и c) во внешнем скрипте, но ничего не выполнять. Затем создайте встроенный скрипт, который вызывает функции / методы, определенные во внешнем скрипте.

 <script src="http://example.com/something.js" type="text/javascript"></script>
<script type="text/javascript">
    something(123);
</script>
  

Комментарии:

1. У этого все еще есть те же недостатки, что и у моего # 3 (глобальные переменные, слишком сложные для включения), хотя и короче 🙂

2. @pitr: глобальной переменной нет, и вызов функции не так уж сложен. Этот подход аналогичен тому, который вы использовали бы в других языках, где внешний скрипт является библиотекой, а внутренний — точкой входа в программу. Точно так же используются библиотеки JS.

3. something() находится в глобальном пространстве имен, не так ли? Библиотеки предоставляют свою функциональность (поскольку для этого они и предназначены) через глобальные переменные (например, $ или _ ). Я, однако, не хочу излишне загрязнять пространство имен (о чем я не упомянул в своем вопросе.)

4. @pitr: something находится в глобальном пространстве имен (которое на самом деле является объектом window в случае браузеров; глобально определенные символы — это свойства глобального объекта), но это глобальная функция, а не глобальная переменная (это тот тип глобальных переменных, которого вам следует избегать, и единственный тип глобальных, который обсуждался до сих пор). Глобальные функции (включая конструкторы объектов) хороши (действительно, необходимы); даже если вы их не используете, включенный скрипт определит их, если вы не обернете весь скрипт анонимным вызовом функции.

5. … Это глобальные переменные и глобальное состояние, которые являются проблематичными. Вы можете минимизировать количество глобальных символов, определенных библиотекой, создав пространство имен (которое в JS является просто объектом), в котором функции, константы и переменные (которые все равно следует свести к минимуму, чтобы контролировать глобальное состояние) определены как свойства.

Ответ №2:

Если способ выполнения скрипта зависит от того, как он вызывается, вы можете добавить параметры, подобные вашему варианту 1.

Другие способы:

 <script params='{"abc": 123}' src="script.js"></script><!-- params is a non standard, non official attr that the script will read -->
  

или

 <script>var _abc = 123;</script>
<script src="script.js"></script>
  

или даже

 <script src="script.js#abc=123"></script>
  

Хотя я должен согласиться с @outis: загружайте одно и то же для всех, всегда, и выполняйте это так, как хотите вы / клиент (ы) впоследствии.

Ответ №3:

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

 <script type="text/javascript" src="xd.js#subdomain"></script>
  

а затем в скрипте проанализируйте его как таковой (используя jQuery):

 $('script').each(function(){
    if((src = this.src).indexOf('xd.js') < 0){ return; }
    xds = src.substr(src.indexOf('#')   1).split(',');

    // do stuff with xds
});
  

Комментарии:

1. не то, что я искал, поскольку для этого требуется код jQuery в другом месте, но идея (похожая на @Rudie) — это то, к чему я, вероятно, в конечном итоге приду. Спасибо!

2. Фрагмент jQuery идентичен ‘document.getElementsByTagName(‘скрипт’)’

3. Я говорил не о зависимости jQuery, а о том факте, что, по сути, существует два местоположения, в которых находится код.

4. Что вы имеете в виду, что для этого требуется jQuery в другом месте?

5. ваш второй фрагмент кода (использующий jQuery или нет) будет расположен далеко от первого, что снизит удобство сопровождения

Ответ №4:

В вашем первом примере не нужно генерировать несколько файлов. Его можно использовать только с помощью JavaScript, путем его обнаружения window.location.href и синтаксического анализа (вы можете найти подобные http://phpjs.org/functions/parse_url:485 и http://phpjs.org/functions/parse_str:484 полезно для этого: var queryString = parse_str(parse_url(window.location.href).query); ).

Однако, если вы используете что-то вроде #P=123 вместо ?P=123 , вы не вызовете повторной загрузки файла вашими пользователями, поэтому я бы рекомендовал это вместо этого (в этом случае измените «запрос» в приведенном выше примере кода на «фрагмент»).

Другой возможностью является использование атрибутов data-*, зарезервированных в HTML5, и определение их значений в вашем скрипте:

 <script src="http://example.com/something.js" data-myOwnAttribute="someValue" data-anotherCustomAttribute="anotherValue"></script>
  

Затем скрипт определил бы по этим строкам:

 (function () {
    function getScriptParam (attr) {
        var scripts = document.getElementsByTagName('script'),
            currentScript = scripts[scripts.length-1];
        return currentScript.getAttribute('data-'   attr); // in future, could just use the HTML5 standard dataset attribute instead: currentScript.dataset[attr]
    }
    var myOwnAttribute = getScriptParam('myOwnAttribute');
    // ... do stuff here ...
}());
  

Реальное преимущество уродливого API Google заключается в том, что он позволяет разработчикам вставлять этот код в <head> часть документа (считается правильной формой), при этом все еще действуя асинхронно в кроссбраузерном режиме. Я думаю, что они действительно могли бы избежать глобального, если бы объединили свою технику динамического тегирования скрипта с любым из вышеупомянутых подходов.