Зарегистрировать события onclick из динамически созданного массива div?Rails + Jquery? - PullRequest
0 голосов
/ 02 апреля 2012

После того, как не удалось добиться этого с удаленным link_to, я решил попробовать способ jQuery. Вот цикл jQuery и цикл рельсов и как они взаимодействуют. Проблема в том, что я могу регистрировать клики только по одному из элементов div из каждого цикла, так что эта штука на самом деле не работает .. Вот код:

<% @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, который обновляет div из response_to format.js в этом действии, эта часть работает ..

Большое спасибо, любой совет очень ценится.

Ответы [ 2 ]

2 голосов
/ 02 апреля 2012

Похоже, проблема в том, что все ваши обработчики делят переменную dst. Вы можете использовать опцию http://api.jquery.com/event.data/, чтобы не полагаться на совместно используемые переменные замыкания. Вариант, предложенный JasonWoof, также работает, вы можете выбрать тот, который кажется вам более простым.

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(){}) внутри цикла. Должен быть только один звонок на $(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 голосов
/ 02 апреля 2012

Беда в том, что 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...