Есть ли какой-нибудь быстрый способ получить <option>из <select>по значению, используя JavaScript? - PullRequest
4 голосов
/ 07 ноября 2008

У меня есть

Вот подвох: есть тысячи вариантов, и мне нужно сделать это несколько сотен раз в цикле. Прямо сейчас я перебираю массив «options» и ищу нужный вариант. Это слишком медленно (в том смысле, что на моей очень быстрой машине браузер блокировался, пока я не убил его через несколько минут).

Есть ли более быстрый способ сделать это? Я выберу специфичные для браузера способы, но, конечно, было бы неплохо использовать стандарт DOM.

Ответы [ 8 ]

7 голосов
/ 07 ноября 2008

Я бы сделал это так:

// first, build a reverse lookup
var optCount      = mySelect.options.length;
var reverseLookup = {};
for (var i = 0; i < optCount; i++)
{
  var option = mySelect.options[i];
  if (!reverseLookup[option.value])
  {
    // use an array to account for multiple options with the same value
    reverseLookup[option.value] = [];
  }
  // store a reference to the DOM element
  reverseLookup[option.value].push(option);
}

// then, use it to find the option
var foundOptions = reverseLookup["Value that you are looking for"];
if (foundOptions && foundOptions.length)
{
  alert(foundOptions[0].id);
}
2 голосов
/ 07 ноября 2008

Я бы предложил не иметь тысячи вариантов на ваш выбор.

Возможно, вы могли бы структурировать свои данные по-разному, выбор с тысячами записей мне кажется неправильным.

Возможно, ваше приложение требует этого, но это не типичное использование этого элемента.

1 голос
/ 07 ноября 2008

Это ответ Томалака с небольшим изменением скорости. Вы видите, что цикл while с итерацией вниз выполняется быстрее, чем цикл for с итерацией вверх. (Мне лень, поэтому я не буду предоставлять ссылку.)

var i = mySelect.options.length - 1;
var reverseLookup = {};
while ( i >= 0 )
{
  var option = mySelect.options[i];
  if (!reverseLookup[option.value])
  {
    // use an array to account for multiple options with the same value
    reverseLookup[option.value] = [];
  }
  // store a reference to the DOM element
  reverseLookup[option.value].push(option);
  i--;
}

// then, use it to find the option
var foundOptions = reverseLookup["Value that you are looking for"];
if (foundOptions && foundOptions.length)
{
  alert(foundOptions[0].id);
}
0 голосов
/ 07 ноября 2008

Я думаю, что это может быть индикатором того, что «тысячи» предметов в избранном, вероятно, не лучший пользовательский опыт. Возможно, вам следует попробовать ограничить количество выпадающих списков несколькими, которые сужают результаты по мере их выбора пользователем.

0 голосов
/ 07 ноября 2008

Я бы посоветовал взглянуть на такой фреймворк / инструментарий, как Dojo и способ выбора узлов DOM .

Инструментарий устраняет многие несоответствия браузера и позволяет быстро и легко выбирать и управлять узлами DOM.

0 голосов
/ 07 ноября 2008

Вы можете просмотреть все параметры один раз и поместить все элементы в ассоциативный массив. Тогда вы можете просто искать myOptions[valueImLookingFor].

Я не проверял это и не могу гарантировать, что это будет быстрее / лучше. Но он должен избавиться от всех этих петель.

В зависимости от ваших настроек и потребностей вы также можете сгенерировать массив JavaScript на стороне клиента и поместить его в разметку вместо (или в дополнение к) выбора.

0 голосов
/ 07 ноября 2008

нет, нет, вы делаете это действительно наилучшим способом. Единственное, что вы можете попробовать, возможно, для более быстрого поиска, - дать каждому из параметров тег ID, чтобы вы могли искать их как объект DOM, а не циклически просматривать дочерние объекты объекта DOM.

0 голосов
/ 07 ноября 2008

С jQuery что-то вроде этого может быть быстрее:

$("#idselect option[value='yourval']")

http://docs.jquery.com/Selectors/attributeEquals#attributevalue

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...