проблемы с объектом jQuery и циклом

#javascript #jquery-plugins #dom-manipulation #jquery

#javascript #jquery-плагины #dom-манипуляция #jquery

Вопрос:

В данный момент я создаю плагин jQuery, который превращает a <select> в красивое выпадающее меню, хотя у меня небольшая проблема, я могу получить параметры выбора на странице, выполнив это,

 var self = $(this);
    name = self.attr('name');
    select_options = $(this).children();
    // an array so that we can related options together
    sorted_options = [];
    //loop through the options sorting them into the array as we go.
    for(i=0;select_options.length>i;i  ) {
        sorted_options.push({
            'value': select_options.eq(i).val(),
            'name': select_options.eq(i).text()
        });
    }
  

Итак, я получаю параметры, а затем сортирую их в массив, когда я отправляю этот массив на свою консоль, я получаю следующее,

 [Object { value="0", name="I'm looking for..."}, Object { value="1", name="actors"}, Object { value="2", name="presenters"}, Object { value="3", name="voice overs"}]
[Object { value="0", name="Skill"}, Object { value="1", name="actors"}, Object { value="2", name="presenters"}, Object { value="3", name="voice overs"}, Object { value="4", name="dancers"}, Object { value="5", name="accents"}, Object { value="6", name="film"}, Object { value="7", name="tv"}]
[Object { value="0", name="Gender"}, Object { value="1", name="male"}, Object { value="2", name="female"}]
  

Мой первый вопрос: как я могу удалить из массива все, что имеет значение 0, поскольку мой плагин заменяет первую запись из выпадающего списка, если пользователи тоже сообщают об этом, прежде чем я внес некоторые изменения в то, как я получил параметры, я использовал следующее,

 options.splice(0, 1);
  

Но опций больше не существует, поэтому я не могу просто удалить первую запись каждого массива, во-вторых, мне нужно добавить значения и имена в мои новые выпадающие списки, однако у меня возникают проблемы с этим,

Я использую этот код для добавления значений в данный момент,

 for(i=0;sorted_options.length>i;i  ) {
    $('.dropdown dd ul').append('<li <a href="#"><span class="option">'  sorted_options[i]['value']   '</span><span class="value">'   sorted_options[i]['name']   '</span></a></li>');
}
  

однако это добавляет все 3 объекта, которые я вижу в своей консоли, в первый выпадающий список, 2 объекта, которые я вижу в своей консоли, во второй объект и 1 объект в последний выпадающий список.

Мне нужно добавить первый объект в первый выпадающий список, второй — во второй, а третий — в третий и т.д.

Ответ №1:

Для вашего первого вопроса вы можете использовать jQuery.grep() функцию для фильтрации по элементам массива.

 var filteredArray = $.grep(rawArray, function(v,i) {
    return (v.value === '0' ? null : v);
});
  

Что касается вашего второго вопроса, я бы, вероятно, сделал это в соответствии с (если я вас правильно понимаю), используя jQuery.each :

 var template = $(
    '<li><a href="#"><span class="option"></span><span class="value"></span></a></li>'
), dropdown = $('.dropdown dd ul');

// notice that the args of $.grep and $.each are reversed
$.each(filteredArray, function(i,v) {
    // add the (i)th object to the (i)th dropdown
    dropdown.eq(i).append(
        template.clone()
            .find('.option').text(v.value).end()
            .find('.value).text(v.name).end()
    );
});
  

Итак, в основном:

  1. jQuery имеет встроенную функциональность для фильтрации и итерации по необработанным массивам JS.
  2. Кэшируйте HTML-шаблон, который вы вставляете в DOM (чтобы jQuery не приходилось проходить всю процедуру «выбора» каждый раз, когда вы добавляете его в документ)
  3. Также кэшируйте выпадающий список по тем же причинам.

Комментарии:

1. Большое спасибо за ваш ответ, я его реализовал, однако я не могу заставить его работать правильно, я создал jsFiddle, который вы можете увидеть здесь, jsfiddle.net/9f8Y2/2

Ответ №2:

Таким образом, вы можете фильтровать из списка все объекты, имеющие value свойство, равное 0:

 /**
 * Remove from a list all object having `obj.value` == value (ex. 0).
 *
 * @param {Object} value The value to avoid.
 * @param {Array:Object} A list of objects.
 * @return {Array:Object} The new filtered Array.-*emphasized text*
 */
function filterByValue(value, list) {
   var newlist = [],
       obj,
       max,
       i;

   for (i = 0, max = list.length; i < max; i  = 1) {
      obj = list[i];

      if (obj.value !== value) {
         newlist.push(obj);
      }
   }
}

var newList = filterByValue(0, list);
  

Теперь вам нужно отфильтровать свой select_options список (который представляет собой список списков):

 function filter_selectOptions(select_options) {
   var sortedOptions;
       max,
       i;

   for (var i = 0, max = select_options.length; i < max; i  = 1) {
      sortedOptions = select_options[i];
      sortedOptions = filterByValue(0, sortedOptions);             
   }
}
  

Затем вы должны добавить правильный options список к соответствующему select .

 var uls = document.getElementsByClassName("dropdown").
                  .getElementsByTagName("dd").
                  .getElementsByTagName("ul");

for (var i = 0, max = uls.length; i < max; i  = 1) {
   ul = uls[i];

   sortedOptions = sortedOptions[i];

   ul.innerHTML = '<li <a href="#"><span class="option">'  sortedOptions[i]['value']   '</span><span class="value">'   sortedOptions[i]['name']   '</span></a></li>';
}