Третья программа: "Мессенджер". 100%

Моё решение с комментариями к добавленной части кода:

Сводка
// Контейнер для сообщений
var chatContainer = document.querySelector('.chat-content');
// Коллекция всех сообщений в контейнере
var messages = chatContainer.children;
// Форма и поле ввода текста
var newMessageForm = document.querySelector('.chat-form');
var newMessageInput = newMessageForm.querySelector('.chat-form-input');
// Шаблон для сообщения
var messageTemplate = document.querySelector('#message-template').content;
var newMessageTemplate = messageTemplate.querySelector('.chat-message');


// Создание нового сообщения
newMessageForm.addEventListener('submit', function (evt) {
  evt.preventDefault();

  // Получаем текст из поля ввода
  var messageText = newMessageInput.value;
  // Клонируем шаблон сообщения
  var newMessage = newMessageTemplate.cloneNode(true);
  // Добавляем текст вводимый пользователем
  newMessage.children[1].textContent = messageText;
  // Добавляем сообщение на страницу
  chatContainer.appendChild(newMessage);
  // Добавляем обработчик удаления новых сообщений
  deleteMessageHandler(newMessage);
  // Чистим содержимое поля ввода
  newMessageInput.value = '';
});
// Функция удаления сообщения
var deleteMessageHandler = function (message) {
  var crossSign = message.querySelector('.chat-message-button');
  crossSign.addEventListener('click', function () {
  message.remove(); 
  });    
}
// Цикл для выбора сообщения для удаления из коллекции(списка)
for (var i = 0;i < messages.length;i++) {
  deleteMessageHandler(messages[i]);  
}
7 лайков

все кайф, но мне кажется вот тут нужно чутка переделать для гибкости

newMessage.children[1].textContent = messageText;

вдруг кому-то в голову трахнет и захочется в шаблон добавить время сообщения…
лучше явно по классу сделать

моё для памяти
// Контейнер для сообщений
let chatContainer = document.querySelector('.chat-content');
// Создаем динамическую коллекцию из сообщений внутри контейнера сообщений
let items = chatContainer.children;
// Форма и поле ввода текста
let newMessageForm = document.querySelector('.chat-form');
let newMessageInput = newMessageForm.querySelector('.chat-form-input');

// Шаблон для сообщения
let messageTemplate = document.querySelector('#message-template').content;
let newMessageTemplate = messageTemplate.querySelector('.chat-message');

// Удаление сообщения по крестику
let deleteMessageHandler = function(item) {
  let closeButton = item.querySelector('.chat-message-button');
  closeButton.addEventListener('click', function() {
    item.remove();
  });
}
for (let i = 0; i < items.length; i++) {
  deleteMessageHandler(items[i]);
}

// Создание нового сообщения
newMessageForm.addEventListener('submit', function(evt) {
  evt.preventDefault();

  // Получаем текст из поля ввода
  let messageText = newMessageInput.value;
  // Клонируем шаблон сообщения
  let newMessage = newMessageTemplate.cloneNode(true);
  // Находим контейнер для текста и записываем туды сообщение из ввода
  newMessage.querySelector('.chat-message-text').textContent = messageText;
  // Добавляем сообщение на страницу
  chatContainer.appendChild(newMessage);
  // Добавляем обработчик удаления сообщений по крестику
  deleteMessageHandler(newMessage);
  // Чистим содержимое поля ввода
  newMessageInput.value = '';
});
3 лайка

Цикл-то тут не нужен получается. Сообщения же не будут писаться через редактор. можно все упаковать в одну функцию, задача выполнится.

Сводка

var chat = document.querySelector(’.chat-content’);
var messages = chat.children;
var newMessageForm = document.querySelector(’.chat-form’);
var newMessageInput = document.querySelector(’.chat-form-input’);
var messageTemplate = document.getElementById(‘message-template’).content;
var newMessageTemplate = messageTemplate.querySelector(’.chat-message’);

newMessageForm.addEventListener(‘submit’, function (evt) {
evt.preventDefault();
var messageText = newMessageInput.value;
var message = newMessageTemplate.cloneNode(true);
var messageBox = message.querySelector(‘p’);
messageBox.textContent = messageText;
chat.appendChild(message);
var deleteButton = message.querySelector(’.chat-message-button’);
deleteButton.addEventListener(‘click’, function () {
message.remove();
});
newMessageInput.value = ‘’;
})

1 лайк

Вот мой вариант с комментариями.

Сводка

//Находим шаблон и его содержимое
var messageTemplate = document.querySelector(’#message-template’).content;
var newMessageTemplate = messageTemplate.querySelector(’.chat-message’);
//Находим чат, форму и текстовое поле
var chat = document.querySelector(’.chat-content’);
var chatForm = document.querySelector(’.chat-form’);
var messageInputField = chatForm.querySelector(’.chat-form-input’);

//На форму вешаем обработчик события submit
chatForm.addEventListener(‘submit’, function(evt){
//Отменяем действие по умолчанию
evt.preventDefault();
//Новое сообщение клонируем из шаблона
var newMessage = newMessageTemplate.cloneNode(true);
//Сохраняем текст, который пользователь ввёл в поле
var newMessageText = messageInputField.value;
//В новом сообщении находим элемент, где будет содержаться текст
var messageTextContainer = newMessage.querySelector(’.chat-message-text’);
// … и кнопку удаления сообщения.
var messageRemoveButton = newMessage.querySelector(’.chat-message-button’);

//Записываем в разметку сообщения текст пользователя
messageTextContainer.textContent = newMessageText;
//Аппендим сообщение в чат
chat.appendChild(newMessage);
//Очищаем поле
messageInputField.value = “”;

//На кнопку вешаем обработчик кликов, который будет удалять сообщения.
messageRemoveButton.addEventListener(‘click’, function(){
newMessage.remove();
});
});

К сожалению, я не смог вынести удаление сообщений в отдельную функцию, хотя желание такое было. Теперь, посмотрев, предыдущие варианты, понял как нужно было это делать.

1 лайк

Здравствуйте!
При попытке удалить сообщение, мне выскакивает следующая ошибка " TypeError : msgContent.remove is not a function".
Где именно я ошибся ? Спасибо!

Код: https://pastebin.com/zJK0sWR5

.querySelector('.chat-message'); добавьте к msgTemplateContent
а то чет не очень ясно что вы удалить пытаетесь

зачем к msgTemplateContent ? msgTemplateContent это тег template в html, мне его не надо удалять.

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

потому он и пишет, что remove() is not a function, т.к. такого метода не описано для коллекции-фрагмента (даже прототипно)

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

1 лайк

ПАМАГИТЕ!
Буду признателен если объясните почему не получается удалить сообщение?
Заранее спасибо)))

var chatContent = document.querySelector('.chat-content');
var messageItems = chatContent.children;
var messageTemplate = document.querySelector('#message-template').content;
var chatMessage = messageTemplate.querySelector('.chat-message');
var chatForm = document.querySelector('.chat-form');

chatForm.addEventListener('submit', function (evt) {
  evt.preventDefault();
  
  var chatInput = chatForm.querySelector('.chat-form-input'); 
  var messageText = chatInput.value;
  var chatMessageText = chatMessage.querySelector('.chat-message-text'); 
  
  chatMessageText.textContent = messageText;
  var yourMessage = chatMessage.cloneNode(true);
  chatContent.appendChild(yourMessage);
  chatInput.value = '';
  });


var removeMessage = function (item) {
var buttonClose = item.querySelector('.chat-message-button');  
buttonClose.addEventListener('click', function () {
    item.remove();
  });
};

for (var i = 0; i < messageItems.length; i++) {
  removeMessage(messageItems[i]);
  }

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

подсказка
removeMessage( yourMessage );
2 лайка

Спасибо! Вы сэкономили мне кучу времени и нервов))

2 лайка

https://learn.javascript.ru/event-delegation

Я тоже сделала также! Кто-нибудь может сказать: ЭТОТ ВАРИАНТ — допустим или все-таки так лучше не делать и здесь есть какие-то минусы??

Не могу понять, с ответами сходится на 100%, но пишет, что “Тест не пройден”. Кто-нибудь знает, в чём дело?

let chat = document.querySelector(".chat-content");
let form = document.querySelector(".chat-form");
let buttonInForm = form.querySelector("button");
let inputInForm = form.querySelector("input");
let template = document.querySelector("template").content;
let textTemplate = template.querySelector(".chat-message"); 

buttonInForm.addEventListener("click", function(evt) {
	evt.preventDefault();
	let cloneTemplate = textTemplate.cloneNode(true);
	let deleteMessage = cloneTemplate.querySelector(".chat-message-button");
	let p = cloneTemplate.querySelector("p");

	p.textContent = inputInForm.value;
	deleteMessage.addEventListener("click", function() {
		cloneTemplate.remove();
	})	
	chat.appendChild(cloneTemplate);
})

Результат не совпадает с ожидаемым. Нужно очищать поле ввода после каждой операции.

1 лайк

Спасибо, добавил 1 строчку.:sweat_smile:

let chat = document.querySelector(".chat-content");
let form = document.querySelector(".chat-form");
let buttonInForm = form.querySelector("button");
let inputInForm = form.querySelector("input");
let template = document.querySelector("template").content;
let textTemplate = template.querySelector(".chat-message"); 

buttonInForm.addEventListener("click", function(evt) {
	evt.preventDefault();
	let cloneTemplate = textTemplate.cloneNode(true);
	let deleteMessage = cloneTemplate.querySelector(".chat-message-button");
	let p = cloneTemplate.querySelector("p");

	p.textContent = inputInForm.value;
	inputInForm.value = "";
	deleteMessage.addEventListener("click", function() {
		cloneTemplate.remove();
	})	
	chat.appendChild(cloneTemplate);
})

Ничего нового, разве что функции стрелочные…

Давно не спойлер
let chatContent = document.querySelector('.chat-content');

let templateMessage = document.querySelector('#message-template').content;
let messageBlock = templateMessage.children[0]; 

let chatForm = document.querySelector('.chat-form');
let formInput = chatForm.querySelector('.chat-form-input');    
   
chatForm.addEventListener('submit', (evt) => {
  evt.preventDefault();
  
  let message = formInput.value;
  let newMassgeBlock = messageBlock.cloneNode(true);
  let messageText = newMassgeBlock.querySelector('.chat-message-text');
  messageText.textContent = message;
  
  let messageDelitButton = newMassgeBlock.querySelector('.chat-message-button');

  messageDelitButton.addEventListener('click', () => {
    newMassgeBlock.remove()
    })

  chatContent.appendChild(newMassgeBlock);
  formInput.value = '';
});

Добавлю свой вариант решения. Буду рада конструктивным замечаниям.

Сводка
var chatForm = document.querySelector('.chat-form');
var chatFormInput = chatForm.querySelector('.chat-form-input');
var chatFormButton = chatForm.querySelector('.chat-form-button');
var chatContent = document.querySelector('.chat-content');
var chatContentItems = chatContent.children;

var messageTemplate = document.querySelector('#message-template').content; 
var newItemTemplate = messageTemplate.querySelector('div');

var removeMessageHandler = function (item) { 
  var chatMessageButton = item.querySelector('.chat-message-button'); 

  chatMessageButton.addEventListener ('click', function () {
    for (var i = 0; i < chatContentItems.length; i++) {      
      item.remove();
      }
   });    
};

chatForm.addEventListener('submit', function (evt) {
  evt.preventDefault();
  
  var newMessage = chatFormInput.value;    
  var message = newItemTemplate.cloneNode(true);
  var messageText = message.querySelector('p');
  messageText.textContent = newMessage;
  
  chatContent.appendChild(message);
  chatFormInput.value = '';   

  removeMessageHandler(message);
});
var chatСontent = document.querySelector('.chat-content');
var messageTemplate = document.querySelector('#message-template').content;
var chatMessage = messageTemplate.querySelector('.chat-message');
var chatForm = document.querySelector('.chat-form');
var chatFormInput = chatForm.querySelector('.chat-form-input');

chatForm.addEventListener('submit', function (evt) {
  evt.preventDefault();
  
  var messageText = chatFormInput.value;
  var message = chatMessage.cloneNode(true);
  var chatMessageText = message.querySelector('.chat-message-text');
  chatMessageText.textContent = messageText;
  
  chatСontent.appendChild(message);
  chatFormInput.value = '';
  
  var chatMessageButton = message.querySelector('.chat-message-button');
  chatMessageButton.addEventListener('click', function (){
    message.remove();  
  });
});

Не знаю зачем здесь цикл for в других решениях и отдельная функция удаления сообщения. Буду благодарен, если кто-нибудь объяснит. Нужны они тут или и так нормально.

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