2012-04-02 33 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