2015-04-20 21 views
0

我具有如我加载雇员部及其脚本作为index.html的一部分javascript如何检测函数的定义,顶部/底部?

的index.html Working Demo

<!DOCTYPE html> 
<html> 

    <head> 
    <meta charset="utf-8" /> 
    <title></title> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="jquery" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script> 
    <script src="script.js"></script> 
    </head> 

    <body> 
    <h1>Employee Details loaded as usual and sript is executing able to see alert</h1> 
    </body> 

</html> 

的script.js

var empModule = (function (empModule) { 
    var Years = null; 

    $(document).ready(function() { 
     var empdata = { Name: 'Billa' } 
     var myVM = new empModule.viewModel(empdata); 

    }); 

    empModule.viewModel = function (data) { 
     var that = this; 
     that.Name = data.Name; 
     alert(that.Name); 
    }; 

    return { 
     empModule: empModule 
    } 
} (empModule || {}));    
以下代码工作只要

错误情景:

我们决定移动员工r高兴的部分基于某种条件。因此,我们通过Ajax加载这个部分和部分相关的脚本(emp.js)。但现在它抛出错误empModule.viewModel is not a constructor。为什么这样?

如果我在移动像以下顺序底部的document.ready部,它是工作

Emp.js(从移动的script.js通过AJAX到emp.js和负载(

var empModule = (function (empModule) { 
var Years = null; 
// Code not working when we load this script file using Ajax.    
// But works if we move this document.ready at bottom 
//$(document).ready(function() { 
    // var empdata = { Name: 'Billa' } 
    // var myVM = new empModule.viewModel(empdata); 

//}); 
empModule.viewModel = function (data) { 
    var that = this; 
    that.Name = data.Name; 
    alert(that.Name); 
}; 
//Working only if I keep the ready section here 
$(document).ready(function() { 
    var empdata = { Name: 'Billa' } 
    var myVM = new empModule.viewModel(empdata); 

}); 

return { 
    empModule: empModule 
} 
} (empModule || {})); 

功能empModule,因为它是自 执行功能将得到自动执行。当执行它需要准备 empModule.viewModel对象,但未能这样做,当视图模型 定义位于document.ready(调用者)之后。这种情况仅 当我加载通过Ajax这个脚本,但如果我预先在一个页面

+0

你能告诉你是如何加入脚本?你什么时候期待使用它?例如'$(document).ready(// call module emp)'? – Matho

+0

@Matho,函数'empModule'将自动执行,因为它是自执行函数。当它正在执行时,它需要准备一个empModule.viewModel对象,但是当viewModel定义位于document.ready(caller) – Billa

+0

阅读关于[function hosting](http://adripofjavascript.com/blog/drips /variable-and-function-hoisting.html) –

回答

1

这是因为在第一个例子中script.js是文档的一部分,因此document.ready等待该.js加载它的工作原理要在调用empModule.viewModel()之前加载文件。

在第二个示例中,脚本异步加载,但页面没有考虑到这一点。因此,页面加载(没有script.js),然后加载脚本。 此时,文档已准备好(因为ajax加载的脚本不是文档的一部分),所以empModule.viewModel()调用在脚本的其余部分(这是定义函数的位)之前立即触发,并且您获得你的错误。

+0

因此,当我们异步加载scriipt时,我们总是/必须需要定义document.ready函数上方的函数/变量? – Billa

0

就像@dougajmcdonald说是你的问题,但你的解决方案,而不是通过loadding AJAX,只需插入脚本标签文档中:

// Instead of $.ajax(... /myScript.js) use: 

function loadMyScript(){ 
     var script = document.createElement("script"); 
     script.type = "text/javascript"; 
     script.src = 'myScript.js'; 
     script.onload = function() {       
      empModule.doSomething(); // or callback 
     }; 
} 
+0

我不认为它是一个好主意,在dom中插入脚本 – Billa

+0

我没有看到任何消极的方面,但如果你仍然不想添加它,可能你应该等到文档被加载,然后使AJAX请求脚本,在'callback'里面执行你的empModule。doSomething()'代码 – Matho