2012-04-02 40 views
0

failing to achieve this與link_to remote之後,我決定嘗試jQuery方式。 這是jQuery循環和rails循環以及它們如何交互。問題是,我得到僅在div的出每個循環的一個記錄點擊次數,所以事情是不是真正的工作。這裏是代碼:從動態創建的div數組中註冊onclick事件? Rails + JQuery的?

<% @node.parent_relation.videos.each_with_index do |vid, idx| %> 
    <%= image_tag("http://img.youtube.com/vi/#{vid.content}/1.jpg", :id => "img_div_#{idx}") %> 
    <div id="vid_vid_<%=idx%>" style="display: none"> <%= vid.id %></div> 
<% end %> 

    <script> 
    var ids = "<%= @node.parent_relation.videos.length %>"; 
    var div_arr = []; 
    var img_arr = []; 
    var vid_id = 0; 
    for(i=0; i < parseInt(ids); i++){ 
    var x = String("vid_vid_"+String(i)); 
    var y = String("img_div_"+String(i)); 
    div_arr.push(x); 
    img_arr.push(y); 
    } 
    for (i=0; i < parseInt(ids); i++){ 
    var vst = '#'+String(img_arr[i]); 
    var dst = '#'+String(div_arr[i]); 
    $(function() { 
     $(vst).click(function(){ 
     var vid_id = $(dst).html(); 
     console.log(vid_id); 
     $.post("/nodes/iframize/", {video_id: vid_id}); 
     }); 
    }) 

} 
</script> 

並且在節點控制器和一個iframize行動js.erb從respond_to代碼format.js更新DIV在行動,這部分工程..

非常感謝,非常感謝任何意見..

+0

嘗試使用.on('click',function(){})來代替。 – Chibuzo 2012-04-02 16:53:22

回答

2

貌似問題是,所有的處理程序都共享dst變量的事實。您可以使用http://api.jquery.com/event.data/選項,以便您不依賴於共享閉包變量。 JasonWoof建議的選項也有效,您可以選擇哪一個更容易。爲您的代碼

  • 無需環路內包裹在$(function(){})您的通話

    for (i=0; i < parseInt(ids); i++){ 
        var vst = '#'+String(img_arr[i]); 
        var dst = '#'+String(div_arr[i]); 
        $(function() { 
    
        $(vst).click({dst: dst}, function(event){ 
         var vid_id = $(event.data.dst).html(); 
         console.log(vid_id); 
         $.post("/nodes/iframize/", {video_id: vid_id}); 
        }); 
        }) 
    } 
    

    一對額外的評論。從頂層應該只有一個電話給$(function(){})

  • 不需要使用String(),它只是混淆了代碼,JavaScript確實爲您輸入了強制。
  • 不要創建全局變量(您i在循環變量)
  • 不需要兩個循環,或您創建的兩個數組,它都可以在一個更清晰的方式

完成以下是我建議將腳本更改爲,

$(function() { 
    var ids = "<%= @node.parent_relation.videos.length %>"; 
    for(var i=0; i < ids; i++){ 
     $("img_div_"+i).click({dst: $("vid_vid_" + i)}, function() { 
      $.post("/nodes/iframize/", {video_id: event.data.dst.html()}); 
     }); 
    } 
}); 
+0

這工作。謝謝! – Stpn 2012-04-02 17:09:47

0

麻煩的是,DST和VST中更改循環。因此,當您的點擊處理程序運行時,它會使用dst和vst的最終版本,而不是您創建點擊處理程序時的值。

你需要dst和vst的副本,你可以通過創建一個新的上下文來完成。例如

function make_handler(vst, dst) { 
    $(vst).click(function(){ 
     var vid_id = $(dst).html(); 
     console.log(vid_id); 
     $.post("/nodes/iframize/", {video_id: vid_id}); 
    }); 
} 
$(function() { 
    for (i=0; i < parseInt(ids); i++){ 
     var vst = '#'+String(img_arr[i]); 
     var dst = '#'+String(div_arr[i]); 
     make_handler(vst, dst); 
    } 
}); 

你可以這樣做在線,但你需要一個函數,VST和DST作爲參數,因爲它們是複製,以及上下文保存回調時發生。

編輯:由「做內聯」我的意思是更換make_handler()的調用類似:

function(vst,dst) { ... } (vst, dst); 
+0

謝謝,例子會很棒! – Stpn 2012-04-02 16:55:22

+0

那裏,添加了示例。希望這是明確的。 – JasonWoof 2012-04-02 16:58:27

+0

由於某種原因,這是行不通的。 – Stpn 2012-04-02 17:09:30