Javascript 无法使用jquery Ajax请求加载脚本
我需要在加载某个脚本后执行一个函数,因此我使用ajax调用加载脚本,成功后,我调用了一个函数,该函数使用了一个假定已从该脚本加载的对象,我得到一个错误,即该对象未定义。 这是我的密码:Javascript 无法使用jquery Ajax请求加载脚本,javascript,jquery,ajax,Javascript,Jquery,Ajax,我需要在加载某个脚本后执行一个函数,因此我使用ajax调用加载脚本,成功后,我调用了一个函数,该函数使用了一个假定已从该脚本加载的对象,我得到一个错误,即该对象未定义。 这是我的密码: function LoadInlineManualScript() { return $.ajax({ url: "../Scripts/inline-manual-player.js", dataType: "script", befo
function LoadInlineManualScript() {
return $.ajax({
url: "../Scripts/inline-manual-player.js",
dataType: "script",
beforeSend: function () {
loader.hide();
loader.unbind();
},
success: SetInlineManualCallbacks
});
}
function SetInlineManualCallbacks() {
debugger;
//Here I get the error!
window.inline_manual_player.setCallbacks({
onTopicDone: function (player, topic_id, step_id) {
console.log('Step was displayed.');
}
});
}
我得到了uncaughttypeerror:无法读取未定义的
的属性“setCallbacks”
我尝试将调用更改为使用async:false
,但没有帮助。当您执行此操作时
success: SetInlineManualCallbacks(inlineUid)
您正在执行该方法,并将其返回的内容设置为success回调。你不是说在触发成功时调用它
应该是
success: SetInlineManualCallbacks
但是我认为Ajax调用本身存在一个问题,您正在加载一个脚本并期望它做一些事情,我不认为Ajax调用是您想要的。如果脚本只是返回
inlineUid
为什么要使用脚本而不是JSON或文本调用。如果inlineUid
是全局的,则只需在回调方法中读取它。如果不知道脚本文件中发生了什么,就很难给出完整的答案。success
接受函数而不是值。除非SetInlineManualCallbacks
返回另一个函数,否则使用bind
并部分应用参数
function LoadInlineManualScript() {
return $.ajax({
url: "../Scripts/inline-manual-player.js",
dataType: "script",
beforeSend: function () {
loader.hide();
loader.unbind();
},
success: SetInlineManualCallbacks.bind(null, inlineUid)
});
}
如果您能解释一下inlineUid的来源,这会有所帮助。有两件事:
SetInlineManualCallbacks
没有return
语句。因此,尽管存在问题2,SetInlineManualCallbacks(inlineUid)
应该返回undefined
。但是,成功
需要一个功能:
success: SetInlineManualCallbacks.bind(null, inlineUid)
或者没有绑定的旧式学校:
success: function() {
SetInlineManualCallbacks(inlineUid)
}
但是,看起来SetInlineManualCallbacks
不需要任何参数,因此在您的情况下这就足够了:
success: SetInlineManualCallbacks
窗口。内联\u手动\u播放器
是未定义的
。从变量名判断,我认为这是因为您刚刚加载了JS文件内容,作为纯文本,但没有作为JavaScript执行内容
您可以使用eval
在success
回调中执行它,但这确实是个坏主意。我可能会在DOM中插入一个
标记,而不是使用AJAX
function LoadInlineManualScript() {
var s = document.createElement('script')
s.src = "../Scripts/inline-manual-player.js"
// your callback will fire when the script is loaded and executed
s.onload = SetInlineManualCallbacks
// it will start to load right after appended, and execute of course
document.body.appendChild(s)
}
正如有人建议的,内联手册正在该脚本中初始化自身。您的站点处于测试模式,因此脚本本身中还有一个额外的ajax请求,用于检查用户是否可以访问它。因此,脚本可能会加载,但是内联的手动播放器对象在加载时还不可用,因为在它创建对象之前还有其他事情发生 如果要在对象可用之前设置回调,可以在调用脚本加载之前使用队列操作
var inline_manual_player=inline_manual_player | |[];
内联手动播放器推送(['setCallbacks',my_callbacks])代码>
这个答案是我在这里得到的一些答案的组合:
我用来加载脚本而不是使用Jquery的$的函数是:
//Must load the script after inlineManualTracking object is ready.
function LoadInlineManualScript() {
loader.hide();
loader.unbind();
var script = document.createElement('script');
script.src = "../Scripts/inline-manual-player.js";
// your callback will fire when the script is loaded and executed
script.onload = WaitForInlineManualScriptToLoad;
// it will start to load right after appended, and execute of course
document.body.appendChild(script);
}
我加载的脚本有use strict
,无法用jquery加载,原因如下:如前面提到的epascarello
即使在使用了Leo的回答之后,我仍然对该对象有问题,这就是为什么我在脚本的onload事件之后使用以下函数的原因
function WaitForInlineManualScriptToLoad() {
if (typeof window.inline_manual_player == 'undefined') {
setTimeout(WaitForInlineManualScriptToLoad, 100);
return;
}
InitInlineManualPlayerCallBacks();
}
function InitInlineManualPlayerCallBacks() {
window.inline_manual_player.setCallbacks({
onTopicDone: function (player, topic_id, step_id) {
console.log('Step was displayed.');
}
});
}
这很有效这不是最漂亮的,但它很管用。
内联手册工具的开发者在这里(Marek)做出了回应,并提到我的网站处于“测试”模式下。我们不可能知道这会影响。看起来inline-manual-player.js异步加载window.inline\u manual\u player
。这意味着线程可以在该文件的onload事件触发后,但在窗口。inline_manual_player
加载之前继续移动。因此,您会发现window.inline\u manual\u player
在一段时间内没有定义。这可能是由于inline-manual-player.js自己进行ajax调用(或设置超时等)——JavaScript是一种异步beast
与其设置一个丑陋的(没有冒犯)设置超时,还有两种可能更好
1.
如果您愿意并且能够更新inline-manual-player.js,您可以在该文件的顶部添加类似的内容:
window.inline-manual-player-callback-queue = [];
。。。稍后在该文件中,在异步定义了窗口.inline\u manual\u player
之后,添加:
// I've made this an array, in case you'd like to add multiple functions to be called upon window.inline-manual-player being ready.
var queue = window.inline-manual-player-callback-queue;
var length = queue.length;
var i = 0;
for(i; i<length; i++) {
queue[i]();
}
2.
如果不选择编辑inline-manual-player.js,则该文件的初始作者可能已经包含类似于window.inline-manual-player-callback-queue的内容。检查该文件的文档,看看是否有一个全局方法或数组可以添加回调函数,让inline-manual-player.js在所有异步魔法发生后自动调用它
祝你好运 根据您的问题,您希望在正确加载另一个脚本后执行SKcript
在您自己的答案中,使用jQuery“getScript”函数对您来说是行不通的,那么,为什么不尝试一下不使用jQuery的老式方法呢
创建一个新的脚本元素,将其添加到文档头,并在readystate上设置回调函数
function loadScript(url, callback) {
var newScript = document.createElement( "script" )
newScript.type = "text/javascript";
if(newScript.readyState) { //IE
newScript.onreadystatechange = function() {
if (newScript.readyState === "loaded" || newScript.readyState === "complete") {
newScript.onreadystatechange = null;
callback();
}
};
} else { //Others
newScript.onload = function() {
callback();
};
}
newScript.src = url;
document.getElementsByTagName("head")[0].appendChild( newScript );
}
现在,您可以调用已定义的方法并提供回调函数,在您的情况下,这将是:
loadScript("../Scripts/inline-manual-player.js", function() {
debugger;
// should work now
window.inline_manual_player.setCallbacks({
onTopicDone: function (player, topic_id, step_id) {
console.log('Step was displayed.');
}
});
});
为什么要用ajax加载?让浏览器来做吧
函数loadScript在DOM上插入脚本,并将回调附加到脚本元素的事件onload
function loadScript(href_script, callback) {
var script = document.createElement('script');
script.src = href_script;
script.onload = callback;
// The same code used by Google Analytics
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(script, x);
};
function SetInlineManualCallbacks() {
debugger;
//Here I get the error!
console.log("Code Running");
}
这里有一个例子:
loadScript("//www.google-analytics.com/analytics.js", SetInlineManualCallbacks);
当时似乎没有执行脚本。请注意,一旦加载脚本,就会触发回调,但不一定是exec
loadScript("//www.google-analytics.com/analytics.js", SetInlineManualCallbacks);
$.event.trigger({
type: "fileExecuted");
$(document).on("fileExecuted", SetInlineManualCallbacks);