У меня возникла проблема с пониманием общего порядка выполнения 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, на переменные шаблона больше не ссылаются должным образом. Возможно, это заслуживает отдельного поста.
plateinfo.js
. Но я все еще держу пари, что ваша проблема связана с областью, в которой вы объявляете свою функцию, и областью, в которой вы пытаетесь ее запустить. 17.09.2015