Как сохранить правильное событие Javascript после использования cloneNode (true) - PullRequest
5 голосов
/ 27 августа 2008

У меня есть элемент формы, который содержит несколько строк ввода. Думайте о каждой строке как об атрибутах нового объекта, который я хочу создать в своем веб-приложении. И я хочу иметь возможность создавать несколько новых объектов в одном 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?

Ответы [ 6 ]

7 голосов
/ 12 октября 2008

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

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>
0 голосов
/ 19 октября 2008

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

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

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

0 голосов
/ 06 октября 2008

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

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

в функции:

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

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

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

0 голосов
/ 04 октября 2008

Я проверил это в 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>
0 голосов
/ 28 августа 2008

Вы можете попробовать клонирование с помощью метода innerHTML или смеси:

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

Также: я думаю, что cloneNode не клонирует события, зарегистрированные в addEventListener. Но события IEE attachEvent клонируются. Но я могу ошибаться.

0 голосов
/ 27 августа 2008

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

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

...