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

标签 javascript arrays for-loop

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

我需要采用下面的函数并重复它,除了将 info_throbber 更改为 video_throbber,然后更改为 map_throbber,然后更改 picture_throbber 并仅在 2 行上进行这些更改:第 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,等等),它不起作用。 。), 有用。所以我通过数组创建迭代应该可以工作。

感谢您的帮助,

最佳答案

您遇到了 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 循环时才需要它,而不是当您对数组的索引进行循环时才需要它.

关于javascript - 循环遍历数组以分解 JavaScript 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31253169/

相关文章:

JavaScript 和 Promise.all()

python - 在 for 循环中使用变量作为数据框列名称

javascript - 如何判断某个字母在字符串中的索引是什么? (Python、JS、Ruby、PHP 等......)

Javascript:如何使用 ajax 请求在 for 循环内以正确的顺序将对象插入数组

javascript - 使用 Wordpress 和 Waypoints 使左侧图像变粘,而右侧滚动

arrays - 哈希表桶数组

python - 循环遍历 pandas 数据框,同时使用正则表达式更改行值

javascript - 循环遍历函数数组 - 对象不支持此属性或方法 (IE8)

javascript - 在javascript中获取链接名称

php - 单击更改 css