Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Не срабатывает click (https://javascript.ru/forum/dom-window/73296-ne-srabatyvaet-click.html)

Эдди 04.04.2018 17:50

Не срабатывает click
 
Замылились глаза или мозги. Вообще плохо знаю JS.

Загружаю картинки на сервер.
В конце загрузки вывожу в <div> загруженные изображения.
Рядом с каждой картинкой выводится картинка "Удалить"

<div class="img-reply" id="img-reply"></div>

(function($){    
//загрузка файлов

img_name += '<br><img style="max-width: 500px; height: auto" src="/catalog/controller/extension/module/comment_img-uploads/product_id_' + product_id + '/' + fileName(val) + '">&nbsp;&nbsp;&nbsp;<img id="delfile" src="/image/review/delete.png" width="20" height="20" alt="Удалить" />';

$('.img-reply').html( img_name );

})(jQuery)


Если в теге картинки "Удалить" пишу onclick="alert('тра-ля-ля')", работает.

А так не работает:
<script> 
    $(function() {
            $('#delfile').click(function() {
                alert('Тра-ля-ля');
            });
    })
</script>


Вообще где эта функция должна находиться?
В новой оболочке jquery? Внутри той же функции?
Что я делаю не так?

laimas 04.04.2018 18:03

Удалить что?

Эдди 04.04.2018 18:06

Цитата:

Сообщение от laimas (Сообщение 482294)
Удалить что?

Только что загруженную и выведенную на страницу картинку.
В принципе, как удалить, я знаю. Но не захватывается событие клик, чтобы функцией jquery удалить файл и картинку со страницы.

Dilettante_Pro 04.04.2018 18:21

Эдди,
И у всех картинок "Удалить" id="delfile" ?

laimas 04.04.2018 18:23

Цитата:

Сообщение от Эдди
Только что загруженную и выведенную на страницу картинку.

Картинку загруженную на сервер (не видно самой загрузки) нельзя удалить на клиенте, для этого нужно делать запрос на сервер. Но какой тогда смысл в такой загрузке?

А предпросмотр загруженного, то что отображено на клиенте, это удалить можно.

Если пердпросмотр это <div class="img-reply" id="img-reply"></div>, то ('#img-reply').empty()

j0hnik 04.04.2018 18:25

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<img src="https://javascript.ru/forum/images/ca_serenity/misc/logo.gif" alt="" class="img"> <img src="" alt="Удалить"><br>
<img src="https://javascript.ru/forum/images/ca_serenity/misc/logo.gif" alt="" class="img"> <img src="" alt="Удалить"><br>
<img src="https://javascript.ru/forum/images/ca_serenity/misc/logo.gif" alt="" class="img"> <img src="" alt="Удалить"><br>
<script> 
    $(function() {
            $('[alt="Удалить"]').click(function() {
                $(this).prev('.img').remove();
            });
    })
</script>

	</script>
</body>
</html>

laimas 04.04.2018 18:27

j0hnik,
это видимо кнопка вызова операции удаления.

Эдди 04.04.2018 18:47

Цитата:

Сообщение от laimas (Сообщение 482303)
j0hnik,
это видимо кнопка вызова операции удаления.

Да. Но в данный момент удаление/не удаление не играет роли. Почему не откликается на алерт?

Эдди 04.04.2018 18:48

j0hnik,
Ай спасибо!!! Ща буду пробовать.

А в чем у меня была ошибка?

И еще. Удалить надо не только картинку, но и "кнопку" удалить рядом с этой картинкой.
В див вставить и див удалить?

j0hnik 04.04.2018 18:50

Эдди,
предполагаю, что на момент выполнения данного кода

$('#delfile').click(function() {
     alert('Тра-ля-ля');
});


кнопки на странице еще нет, и обработчик не вешается.

laimas 04.04.2018 18:51

Ошибки значит есть, в самом обработчике их нет. Консоль подскажет.

Эдди 04.04.2018 19:03

Цитата:

Сообщение от j0hnik (Сообщение 482308)
Эдди,
предполагаю, что на момент выполнения данного кода

$('#delfile').click(function() {
     alert('Тра-ля-ля');
});


кнопки на странице еще нет, и обработчик не вешается.

Да, наверное. Load надо было делать.

j0hnik 04.04.2018 19:06

Эдди,
Обработчик вешать колбек функцией.
Или
Вешать обработчик на родителя, выполнять проверку на нужный элемент.

laimas 04.04.2018 19:07

Цитата:

Сообщение от Эдди
Load надо было делать.

А он причем? Даже пустое изображение будет иметь событие.

Вы не поясняете как делаете, и когда с ... А коли все это у вас динамически добавляется на страницу, то не Load, а либо делегирование обработки события, либо установка обработчика после добавления элемента на страницу.

laimas 04.04.2018 19:08

Цитата:

Сообщение от j0hnik
выполнять проверку на нужный элемент.

В JQ в этом нет необходимости, в методе все уже имеется.

Эдди 04.04.2018 19:10

Цитата:

Сообщение от laimas (Сообщение 482312)
А он причем? Даже пустое изображение будет иметь событие.

Вы не поясняете как делаете, и когда с ... А коли все это у вас динамически добавляется на страницу, то не Load, а либо делегирование обработки события, либо установка обработчика после добавления элемента на страницу.

Да. Динамически добавляются сама картинка и картинка "Удалить".

"делегирование обработки события"??? Говорил, JS использую только по мере необходимости.:-/

laimas 04.04.2018 19:22

Эдди,
если по полной, то в вашем коде напрочь отсутствует логика.

Допустим - имеется исходный код: поле выбора файла, бокс куда будет помещаться предпросмотр и кнопка "Отменить", именно Отменить, а не Удалить, ибо нет у вас никакого удаления.

Загрузка файлов при этом асинхронная. Допустим - выбираем файл и грузим на сервер. Если нет ошибок, то по ответу сервера поле очищается и очищается бокс предпросмотра. Все, можно выбирать другой файл этим же набором элементов. Если хотим отказаться от загрузки щелкаем Отметить. Никакого делегирования не требуется.

А если клонируем этот набор, это уже динамическое добавление элементов. В остальном поведение может быть таким же.

Встает вопрос - а зачем так много наборов, если можно все делать одним? Если предполагается, что сперва набираем, а уже множество файлов загружаем (а не видно по вопросам чтобы это было так), тогда да. Но почему при удачной загрузке файлов нужно щелкать кнопки удаляя вручную отработанные наборы?

Эдди 05.04.2018 07:56

Цитата:

Сообщение от laimas (Сообщение 482315)
ЭддиНо почему при удачной загрузке файлов нужно щелкать кнопки удаляя вручную отработанные наборы?

Логика у меня такая (поправьте, если можно лучше).
Клиент хочет загрузить несколько изображений на сайт.
Он их именно сразу загружает, а не просто выводит для просмотра.
Сразу же после загрузки клиент видит на странице уменьшенные уже загруженные на сервер картинки. И если вдруг передумал какую-то из них оставлять, то удаляет ее и конкретно ее.

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

laimas 05.04.2018 12:24

Предпросмотр загружаемого в рамках HTML5 можно организовать и до загрузки изображения на сервер.

Но пусть ваши картинки, это не предпросмотр, а что уже загрузилось, что в общем то можно и не делать, если это можно и на клиенте сделать.

Загрузка изображения на сервер, как впрочем и любого файла не обязательно успех и сразу, возможны ошибки загрузки. Значит это еще требует обработки. Пусть в этом вопросе у вас все как положено, но если "удалить после загрузки", то вообще не понятно как же вы удаляете их:

1) Должен быть запрос на сервер на удаление фото по параметрам которые должен возвращать сервер.
2) Клиент не имеет права удалять картинку на клиенте пока сервер не даст положительного ответа - изображение удалено.

Эдди 05.04.2018 12:31

Собираюсь удалять с сервера файлы ajax-запросом.

А это как делается?
"установка обработчика после добавления элемента на страницу"

laimas 05.04.2018 12:46

Цитата:

Сообщение от Эдди
А это как делается?

В этом плане больше вопросов будет к вам, ибо "удалять с сервера файлы ajax-запросом" никак не получится, клиент только инициализирует запрос, асинхронный ли он или нет, это не важно, а удалять будет сервер. Но чтобы серверу знать что удалить, ему нужны параметры запроса. Картинок то на сервере много, и они ведь не валяются как бесхозные, а кому-то принадлежат, и эта принадлежность как связи тоже где-то на сервере может быть описана (а по уму именно так и делается). То есть, не просто удалить фото, но и связи по этому фото.

А значит успешная загрузка сервером фото, это возврат клиенту информации о том, как это фото идентифицируется на сервере, чтобы по этим параметрам можно было сделать запрос на корректное удаление фото и прочего с ним связанного.

Эдди 05.04.2018 13:05

Цитата:

Сообщение от laimas (Сообщение 482392)
Но чтобы серверу знать что удалить, ему нужны параметры запроса.

Ясно, что это так. А я и передаю параметры запроса.
В качестве id или class могу использовать, в частности, название файла, который надо удалить, которое получаю в первом запросе ajax.
В качестве папки, из которой удалить, я указываю product_id.
Разве не так?

Указываю серверному сценарию, в какую папку сохранить
$.ajax({
  		url         : '/catalog/controller/extension/module/comment_img-upload.php?product_id=' + product_id,


Указываю, какую картинку удалить, предварительно вырезав имя файла из пути
img_name += '<br><img style="max-width: 500px; height: auto" src="/catalog/controller/extension/module/comment_img-uploads/product_id_' + product_id + '/' + fileName(val) + '">&nbsp;&nbsp;&nbsp;<img id="' + fileName(val) + '" src="/image/review/delete.png" width="20" height="20" alt="Удалить" />';


А вопрос был лишь в том, как отловить клик после динамической загрузки картинки.

laimas 05.04.2018 13:19

Цитата:

Сообщение от Эдди
В качестве id или class могу использовать, в частности, название файла, который надо удалить, которое получаю в первом запросе ajax. В качестве папки, из которой удалить, я указываю product_id.

Коли product_id, будем считать, что это добавление фото товару. В этом случае клиент может знать ID товара (product_id), но если id, которое "в качестве", это id добавленного фото, то оно будет известно только после загрузки фото и его связывании с товаром, то есть с product_id, то есть возвращать это клиенту. О чем я и говорил, и эти параметры и могут служить запросом для удаления. Имя тоже можно использовать, если знаем его и каталог, в котором фото находится. Все зависит от того как хранятся и связываются эти данные на сервере, чего я не знаю. А вот имя класса к данному процессу отношения не имеет.

Цитата:

Сообщение от Эдди
предварительно вырезав имя файла из пути

Если знаем путь /catalog/controller/extension/module/comment_img-uploads/product_id_' + product_id + '/, что удобно не писать помногу раз, а определить единожды, а успешная загрузка означает возврат сервером имени файла (не понятно тогда как при этом ошибки возможные обрабатываются), то можно ли обойтись без "вырезки"?

Но как бы вы не формировали запрос на удаление, картинку на клиенте можно удалять только тогда, когда сервер ответил - удалено.

Эдди 05.04.2018 13:45

laimas
А если забыть ВСЕ, о чем говорилось до сих пор. И взять только это:

На страницу динамически ajax-ом в цикле выводятся картинки".
У каждой есть свой конкретный id.

Как при клике по картинке вывести алерт "Hello! World." Отдельной функцией, а не вставкой динамического onclick в каждую картинку.
Поэтому я спросил, как повесить на картинку событие уже после ее динамической загрузки.

Вот вопрос. :)

P.S. Когда картинка изначально присутствует на странице - нет проблем. Когда динамически - проблема

Все тут.

laimas 05.04.2018 13:58

Цитата:

Сообщение от Эдди
А если забыть ВСЕ, о чем говорилось до сих пор.

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

Уж если говорить в контексте вашего добавления, то сначала это добавление, а удачный результат его, это уже редактирование. И если в первом случае (допустим каждое фото добавляется своим полем), это кнопка Добавить со своим обработчиком, а во втором случае, это уже кнопка Удалить, со своим обработчиком.

Если такая реализация, то выгодно делегировать обработку кнопок Добавить/Удалить общему родителю, который гарантировано есть на странице.

Либо - сервер ответил, что добавил. Клиент сформировал url к картинке, добавил ее на страницу и кнопку Удалить, которой устанавливается и обработчик.

И никаких проблем нет ни для первого случая, ни для второго.

Эдди 05.04.2018 19:20

"делегировать обработку кнопок Добавить/Удалить общему родителю"...
---
В таком случае нужно просто нумеровать id картинки (0-1-2-3 и т.д.) и при прокрутке массива тоже использовать for с нумерацией.
Иначе, если делегировать родительскому элементу, то какие либо присваиваемые id тоже будут динамическими, и все останется по прежнему плохо. Так:?

Эдди 05.04.2018 19:20

~~~ Сказал, не проверив. Пардон.

Эдди 05.04.2018 20:43

Последний, наверное, вопрос.
Если явно задать id картинки и использовать метод on, то нормально.
$('body').on('click', '#abc', function(){
      alert('adfasdf');
  });

А если id картинки формируется динамически, то как в эту функцию вставить вместо '#abc' переменную?

laimas 05.04.2018 22:28

Цитата:

Сообщение от Эдди
Если явно задать id картинки и использовать метод on, то нормально.

Нет не нормально, я уж думал, что "~~~ Сказал, не проверив.", это о том, что есть понимание того, что "нужно просто нумеровать id картинки (0-1-2-3 и т.д.)", это просто зло усугубляющее ситуацию.

Каким образом банальная нумерация чего либо может иметь отношение к идентификации объекта?

Что в вашем случае является уникальным идентификатором загруженного на сервер фото? Нужно ли для каждой кнопки Удалить писать свой отдельный обработчик и отдельный запрос к индивидуальному серверному сценарию, или достаточно иметь один обработчик, один запрос отличающийся параметром, к одному сценарию?

Второе же ведь, о чем вы выше и пишите, и описываете код, тогда откуда могут рождаться мысли о вредном в данном случае - атрибуте id?

Пусть у вас идентификатор, это имя, тогда кнопки удаления и должны его содержать в атрибуте, например так data-del="name", а не вырезать его выискивая среди src. Тогда делегирование обработчика этим кнопкам, это

$(parent_selector).on('click', '[data-del]', function() {
     var btn = $(this),
         del = btn.data('del'), //то почему сервер узнает, что удалять
         etc ....
})


И делегировать нужно не тому, что удобно пишется, а ближайшему родителю, который всегда есть на странице.


Часовой пояс GMT +3, время: 02:00.