循环遍历数组以分解javascript代码

时间:2015-07-06 18:36:14

标签: javascript arrays for-loop

我有一个javascript代码,我需要重复多次,只需稍作修改:

我需要接受下面的功能,除了将info_throbber更改为video_throbber,然后更改为map_throbber,然后执行picture_throbber并仅在2行上执行tyhese更改(第2行和第9行)

我不想只重复几十行一行,即使它有效。我想将其分解。

$(function() {
   var $modal_types  = $('select#game_info_throbber_modal_types') # FIRST INJECTION HERE 
   , $li           = $modal_types.parent('li')
   , $ol           = $li.parent('ol')
   , $form         = $modal_types.closest('form')
   , $submit       = $form.find('input[type=submit]')
   , $add_modal    = $('<a href="#">Add Modal</a>')
   , $remove_modal = $('<a href="#">Remove Modal</a>')
   , $hidden_info_modals = $('input[id=game_info_throbber][type=hidden]')  # SECOND INJECTION HERE 
  ;

  $add_modal.click(function(e) {
    e.preventDefault();

      .append($remove_modal.clone(true));
    create_info_modal($li.clone());
  });

  $remove_modal.click(function(e) {
    e.preventDefault();

    $(this).parent('li').remove();
  });


});

使用Loop through an array in JavaScript,这是我尝试但失败的原因:

var i, s, myStringArray = [ "info_throbber", "video_throbbe", "map_throbber", "picture_throbber" ], len = myStringArray.length
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do stuff with s ...
    $(function() {
      var $modal_types  = $('select#deal_' + s + '_modal_types') 
        , $li           = $modal_types.parent('li')
        , $ol           = $li.parent('ol')
        , $form         = $modal_types.closest('form')
        , $submit       = $form.find('input[type=submit]')
        , $add_modal    = $('<a href="#">Add Modal</a>')
        , $remove_modal = $('<a href="#">Remove Modal</a>')
        , $hidden_info_modals = $('input[id=deal_' + s + '][type=hidden]')
      ;

      $add_modal.click(function(e) {
        e.preventDefault();

        $(this).closest('li')
          .append($remove_modal.clone(true));
        create_info_modal($li.clone());
      });

      $remove_modal.click(function(e) {
        e.preventDefault();

        $(this).parent('li').remove();
      });


      };   

  }
};

问题是它似乎工作但不完全,因为它没有附加在$ add_modal上,也不允许更改值。我不认为有必要深入理解上面的复杂代码,但事实是,当我只是将所有4个函数一个接一个地放入时(第一个用于info_throbber,然后是video_throbber)它不起作用,等等...),它的工作原理。所以我通过数组创建一个iteraiton应该是有效的。

感谢你的帮助,

1 个答案:

答案 0 :(得分:1)

您有JavaScript范围问题。循环中的函数仅使用为该函数的所有迭代提供的最后一个i值。您需要将索引传递给函数以使其正常工作。

有关详细信息,请参阅此堆栈问题JavaScript loop variable scope

最简单的解决方法就是将函数包装成

var i, myStringArray = [ "info_throbber", "video_throbber", "map_throbber", "picture_throbber" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  (function(index) {
    var s = myStringArray[index];
    // ... do stuff with s ...
    $(function() {
      var $modal_types  = $('select#deal_' + s + '_modal_types') 
        , $li           = $modal_types.parent('li')
        , $ol           = $li.parent('ol')
        , $form         = $modal_types.closest('form')
        , $submit       = $form.find('input[type=submit]')
        , $add_modal    = $('<a href="#">Add Modal</a>')
        , $remove_modal = $('<a href="#">Remove Modal</a>')
        , $hidden_info_modals = $('input[id=deal_' + s + '][type=hidden]')
      ;

      $add_modal.click(function(e) {
        e.preventDefault();

        $(this).closest('li')
          .append($remove_modal.clone(true));
        create_info_modal($li.clone());
      });

      $remove_modal.click(function(e) {
        e.preventDefault();

        $(this).parent('li').remove();
      });

      $submit.click(function(e) {
        var components = JSON.stringify( collect_info_modals() )
        ;

        $ol.find('ol.info_modal').remove();
        $modal_types.remove();

        $hidden_info_modals.val( components );
      });

      var modal_types_change = function() {
        var $el = $(this)
          , $li = $(this).closest('li')
          , id = $(this).val()
          , $components = $li.find('ol.components')
        ;

        $components.remove();

        get_modal_structure(id, $li.find('select') );
      };

      $modal_types.attr({ id: null, name: null });

      $li.remove();

      var create_info_modal = function($modal, modal_type_id) {

        var $select = $modal_types.clone();

        if($modal.find('select').length) { $select = $modal.find('select'); }

        $select.val(modal_type_id); 
        $select.change(modal_types_change);

        $modal.prepend($select);
        $modal.append($add_modal);

        $ol.append($modal);
      };

      var collect_info_modals = function() {
        var $info_modals = $ol.find('ol.components')
          , components   = []
        ;

        $.each($info_modals, function(_, $info_modal) {
          $info_modal    = $($info_modal);

          var info_modal = {}
            , $components  = $info_modal.find('li.component input')
            , modal_id   = $info_modal.parent('li').find('select').val()
          ;

          info_modal['modal_id'] = modal_id;

          $.each($components, function(_, component) {
            component = $(component);

            key = component.attr('name');
            val = component.val();
            info_modal[key] = val;

            component.remove();
          });

          $info_modal.parent('li').remove();
          components.push(info_modal);
        });

        return components;
      };

      function get_modal_structure(id, $select) {
        // Grab modal structure
        var url = '/admin/modal_types/modal_structure?id='+id;

        $.getJSON(url, function(modal_structure) {
          var $ol = $('<ol class="components">');

          modal_structure.forEach(function(component){
            $ol.append(build(component));
          });

          $ol.insertAfter($select);
        });
      };

      function build(component, value) {

        value = value || '';

        var text_maxlength = 300
          , $li    = $('<li class="component string input stringish" />')
          , $label = $('<label>'+component+'</label>')
          , $input = $('<input name="'+component+'" type="text" required="required" maxlength='+text_maxlength+' value="' + value + '"/>')
        ;

        // validations
        if(component.match(/^text/)) {
          $input.attr('maxlength', text_maxlength);
        }

        $li
          .append($label) // returns the LI NOT THE LABEL
          .append($input);

        return $li;
      };



      (function() {
        var hidden_info_modals = ($hidden_info_modals.val().length) ? $hidden_info_modals.val() : '[]';

        hidden_info_modals = JSON.parse( hidden_info_modals );

          hidden_info_modals.forEach(function(info_modal) {
              var modal_type_id
                , $info_modal = $li.clone(true)
                , $ol = $('<ol class="components">');
            ;

              modal_type_id = info_modal['modal_id'];

              delete info_modal['modal_id'];

              for (var key in info_modal) {
                  $ol.append(build(key, info_modal[key]));
                }

              $info_modal.append($ol)
              $info_modal.append($remove_modal.clone(true))
              create_info_modal($info_modal, modal_type_id);
          });
      })();

      create_info_modal($li.clone(true));

    });
  })(i);
}

此外,您应该删除if (i in myStringArray),因为仅当您对对象的属性执行foreach循环时才需要,而不是在循环遍历数组的索引时。