Nano Hash - криптовалюты, майнинг, программирование

Ошибка ссылки jquery и порядок выполнения?

У меня возникла проблема с пониманием общего порядка выполнения javascript/jquery и того, где правильно хранить ваши файлы js. В данный момент я пытаюсь реорганизовать свой код и продолжаю сталкиваться с теми же проблемами, которые все больше и больше разочаровывают меня во всем javascript.

Я создаю веб-приложение Python + Flask с шаблонами Jinja2, включая различные материалы jquery. Изначально у меня был стандартный HTML-код, который выглядел примерно так...

<html>
 <head>
    <script type="text/javascript" src="{{url_for('static',filename='js/jquery/jquery-1.11.2.min.js')}}"></script>
    <script type="text/javascript" src="{{url_for('static',filename='js/bootstrap/bootstrap.min.js')}}"></script>
    <script type="text/javascript" src="{{url_for('static',filename='js/utils.js')}}"></script>

    <script type='text/javascript'>
       # get hash from page
       function getHash() {
          var hash = window.location.hash;
          var newhash = hash.slice(hash.search('_')).replace('_','#');
          return newhash;
       }

      // Load ifu div element if hash present when page loads
      $(function(){
        var ifuhash = getHash();
        var ifu = ifuhash.slice(ifuhash.search('#')+1);
        $(String(ifuhash)).fadeIn();    
        if (hash.search('comment') >= 0) $(String(hash)).fadeIn();
      });           

      ... other js ....

    </script>
 </head>

 <body>
    {% include 'header.html' %}
 </body>
</html>

Это работает просто отлично. Но поскольку хорошей практикой, по-видимому, является размещение всех JS в своих собственных файлах, чтобы не загромождать html, я пытаюсь реорганизовать свой текущий код javascript так, чтобы он, по моему мнению, должен работать, но я сталкиваюсь с проблемами .

функция getHash является общей для нескольких страниц, поэтому я вытащил ее и вставил в отдельный фрагмент js, называемый plateinfo.js, так что теперь мой код

<html>
 <head>
    <script type="text/javascript" src="{{url_for('static',filename='js/jquery/jquery-1.11.2.min.js')}}"></script>
    <script type="text/javascript" src="{{url_for('static',filename='js/bootstrap/bootstrap.min.js')}}"></script>
    <script type="text/javascript" src="{{url_for('static',filename='js/utils.js')}}"></script>
    <script type="text/javascript" src="{{url_for('static',filename='js/plateinfo.js')}}"></script>

    <script type='text/javascript'>
      // Load ifu div element if hash present when page loads
      $(function(){
        var ifuhash = getHash();
        var ifu = ifuhash.slice(ifuhash.search('#')+1);
        $(String(ifuhash)).fadeIn();    
        if (hash.search('comment') >= 0) $(String(hash)).fadeIn();
      });           

      ... other js ....

    </script>
 </head>

 <body>
   {% include 'header.html' %}
 </body>
</html>

и plateinfo.js выглядит так

// Toggle add comment login function
$(function() {
    $('#addcommentbut').click(function() {
        var fxn = 'grabComments';
        $('#fxn').val(fxn);
    });
});

// Get IFU hash from page
function getHash() {
    var hash = window.location.hash;
    var newhash = hash.slice(hash.search('_')).replace('_','#');
    return newhash;
}

// Render Tags in div
function renderTags(hash) {
  ..does stuff
}

Однако, когда я это делаю, я получаю сообщение об ошибке

ReferenceError: getHash не определен

Функция находится за пределами области DOM и должна быть импортируемой. И я делал это успешно раньше. Файл utils.js содержит автономные функции, которые отлично работают. Я очистил кеш, перезапустил браузер, чтобы обновить сеанс, перезагрузил компьютер, но ничего не работает. Так в чем же дело? Я думал, что порядок выполнения кода html/js был прямым сверху вниз. Итак, какова лучшая практика здесь? Каков правильный порядок импорта/выполнения?

Обновить, чтобы показать порядок выполнения:
Итак, я добавил кучу console.logs вот так

<html>
 <head>
    <script type="text/javascript" src="{{url_for('static',filename='js/jquery/jquery-1.11.2.min.js')}}"></script>
    <script type="text/javascript" src="{{url_for('static',filename='js/bootstrap/bootstrap.min.js')}}"></script>

 <script type='text/javascript'>$(function() {console.log('before utils.js');});</script>
    <script type="text/javascript" src="{{url_for('static',filename='js/utils.js')}}"></script>
<script type='text/javascript'>$(function() {console.log('after utils.js');});</script>

<script type='text/javascript'>$(function() {console.log('before plateinfo.js');});</script>
    <script type="text/javascript" src="{{url_for('static',filename='js/plateinfo.js')}}"></script>
<script type='text/javascript'>$(function() {console.log('after plateinfo.js, before last script');});</script>

    <script type='text/javascript'>
      console.log('start of last script');

      // Load ifu div element if hash present when page loads
      $(function(){
        console.log('calling gethash');
        var ifuhash = getHash();
        var ifu = ifuhash.slice(ifuhash.search('#')+1);
        $(String(ifuhash)).fadeIn();    
        if (hash.search('comment') >= 0) $(String(hash)).fadeIn();
      });           

      ... other js ....

    </script>
 </head>

 <body>
   {% include 'header.html' %}
 </body>
</html>

и вот вывод лога

before utils.js plateInfo.html:40:1
after utils.js plateInfo.html:44:1
start of last script plateInfo.html:204:5
before plateinfo.js plateInfo.html:185:3
after plateinfo.js, before last script plateInfo.html:189:15
calling gethash plateInfo.html:221:3
ReferenceError: getHash is not defined plateInfo.html:222:6

Почему это?

Кроме того: у меня также есть отдельные, но связанные проблемы со ссылкой на мои переменные шаблона Jinja2 внутри javascript. Это происходит с этим файлом header.html, который я включаю. Если я включу весь код js в один и тот же html-файл, он будет работать нормально. Но когда я перемещаю js в отдельный header.js, на переменные шаблона больше не ссылаются должным образом. Возможно, это заслуживает отдельного поста.


  • Я бы подумал, что {{url_for('static',filename='js/plateinfo.js')}} оценивается после того, как DOM готов, так что ваш встроенный скрипт запускается до того, как все ваши скрипты будут загружены. Возможно, я бы попробовал вставить console.logs в разные места вашего кода, чтобы вы могли отслеживать, когда загружаются компоненты. 17.09.2015
  • Так что да, я попробовал это, и кажется, что это вызывает все не по порядку. Он пропускает console.logs, а затем возвращается к ним. Я понятия не имею, что происходит. Если это происходит в правильном порядке, то почему метод не определяется. Я отредактировал текст, чтобы обновить его в соответствии с порядком регистрации. 17.09.2015
  • @Neil Jinja — это язык шаблонов Python; Я почти уверен, что он будет оцениваться на сервере, а не в браузере. 17.09.2015
  • не помещайте свои console.logs в методы загрузки jQuery. Все они выполняются одновременно, один за другим. Лучшей методологией было бы поместить вызовы console.log непосредственно в сами файлы (utils.js, plateinfo.js). 17.09.2015

Ответы:


1

getHash() не определена как глобальная функция. Он частный, принадлежит только функции в plateinfo.js, которую вы указываете jQuery для запуска при загрузке страницы. То, как ваш код настроен в настоящее время, вы не можете получить к нему где-либо еще. Но в вашем встроенном JS это то, что вы пытаетесь сделать:

var ifuhash = getHash();

Вы можете сделать getHash() доступным по всему миру:

function getHash() {
  // ...
}

window.getHash = getHash;

но это обычно считается плохой практикой кодирования. Лучший способ структурировать код — использовать пространства имен для храните все свои пользовательские функции и объекты в одном месте и прикрепите их к window:

<script type="text/javascript">
  window.myNamespace = window.myNamespace || {};
  window.myNamespace.getHash = function() {
    return 123;
  };
</script>
<script type="text/javascript">
  $(function() {
    var foo = window.myNamespace.getHash(); // foo now equals 123
  });
<script>
17.09.2015
  • ах, я неправильно проанализировал ваш файл plateinfo.js. Но я все еще держу пари, что ваша проблема связана с областью, в которой вы объявляете свою функцию, и областью, в которой вы пытаетесь ее запустить. 17.09.2015
  • Он уже объявляет getHash в глобальном пространстве имен, это не закрытие. Тот факт, что объявление функции находится в отдельном файле, не означает, что оно не объявлено в глобальной области видимости. 17.09.2015
  • Думаю, это был своего рода ответ. В итоге я переписал весь plateinfo.js, чтобы он стал объектом, экземпляр которого я создаю в своем основном блоке кода. Я преобразовал getHash в функцию, которая запускается при инициализации и сохраняет результат в переменной объекта. Это, казалось, упростило и решило мою проблему. 22.09.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..