2012-09-06 53 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