JQuery добавить, а затем удалить

Скрипт: http://jsfiddle.net/YbfZG/4/ По какой-то причине функции toggleDiv/removeDiv не работают (я мало использовал jsfiddle), но, надеюсь, это даст вам лучшее представление о том, чего я пытаюсь достичь.

У меня есть страница, на которой пользователи могут динамически добавлять элементы (div), выбирая из раскрывающегося списка. Это достигается с помощью .append(). Они также могут удалить элемент (.remove()) и, возможно, повторно добавить его. Каждый div содержит область скрытия/отображения, активируемую нажатием на ссылку.

При первом добавлении div на страницу область скрытия/отображения работает нормально. Если один и тот же div удаляется, а затем снова добавляется, скрытие/отображение больше не работает. Я полагаю, это связано с тем, что div не полностью удаляется из DOM, поэтому функция скрытия/отображения, которая работает на основе идентификаторов, не может найти правильный div для работы.

Я попытался изменить свою функцию удаления на $(this).empty().remove(); но это не сработало. Я также пытался использовать отключение, но функциональность не изменилась. Я немного почитал, и мне потенциально нужно использовать .on(), но я не уверен, как это структурировать.

ETA: код добавления и переключения и измененное имя div, чтобы оно не было исключительно числовым (опечатка с моей стороны).


person shimmoril    schedule 16.10.2012    source источник
comment
Недостаточно информации, чтобы помочь вам. Вы также должны показать нам код, который добавляет div. Лучше всего вам собрать скрипку, вы наверняка получите ответ, который вам поможет.   -  person Adriano Carneiro    schedule 16.10.2012
comment
Какой код для вашего скрытия/шоу?   -  person ninja    schedule 16.10.2012
comment
Если вы не используете html5, числовые значения id недействительны.   -  person James Montagne    schedule 16.10.2012
comment
@JamesMontagne - Да, это была опечатка. Исправлена.   -  person shimmoril    schedule 16.10.2012


Ответы (4)


Будет проще, если вы измените разметку на:

<div id="8" class="wrapper">
    <div>
    <a title="Remove" class="remove" href="#">Remove</a>
    </div>
</div>

(в основном я добавил класс «обертки» в основной div и класс «удалить» в ссылку удаления)

Таким образом, вы избавитесь от атрибута onclick и вместо этого будете использовать простую функцию:

$('body').on('click','a.remove',function(){
    $(this).closest('div.wrapper').remove();
});​

Демо


Учитывая ваш полный код, вот как заставить его работать (демонстрация):

$(function() {

    $('.elements').on('click', '.remove', function() {
        $(this).closest('div[id^=div]').remove();
    });

    $('.elements').on('click', '.open-close', function() {
        var hideShowN = $(this).closest('div[id^=div]').attr('id').replace(/\D/g,'');
        $('#hide_show_'+hideShowN).toggle();
    });

    $('.add').on('click', function() {
        $('.elements').append('<div id="div_8">Element<a class="open-close" href="#" title="Open/Close">Open/Close</a><div id="hide_show_8" style="display: none;">Stuff</div><a class="remove" href="#" title="Remove">Remove</a></div>');
    });

});​
person Giona    schedule 16.10.2012
comment
Я думаю, что closest немного чище, чем parents. - person James Montagne; 16.10.2012
comment
Это правильный комментарий, но это не ответ на вопрос ОП. - person Adriano Carneiro; 16.10.2012
comment
Верно, поэтому я и сказал чище. Оба будут работать, но нет необходимости продолжать поиск дополнительных совпадений в DOM, если вам нужен только один. В итоге небольшая разница. - person James Montagne; 16.10.2012
comment
Это не будет работать для элементов, которые добавляются динамически. Вам нужно написать его как $('#container').on('click', 'a.remove', function()...) для правильного делегирования. - person Barmar; 16.10.2012
comment
@GionaF - я ценю более чистый код и, вероятно, буду использовать его, как только эта проблема будет решена, но мои области скрытия/отображения по-прежнему не работают после внесения ваших изменений. - person shimmoril; 16.10.2012
comment
Каковы ваши области скрытия / показа @shimmoril ? не могли бы вы сделать скрипку - person Giona; 16.10.2012
comment
@GionaF - Скрипт добавлен выше. - person shimmoril; 16.10.2012
comment
@GionaF - спасибо, похоже, это решит проблему. Одна последняя загвоздка - когда нажимается ссылка скрыть/показать, я действительно хотел бы изменить отображаемое изображение. Раньше я делал это, передавая imageID функции toggleDiv, но я не уверен, как интегрировать это с вашими изменениями. Изображение находится внутри тега Open/Close a. - person shimmoril; 16.10.2012
comment
@GionaF - Извините, у меня есть еще один вопрос. В моем примере кода я использовал _8 для идентификаторов, что в основном является заполнителем. Каждый элемент будет иметь свой собственный идентификационный номер (хотя удаленные/повторно добавленные элементы будут иметь один и тот же идентификатор). Ваш код учитывает это? - person shimmoril; 16.10.2012
comment
@shimmoril да, это принято во внимание. Не в обработчике .add, вам придется разобраться. Но для открытия/закрытия у вас есть эта переменная: var hideShowN которая возвращает числовую часть вашего идентификатора div - person Giona; 16.10.2012

Я бы посоветовал вам использовать прослушиватели при использовании jQuery, это чище и часто проще.

Я сделал jsfiddle с тем, что, как мне кажется, вам нужно. Проверьте это здесь: http://jsfiddle.net/YbfZG/2/.

Что важно в этом примере, так это то, что слушатель, который удаляет элементы, прослушивает div «элементы», а не кнопку удаления. Когда прослушиватель срабатывает, ТОГДА он проверяет, был ли щелчок внутри ".element .remove", и если да, то он выполняет функцию.

Это важно, потому что, если вы поместите прослушиватель непосредственно в «.element .remove», это приведет к сбою для вновь добавленных классов с помощью кнопки «Добавить», потому что они были добавлены после того, как jQuery добавил слушателей.

person gitaarik    schedule 16.10.2012
comment
Другими словами, делегируйте событие click элементу-предку и проверьте, от какого потомка оно произошло. - person aziz punjani; 16.10.2012
comment
Именно, это очень важно при работе со слушателями на динамически создаваемых элементах. - person gitaarik; 16.10.2012
comment
Я ценю скрипку, но, поскольку вы добавляете новые элементы, это не совсем то же самое, что и моя проблема. - person shimmoril; 16.10.2012
comment
Если вы используете такие же слушатели для своей функции скрытия / показа, я думаю, ваша проблема должна быть решена. - person gitaarik; 16.10.2012

У меня была похожая проблема раньше. Я считаю, что это было вызвано тем же самым. Проблема в том, что вам нужно перепривязать обработчик кликов при удалении/чтении div. Что я делаю, так это создаю функцию, которая связывает обработчик, и я вызываю ее всякий раз, когда возникает ситуация, подобная этой, когда элемент добавляется/удаляется из DOM.

Удачи

person OneChillDude    schedule 16.10.2012

Используйте .detach вместо удаления, чтобы сохранить привязки событий. Цитата из документов.

Метод .detach() аналогичен .remove(), за исключением того, что .detach() сохраняет все данные jQuery, связанные с удаленными элементами. Этот метод полезен, когда удаленные элементы должны быть повторно вставлены в DOM позднее.

person aziz punjani    schedule 16.10.2012
comment
Следует отметить, что для этого потребуется сохранить ссылку на элемент, чтобы тот же элемент был повторно добавлен. Это не сработает, если элементы будут созданы заново. К сожалению, мы не можем знать, так как вопрос не включает этот код. - person James Montagne; 16.10.2012
comment
Как отмечалось ранее, я попытался отсоединить, и это не сработало. Кроме того, учитывая требования этого проекта, я не хочу управлять тысячами добавленных и удаленных элементов div. Спасибо хоть. - person shimmoril; 16.10.2012