Перенос HTML-элементов из одного списка в другой с помощью Javascript - PullRequest
2 голосов
/ 14 ноября 2011

У меня проблема со следующей функцией Javascript. У меня есть два UL, и мне нужно, чтобы, когда пользователь нажимает на LI, этот элемент переносится на другой UL.

Мне удалось переместить их onClick из списка в другой, проблема возникает, когда я пытаюсь снова переместить LI, который ранее был в другом UL, когда это происходит, это просто не работает .. .

    function testList() {
    usersA = document.getElementById("users-a");
    usersB = document.getElementById("users-b");

    for (var i=0; i < usersA.getElementsByTagName("li").length; i++) {
        usersA.getElementsByTagName("li")[i].onclick = function() {
            transfer = this.cloneNode(true);
            usersB.appendChild(transfer);
            usersA.removeChild(this);
            return false;
        }

    }
    for (var i=0; i < usersB.getElementsByTagName("li").length; i++) {          
        usersB.getElementsByTagName("li")[i].onclick = function() {
            transfer = this.cloneNode(true);
            usersA.appendChild(transfer);
            usersB.removeChild(this);
            return false;
        }

    }

}

Я знаю, что моя логика отстой, но это все, что я мог придумать. Есть идеи, почему он работает при первом переносе LI, но когда я пытаюсь вернуться к исходному UL, он не работает?

Ответы [ 2 ]

4 голосов
/ 14 ноября 2011

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

Согласно MDN , .appendChild() удалитдочерний элемент от его текущего родителя, поэтому вам не нужно двухступенчатое клонирование / удаление, которое вы делаете в данный момент.Я не проверял это, но, возможно, используя только .appendChild(), он сохранит обработчики?Если это так, вам нужно удалить этот обработчик и назначить новый, чтобы разрешить, к какому списку он теперь принадлежит.

Или переписать ваши обработчики так, чтобы они проверяли, какой список является текущим родителем (посмотрите на .parentNode) и перейдите к списку прочее в зависимости от ситуации.

Принимая во внимание, что события щелчка «всплывают», начиная с целевого / исходного элемента и вплоть дородительская иерархия, вам, вероятно, лучше настроить обработчики щелчков на родительских элементах <ul>, а затем проверить, на каком <li> была нажата кнопка.Таким образом, вам не нужно беспокоиться об установке новых обработчиков кликов для новых дочерних <li> элементов.

function testList() {
   var usersA = document.getElementById("users-a"),
       usersB = document.getElementById("users-b");

   usersA.onclick = function(e) {
      // allow for the IE and non-IE way of handling the event object
      if (!e) e = window.event;
      var el = e.target || e.srcElement;

      if (el.tagName === "li") {
         usersB.appendChild(el);
      }
   }

   usersB.onclick = function(e) {
      // allow for the IE and non-IE way of handling the event object
      if (!e) e = window.event;
      var el = e.target || e.srcElement;

      if (el.tagName === "li") {
         usersA.appendChild(el);
      }
   }
}

Кроме того, если вы используете .getElementsByTagName(), называйте его один раз в инициализации цикла и присвойте результат переменной, затем используйте переменную - не продолжайте вызывать функцию снова и снова, чтобы проверить длину или получить доступ к отдельным элементам внутри цикла:

for (var i=0, lis = usersA.getElementsByTagName("li"); i < lis.length; i++) {
    lis[i].onclick = function() {
       // etc
    }
}
2 голосов
/ 14 ноября 2011

Проблема в том, что даже после того, как вы переместили элемент из списка A в список B, он все еще сохраняет свой старый обработчик onclick, который по-прежнему говорит «удалить меня из списка A и добавить меня в список B». Вам нужно изменить его обработчик onclick, чтобы сказать «удалить меня из списка B и добавить меня в список A». Вот один из способов исправить это:

var usersA = document.getElementById("users-a");
var usersB = document.getElementById("users-b");

var onclickA;
var onclickB = function() {
        usersA.appendChild(this);
        this.onclick = onclickA;
        return false;
    };
onclickA = function() {
        usersB.appendChild(this);
        this.onclick = onclickB;
        return false;
    };

for (var i=0; i < usersA.getElementsByTagName("li").length; i++)
    usersA.getElementsByTagName("li")[i].onclick = onclickA;
for (var i=0; i < usersB.getElementsByTagName("li").length; i++)      
    usersB.getElementsByTagName("li")[i].onclick = onclickB;

(Я также избавился от материала cloneNode, именно по тем причинам, которые дает nnnnnn.)

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