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


Автор: fater 27.8.2008, 19:23
Всем привет, буду очень рад вашей помощи.
Предо мной встала задача замены нодов тега LI

Вот такой код HTML:
Код

<ul>
<li id="menu_item_id_1"><a href="javascript://" onclick="edit_item (this, 'down');">Пункт 1</a></li>
<li id="menu_item_id_2"><a href="javascript://" onclick="edit_item (this, 'down');">Пункт 2</a></li>
<li id="menu_item_id_3"><a href="javascript://" onclick="edit_item (this, 'up');">Пункт 3</a></li>
</ul>


Необходимо при нажатии на ссылу в ноде, менять местами с элементом стоящим ниже, если в параметре функции указано значение 'down', иначе менять местами с верхним. Заблудился и запарился как это делать. вот мои наработки:

Код

function edit_item (obj, move)
{
        obj = obj.parentNode;
        if (move == 'down')
        {
            clone = obj.cloneNode (true);
            obj.appendChild (clone);
            next = obj.nextSibling;
            obj.replaceChild (next, obj);
//            obj.parentNode.insertBefore (obj, next);
        }
    }


Я решил попробовать методом:
- Клонировать нажатый нод (1, сделать 1,2)
- Заменить нажатый на тот (1 заменяем на 3), который стоял ниже его, перед клонированием
- и удалить клонированый нод

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

Автор: АндрейМиндубаев 27.8.2008, 21:30
fater, так вроде бы работает:
Код

function edit_item (obj, move) {
  obj = obj.parentNode;
  if (move == 'down') {
    var next = obj.nextSibling;
    while (next && next.nodeType != 1)
      next = next.nextSibling;
    if (next)
      obj.parentNode.insertBefore(next, obj);
  }
  else if (move == 'up') {
    // ...
  }
}

Автор: fater 28.8.2008, 00:34
Цитата(АндрейМиндубаев @ 27.8.2008,  21:30)
fater, так вроде бы работает:
Код

function edit_item (obj, move) {
  obj = obj.parentNode;
  if (move == 'down') {
    var next = obj.nextSibling;
    while (next && next.nodeType != 1)
      next = next.nextSibling;
    if (next)
      obj.parentNode.insertBefore(next, obj);
  }
  else if (move == 'up') {
    // ...
  }
}

Привет, АндрейМиндубаев
ух ты, работает.. Я благодарю за столь быстрый ответ и помощь мне...
Я кстати сегодня почти так же делал по примерам, но у меня не корректно работало.
Я вот смотрю все просто, но так до конца и не могу понять зацем там цикл...

Если не сложно, можешь хотя бы в кратце описать алгоритм, т.е. что делает какая строчка. чтобы понятно было уже без сомнений.
Огромное спасибо!  smile 

Автор: Hades 28.8.2008, 01:14
Предложу свой вариант
Код

<ul id="rfg">
    <li id="menu_item_id_1"><a href="javascript:void(0);" onclick="editItem(this);">Пункт 1</a></li>
    <li id="menu_item_id_2"><a href="javascript:void(0);" onclick="editItem(this);">Пункт 2</a></li>
    <li id="menu_item_id_3"><a href="javascript:void(0);" onclick="editItem(this);">Пункт 3</a></li>
    <li id="menu_item_id_4"><a href="javascript:void(0);" onclick="editItem(this);">Пункт 4</a></li>
</ul>
    
<script type="text/javascript">
    function editItem(item, move) {
        var first = item.parentNode;
            
        var list = document.getElementById('rfg');
        var listItems = list.getElementsByTagName('li').length;
        var lastListItemsID = list.getElementsByTagName('li')[listItems-1].id;
        var second = (lastListItemsID == first.id) ? first.previousSibling : first.nextSibling;
            
        var cloneItemFirst = first.cloneNode(true);
        var cloneItemSecond = second.cloneNode(true);
            
        list.replaceChild(cloneItemFirst, second);
        list.replaceChild(cloneItemSecond, first);
    }
</script>

Автор: SelenIT 28.8.2008, 05:37
Цитата(fater @  28.8.2008,  00:34 Найти цитируемый пост)
зацем там цикл...

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

Hades, по-моему, 2 замены тут ни к чему совершенно. Вариант АндреяМиндубаева с insertBefore - самое то для такой задачи, манипулируем уже имеющимися элементами, не плодя левых сущностей (клонов и т.п.).

Автор: fater 28.8.2008, 10:03
Всем привет. Спасибо за помощь.
У меня все это заработало. правда на ФФ.
На опере и неИЕбраузере не тестил.

Приведу код, уже с изменениями, для движения в верх и низ НОДа.
Сделал вызов функции по ID из другой части документа, не нажимая на ссылки. получился вот такой код:
(Мне именно это нужно было)

Код

    function edit_item (item_id, move)
    {
        obj = $('menu_item_id_' + item_id);
        if (move == 'down')
        {
            var next = obj.nextSibling;
            while (next && next.nodeType != 1)
                next = next.nextSibling;
            if (next)
                obj.parentNode.insertBefore (next, obj);
        }
        else if (move == 'up')
        {
            var prev = obj.previousSibling;
            while (prev && prev.nodeType != 1)
                prev = prev.previousSibling;
            if (prev)
                obj.parentNode.insertBefore (obj, prev);
        }
    }


 smile  smile 
Спасибо: SelenIT, Hades, АндрейМиндубаев

Автор: Hades 28.8.2008, 12:37
Цитата(SelenIT @  28.8.2008,  05:37 Найти цитируемый пост)
Hades, по-моему, 2 замены тут ни к чему совершенно. Вариант АндреяМиндубаева с insertBefore - самое то для такой задачи

согласен, тут я перемудрил

но меня только одно смущает, хотя может быть автор это и хотел сделать,
когда меняется предпоследний элемент и последний элемент, получится так что у предпоследнего элемента 'move' будет указывать в верх, а у последнего в низ.

Автор: fater 28.8.2008, 21:11
Цитата(Hades @ 28.8.2008,  12:37)
Цитата(SelenIT @  28.8.2008,  05:37 Найти цитируемый пост)
Hades, по-моему, 2 замены тут ни к чему совершенно. Вариант АндреяМиндубаева с insertBefore - самое то для такой задачи

согласен, тут я перемудрил

но меня только одно смущает, хотя может быть автор это и хотел сделать,
когда меняется предпоследний элемент и последний элемент, получится так что у предпоследнего элемента 'move' будет указывать в верх, а у последнего в низ.

Привет, Hades

Задача полностью решена.
А вот на счет последнего мува сейчас объясню..
С начала нажимается на ссылку в элементе LI
Затем, в специальном диве выводятся свойства LI и последовательность этих полей. Порядок берется из БД.
Ну и соответственно в этом ДИВе определяется стрелка движения вниз или вверх по ID.

Надеюсь объяснил доходчиво.
Но все же благодарю за столь активную помощь  smile 

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