从$ .get中调用时,jQuery插件变为未定义

时间:2011-11-17 22:17:52

标签: jquery jquery-plugins

我正在使用jQuery TokenInput,在我的代码中有一个地方,我想在实际调用TokenInput之前进行Ajax调用。但是,如果我尝试从$.get内调用TokenInput,我会得到

  

Uncaught TypeError: Object #<Object> has no method 'tokenInput'

这样可行:

$("#myfield").tokenInput('/search/', {
    tokenLimit: 3
});
$("#myfield").tokenInput("add", { id: 100, name: "Fake Data" });

但这不起作用:

var old_value = $("#myfield").val();
$("#myfield").tokenInput('/search/', {
    tokenLimit: 3
});
$.get('/search/', { q: old_value }, function (data) {
    record = data[0];
    $("#myfield").tokenInput("add", {id: record.id, name: record.name });
});

所以我想我想知道的是,$.tokenInput发生了什么?我可以做些什么来确保它在$.get内可用吗?

jQuery.TokenInput的源代码:https://github.com/loopj/jquery-tokeninput/blob/master/src/jquery.tokeninput.js

更新

horsefeathers 。查看代码,我看到另一部分代码(在本例中,来自django-cms)正在引入不同版本的jQuery。由于我的$.get请求,这是,它只是在页面的另一部分。

但这是我没有得到的:为什么它在一个上下文中工作而在另一个上下文中却不起作用?在我们到达$.tokenInput代码时,两个jQuery版本都已加载。那么$发生了什么,以便它保留.tokenInput

另外,我认为有一种方法可以在一个页面上有两个版本的jQuery而不会遇到问题 - 一个版本的jQuery会以某种方式“保留”另一个版本。显然它能够部分地完成,因为$ .tokenInput确实可以在某些中运行。

幸运的是,在这个页面上,我只能禁用调用其他jQuery的模块,但我不会总是能够。鉴于我不能避免在页面上有两个版本,我可以采取哪些步骤来处理这种情况? (django-cms只与旧版本的jQuery兼容。非常讨厌,但我无能为力)。

2 个答案:

答案 0 :(得分:2)

相对于问题。

这不是问题的直接反映,而是杀死jQuery插件的一般事实。我有一个问题,如下所述,谷歌搜索后我到了这里,所以也许有人也会这样。

<script />标记附加到document会执行这些脚本,并可能会杀死$内的所有插件。

有害的剧本:

// Here html response has full index.php body,
// i.e. html has <body /> and <script /> tags inside
// (including `<script src="js/jquery.js">`).
$.get(url).done(function(html)
{
    // Here happens redeclaration of jQuery variable (i.e. $ variable),
    // because of `<script src="js/jquery.js">` inside `<body />`.
    // 
    // Redeclaration of jQuery variable mean
    // that all plugins will die (i.e. all
    // not native jQuery attributes become undefined).
    $(html).appendTo("body");
});

编辑:

另一个例子:

$("<html />").html("<script src='js/jquery.js'></script>");

将加载jquery.js

需要注意的是:像这样注入的脚本将通过ajax加载(即XMLHttpRequest)。

注意:所有这些都在Chrome中测试过,但有关html解析的jQuery行为跨浏览器:

“传入复杂的HTML时,某些浏览器可能无法生成完全复制所提供的HTML源代码的DOM。如上所述,我们使用浏览器的.innerHTML属性来解析传递的HTML并将其插入当前文档。在此过程中,某些浏览器会过滤掉某些元素,例如<html><title><head>元素。因此,插入的元素可能无法代表传递的原始字符串。“

source

答案 1 :(得分:1)

我怀疑它正在运行的脚本块位于第二个副本中加载的脚本元素之上。所以它们运行得很好 - 直到你把一些东西放到像AJAX回调这样的异步方法中。在触发时,后续的脚本块已执行,删除了回调中所需的支持

参见示例: http://jsfiddle.net/RukeN/1/