jquery引用错误和执行顺序?

时间:2015-09-17 17:51:05

标签: javascript jquery html execution

我遇到了解一般javascript / jquery执行顺序的问题,以及适当的地方存储你的js。我正在尝试重新组织我的代码,并继续遇到同样的问题,这让我对所有的javascript越来越感到沮丧。

我正在使用Jinja2模板构建一个Python + Flask webapp,整合各种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

为什么会这样?

除了: 我在javascript中引用我的Jinja2模板变量也有单独但相关的问题。我正在使用这个header.html文件。如果我在同一个html文件中包含所有js代码,它可以正常工作。但是当我将js移动到单独的header.js时,模板变量不再被正确引用。也许这应该是一个单独的帖子。

1 个答案:

答案 0 :(得分:0)

getHash()未定义为全局函数。它是私有的,只属于plateinfo.js中的函数,你告诉jQuery在页面加载时运行。您的代码当前设置的方式,您无法在其他任何地方找到它。但是在你的内联JS中,这就是你要做的事情:

var ifuhash = getHash();

您可以在全球范围内提供getHash()

function getHash() {
  // ...
}

window.getHash = getHash;

但这通常被认为是编码不良的做法。构建代码的更好方法是使用namespaces将所有自定义函数和对象保存在一个位置并将其附加到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>