2012-09-06 52 views
3

我正在使用JQuery mobile plugin并且出现了奇怪的问题。变量在函数中定义,但需要重新定义

如果我像下面一样使用它,它的工作原理。

$("#mainPage").on("pageshow", function(e) { 

     var availableTags = ['some', 'about', 'tags']; 

     $("#searchField").autocomplete({ 
      target: $('#suggestions'), 
      source: availableTags 
     }); 
    }); 

但是,如果像下面这样使用它,它不起作用。 但在函数中定义了cached并正确显示了该id。 如果我在函数中重新定义了cached,它会再次起作用。谁能解释为什么?

var cached = $("#searchField"); 

    $("#mainPage").on("pageshow", function(e) { 

     var availableTags = ['some', 'about', 'tags']; 

     //Alert says searchField 
     alert(cached.attr('id')); 

     //If I uncomment below line it works. 
     //cached = $("#searchField"); 

     cached.autocomplete({ 
      target: $('#suggestions'), 
      source: availableTags 
     }); 
    }); 
+1

看起来你正在使用jQuery Mobile。 jQuery Mobile在页面导航方面做了一些奇怪的事情。 jQuery Mobile的导航很可能会在某个时候删除您的搜索字段。另一个可能性是你实际上有重复的ID,也是由于jQuery手机处理页面导航的方式。 –

+0

如果没有更多的上下文,我们将无法提供帮助。我建议把jsFiddle演示放在一起。 –

+0

问题是你为什么要在外面宣布它? – Raanan

回答

3

这似乎工作: http://jsfiddle.net/9uxtT/ 它是如何从你的情况有什么不同?

+0

+1不错,让jsfiddle开始,让OP可以得到这个减少。 –

+0

+1我试图重现相同的错误。 – noway

+0

不幸的是,我无法重现相同的错误。有很多脚本,我不能把它们放在那里。我也解决不了。我将此标记为答案。我的快速解决方法是取消注释'cached = $(“#searchField”);'也'cached = cached || $(“#searchField”);'没有帮助,因为我认为已经定义了缓存。 – noway

2

它在你正在寻找pageshow在标记“#searchField”的第一个版本的时间问题,当所有的jQuery的模块已加载和DOM完成

在你正在寻找第二个版本标签,每当JavaScript被加载,有时甚至可能甚至找不到#搜索字段,如果JavaScript是在同一个文件的头部。

要完成答案: 需要采取考虑到jQuery选择返回对象而不是DOM元素检查这个程序,看看你会得到两个不同的对象:

var cached = $("#searchField"); 
cached.test = 1; 
$("#p2").on("pageshow", function(e) { 
    var test2 = $("#searchField"); 
test2.test =2; alert(cached.test +"!="+ test2.test); 
});​ 
+1

我不确定这一点。如果'searchField'不存在,那么存储在'cached'中的引用将是'[]',并且警报将显示'undefined'。尽管使用'cached.attr('id')'的警报显示了id。因此该元素最初被发现。由于'cached'只是对DOM元素的引用,所以引用看起来好像仍然有效,否则alert将不会找到id属性。或者我错过了什么? – Nope

+0

好吧,我认为这可能与原型设计有关,您是否在调用此JavaScript后加载了自动完成javascript? – Raanan

+0

好吧,这就解释了为什么在元素处于DOM之后,但在JQueryMobile有机会使用插件增强其功能之前,您没有得到“未定义”的元素。 – Raanan

1

$("#searchField")当你没有定义调用它的功能外,这里的缓存它的第一次调用处理程序的简单方法

var cached; 

$("#mainPage").on("pageshow", function(e) { 
    // This line will only call jQuery once 
    cached = cached || $("#searchField"); 

    var availableTags = ['some', 'about', 'tags']; 

    alert(cached.attr('id')); 

    cached.autocomplete({ 
     target: $('#suggestions'), 
     source: availableTags 
    }); 
}); 

这里是如何做到这一点没有一个全局变量,通过使用自调用函数T Ø包装变量在封闭

$("#mainPage").on("pageshow", (function(){ 
    var cached; 
    return function(e) { 
     // This line will only call jQuery once 
     cached = cached || $("#searchField"); 

     var availableTags = ['some', 'about', 'tags']; 

     alert(cached.attr('id')); 

     cached.autocomplete({ 
      target: $('#suggestions'), 
      source: availableTags 
     }); 
    } 
})()); 
+0

同样的问题:如果'searchField'不存在,'alert(cached.attr('id'));'如何在原始代码中显示值而不是'undefined'? – Nope

+0

@FrançoisWahl我不明白,你可以创建一个减少http://jsfiddle.net? –

+0

我只读了OP的oringal代码,它在第二个代码示例中提到警告'//Alert说searchField',表示该元素存在。 OP也声明'但是缓存被定义在函数中并且正确地显示了id.'如果在'pageShow'被触发之前'searchField'完全不存在,否则'alert(cached.attr('id '));'会显示'undefined'; – Nope