Как сохранить правильное событие Javascript после использования cloneNode(true)

StackOverflow https://stackoverflow.com/questions/29624

Вопрос

У меня есть элемент формы, который содержит несколько строк ввода.Рассматривайте каждую строку как атрибут нового объекта, который я хочу создать в своем веб-приложении.И я хочу иметь возможность создавать несколько новых объектов в одном HTTP POST.Я использую встроенный в Javascript метод cloneNode(true) для клонирования каждой строки.Проблема в том, что каждая строка ввода также имеет ссылку на удаление, прикрепленную к событию onclick:

// prototype based
<div class="input-line">
    <input .../>
    <a href="#" onclick="$(this).up().remove();"> Remove </a>
</div>

При нажатии на ссылку удаления клонированной строки ввода также удаляются все строки ввода, которые были клонированы из того же объекта dom.Можно ли повторно привязать объект «this» к соответствующему тегу привязки после использования cloneNode(true) в вышеуказанном элементе DOM?

Это было полезно?

Решение

Не помещайте обработчик на каждую ссылку (кстати, это действительно должна быть кнопка).Использовать всплеск событий обрабатывать все кнопки с одним обработчиком:

formObject.onclick = function(e)
{
    e=e||event; // IE sucks
    var target = e.target||e.srcElement; // and sucks again

    // target is the element that has been clicked
    if (target && target.className=='remove') 
    {
        target.parentNode.parentNode.removeChild(target.parentNode);
        return false; // stop event from bubbling elsewhere
    }
}

+

<div>
  <input…>
  <button type=button class=remove>Remove without JS handler!</button>
</div>

Другие советы

Вы можете попробовать клонировать, используя метод InnerHTML или его комбинацию:

var newItem = $(item).cloneNode(false);
newItem.innerHTML = $(item).innerHTML;

Также:Я думаю, что cloneNode не клонирует события, зарегистрированные с помощью addEventListener.Но события AttachEvent в IE являются клонированный.Но я могу ошибаться.

Я тестировал это в IE7 и FF3, и все работало, как и ожидалось — должно быть что-то еще.

Вот мой тестовый сценарий:

<div id="x">
    <div class="input-line" id="y">
        <input type="text">
        <a href="#" onclick="$(this).up().remove();"> Remove </a>
    </div>
</div>

<script>

$('x').appendChild($('y').cloneNode(true));
$('x').appendChild($('y').cloneNode(true));
$('x').appendChild($('y').cloneNode(true));

</script>

Чтобы отладить эту проблему, я бы обернул ваш код

$(this).up().remove()

в функции:

function _debugRemoveInputLine(this) {
    debugger;
    $(this).up().remove();
}

Это позволит вам узнать, что возвращает $(this).Если он действительно возвращает более одного объекта (несколько строк), то вы определенно знаете, где искать — в коде, который создает элемент с помощью cloneNode.Вносите ли вы какие-либо изменения в результирующий элемент (т.изменение атрибута id)?

Если бы у меня возникла проблема, которую вы описываете, я бы рассмотрел возможность добавления уникальных идентификаторов к триггерному элементу и элементу «линия».

Первый ответ правильный.

Порнель неявно предлагает наиболее кроссбраузерное и независимое от фреймворка решение.

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

Похоже, вы используете jQuery?У него есть метод клонирования элемента с событиями: http://docs.jquery.com/Manipulation/clone#true

РЕДАКТИРОВАТЬ:Упс, я вижу, вы используете Prototype.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top