Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > сортировка списка


Автор: kizune 23.10.2007, 16:03
Здравствуйте,все.
проблема такая:есть список
Код

<a href="#sort">sort</a>
<ul>    
    <li>ccc</li>
    <li>bbbb</li>
    <li>ddd</li>
    <li>aaaa</li>
</ul>

при клике на ссылку должна осуществляться сортировка списка по алфавиту.
можно ли как-то воспользоваться этим методом?
Код

function cmp(a, b) 
        {
          if (a > b)
          {
            return 1;
           }
          if (a < b)
           { return -1;
           }
          return 0;  
        }


если да,то как загнать в массив значения li?
а если нет,каким способом посоветуете воспользоваться?
заранее спасибо.   smile 

Автор: dsCode 23.10.2007, 16:34
kizune, 
Цитата(kizune @  23.10.2007,  16:03 Найти цитируемый пост)
можно ли как-то воспользоваться этим методом?

можно, почему нельзя? Так Вам же надо будет потом проапдейтить и html (т.е. отобразить элементы списка "по-новому"). Можно попробовать так:

- собрать все элементы в объект
- воспользоваться стандартной для объектов функцией sort(...), параметром которой передать Вашу функцию cmp(...) (т.е. критерий соритировки для sort(...))
- обновить html на основе отсортированного объекта (либо обновить innerHTML у <li>, либо уничтожить старые <li> и создать новые)

Автор: GIK 23.10.2007, 16:49
Помню писал сам на С++, там все просто было, просто сравнивал символ и использовал два массива, время будет попробую сделать на JS smile 

Автор: kizune 23.10.2007, 17:02
не получается,может я какой момент упускаю?

Код

<script language="javascript" type="text/javascript">
function sorting()
{
var array = document.getElementById('Sort').innerHTML;

        function cmp(a, b) 
        {
          if (a > b)
          {
            return 1;
          }
          if (a < b)
          { 
              return -1;
          }
          return 0;  
        }
 document.getElementById('Sort').innerHTML = array.sort(cmp);       
}
</script>
<a href="#sort" onclick="sorting()">sort</a>
<ul id="Sort">    
    <li>ccc</li>
    <li>bbbb</li>
    <li>ddd</li>
    <li>aaaa</li>
</ul>

Автор: SelenIT 23.10.2007, 17:35
Цитата(kizune @  23.10.2007,  16:03 Найти цитируемый пост)
можно ли как-то воспользоваться этим методом?

Для алфавитной сортировки не нужно - она по умолчанию.

Цитата(kizune @  23.10.2007,  17:02 Найти цитируемый пост)
может я какой момент упускаю?

Упускаете: innerHTML - не массив, поэтому не имеет метода sort().

Предлагаю вариант средствами DOM (проход циклом по элементам <li> внутри списка, создание массива текстов и словаря текст-элемент, сортировка массива текстов и перестройка порядка элементов по отсортированному массиву с помощью словаря):
Код

<a href="#sort" onclick="listSort(document.getElementsByTagName('ul')[0])">sort</a>
<ul>    
    <li>ccc</li>
    <li>bbbb</li>
    <li>ddd</li>
    <li>aaaa</li>
</ul>
<script>
function listSort(list) {
   var items = list.getElementsByTagName('li'), tmp = [], index = {};
   for (var i=0; items[i]; i++) {
      tmp[i] = items[i].firstChild.nodeValue;
      index[tmp[i]] = items[i];
   }
   tmp.sort();
   for (var i=0; tmp[i]; i++) list.appendChild(index[tmp[i]]);
}
</script>

Конечно, это решение не идеально (в частности, никак не оптимизировано кол-во перестановок элементов), но для небольшого списка, имхо, вполне сгодится...

Автор: Castro 26.10.2007, 16:08
Хорошее решение

Автор: kizune 29.10.2007, 10:17
спасибо большое. smile 
а как быть если список большой,элементов этак на двадцать?

Автор: SelenIT 29.10.2007, 12:57
kizune, с двадцатью, имхо, проблем и так не будет. Проверил на списке в 94 строки - на пятилетней машине (Duron-1200) сортирует за <20 мс в IE и Опере, за 60-70 - в FF. Вот уже для нескольких сотен надо всерьез думать об оптимизации...

Автор: kizune 29.10.2007, 13:18
ясно,благодарю.последний вопрос если список будет таким
Код

<ul>
<li><a href="#">ccc</a></li>
    <li><a href="#">bbbb</a></li>
    <li><a href="#">ddd</a></li>
    <li><a href="#">aaaa</a></li>
<ul>

т.е если добавить в него ссылки,надосделать еще один цикл,который будет проходить сначала по <li>,а потом по <a>?

Автор: SelenIT 29.10.2007, 13:35
kizune, нет, цикл останется тот же. Надо будет только изменить строку 
Код

      tmp[i] = items[i].firstChild.nodeValue;
т.к. сейчас она ищет текст (текстовую ноду) непосредственно в самом <li>. Наверное, лучше и универсальнее всего будет заменить эту строку на
Код

      tmp[i] = items[i].innerText||items[i].textContent; // первое - для IE, второе - для прочих

чтобы сортировка шла по текстовому содержимому <li> вне зависимости от тегов внутри него...

Автор: kizune 29.10.2007, 13:42
спасибо,спасибо,спасибо smile 

Автор: SelenIT 29.10.2007, 13:47
Всегда пожалуйста smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)