Добавить div при нажатии Enter [на чистом JS]
Как добавить новый DIV при клике по Enter сразу после дива и сделать на нем focus()?
В моём решении вместо 1 дива добавляет разное множественное количество... <!DOCTYPE html> <html> <body> <!-- Весь список check-листов --> <section id="lists"> <!-- Первая группа check-листов --> <div class="group"> <div class="list"> <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> </div> <div class="list"> <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> </div> </div> <!-- Вторая группа check-листов --> <div class="group"> <div class="list"> <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> </div> <div class="list"> <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> </div> </div> <!-- ... Следующая группа check-листов и т.д. --> </section> <script> //функция, которая создает новый див function enterCheck(e) { //создаем новый див let div = document.createElement('div'); //добавляем ему класс div.classList.add('list'); //наполняем шаблоном списка div.innerHTML = ` <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> `; //перемещаемся на несколько дивов наверх (к началу текущего дива) //и добавляем после него созданный div e.parentNode.parentNode.after(div); //устанавливаем на .check-text созданного дива focus() //чтобы в нем можно было сразу вводить текст div.querySelector('.check-text').focus(); } //собираем массив всех checkText'ов let checkTexts = document.querySelectorAll('.check-text'); //перебираем этот массив checkTexts.forEach(function(e){ //когда сфокусирован на определенном checkText e.addEventListener('focus', function(){ //когда в нём нажимаются клавиши e.addEventListener('keypress', function(event){ //когда нажата Enter if(event.keyPress === 13){ //отменяем стандартное поведение(перенос строки) event.preventDefault(); //если текущий блок не пустой, то добавляем новый сразу после него if(this.innerText !== '') { enterCheck(this); } } }); }); }); </script> </body> </html> |
<!DOCTYPE html> <html> <style> div { position: relative; } .group { border: 1px solid green; margin: 20px 10px; } .check-text { height: 20px; width:200px; border: 1px solid red; margin: 5px 0; } .list-container { border: 1px solid blue } </style> <body> <!-- Весь список check-листов --> <section id="lists"> <!-- Первая группа check-листов --> <div class="group"> <div class="list"> <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> </div> <div class="list"> <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> </div> </div> <!-- Вторая группа check-листов --> <div class="group"> <div class="list"> <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> </div> <div class="list"> <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> </div> </div> <!-- ... Следующая группа check-листов и т.д. --> </section> <script> //функция, которая создает новый див function enterCheck(e) { //создаем новый див let div = document.createElement('div'); //добавляем ему класс div.classList.add('list'); //наполняем шаблоном списка div.innerHTML = ` <div class="list-container"> <input type="checkbox"><div class="check-text" contenteditable></div> </div> `; //перемещаемся на несколько дивов наверх (к началу текущего дива) //и добавляем после него созданный div e.parentNode.parentNode.after(div); setEvents(div); // Устанавливаваем обработчики на новый блок !!! //устанавливаем на .check-text созданного дива focus() //чтобы в нем можно было сразу вводить текст setTimeout (() => div.querySelector('.check-text').focus(), 0); // focus лучше через setTimeout } function setEvents(e) { // e.addEventListener('focus', function(){ --- Лишнее это наверно //когда в нём нажимаются клавиши e.addEventListener('keypress', function(event){ //когда нажата Enter if(event.keyCode === 13){ // Нет keyPress !!! //отменяем стандартное поведение(перенос строки) event.preventDefault(); //если текущий блок не пустой, то добавляем новый сразу после него if(this.innerText !== '') { enterCheck(this); } } }); // }); } //собираем массив всех checkText'ов let checkTexts = document.querySelectorAll('.check-text'); //перебираем этот массив checkTexts.forEach(e => setEvents(e)) //когда сфокусирован на определенном checkText </script> </body> </html> 1. if(event.keyPress === 13){ - не существует keyPress 2 Вы не устанавливаете слушатели событий на вновь созданные элементы 3 установка focus() сразу, почему то обычно не срабатывает. Лучше ее делать с нулевой задержкой черед setTimeout 4 Зачем ждать события focus, что бы поставить обработчик на keypress, я не понял. Почему не сразу? |
insert after by enter
webgraph,
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style type="text/css"> [contenteditable] { height: 50px; width: 400px; border: 1px solid #000000; } [contenteditable]:focus { outline: none; border-color: #FF0000; } </style> <title></title> </head> <body> <!-- Весь список check-листов --> <section id="lists"> <!-- Первая группа check-листов --> <div class="group"> <div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""></div> </div> <div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""></div> </div> </div><!-- Вторая группа check-листов --> <div class="group"> <div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""></div> </div> <div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""></div> </div> </div><!-- ... Следующая группа check-листов и т.д. --> </section> <script> //функция, которая создает новый див function enterCheck(list) { let html = `<div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""><\/div> <\/div>`; list.insertAdjacentHTML('afterend', html); list.nextElementSibling.querySelector('.check-text').focus(); } //собираем массив всех group'ов let groups = document.querySelectorAll('.group'); //перебираем этот массив groups.forEach(function(e) { //когда в нём нажимаются клавиши e.addEventListener('keypress', function(event) { let target = event.target; //когда нажата Enter if (event.key === 'Enter' && (target = target.closest('.check-text'))) { //отменяем стандартное поведение(перенос строки) event.preventDefault(); //если текущий блок не пустой, то добавляем новый сразу после него if (target.innerText !== '') { let list = target.closest('.list') enterCheck(list); } } }); }); </script> </body> </html> |
рони, а как удалить блок на котором:
1. установлен фокус 2. он пустой 3. нажимается клавиша Delete (на пк и смартфонах) ИЛИ происходит расфокус blur() и после удаления перенести focus() на блок который выше него. |
webgraph,
удаляется если в данной группе, есть блок выше над текущим. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style type="text/css"> [contenteditable] { height: 50px; width: 400px; border: 1px solid #000000; } [contenteditable]:focus { outline: none; border-color: #FF0000; } </style> <title></title> </head> <body> <!-- Весь список check-листов --> <section id="lists"> <!-- Первая группа check-листов --> <div class="group"> <div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""></div> </div> <div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""></div> </div> </div><!-- Вторая группа check-листов --> <div class="group"> <div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""></div> </div> <div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""></div> </div> </div><!-- ... Следующая группа check-листов и т.д. --> </section> <script> //функция, которая создает новый див function enterCheck(list) { let html = `<div class="list list-container"> <input type="checkbox"> <div class="check-text" contenteditable=""><\/div> <\/div>` list.insertAdjacentHTML('afterend', html); list.nextElementSibling.querySelector('.check-text').focus(); } //собираем массив всех group'ов let checkTexts = document.querySelectorAll('.group'); //перебираем этот массив checkTexts.forEach(function(e) { //когда в нём нажимаются клавиши e.addEventListener('keydown', function(event) { let target = event.target; //когда нажата Enter if (event.key === 'Enter' && (target = target.closest('.check-text'))) { //отменяем стандартное поведение(перенос строки) event.preventDefault(); //если текущий блок не пустой, то добавляем новый сразу после него if (target.innerText !== '') { let list = target.closest('.list') enterCheck(list); } }; if (event.key === 'Delete' && (target = target.closest('.check-text'))) { //отменяем стандартное поведение(перенос строки) event.preventDefault(); //если текущий блок пустой и есть блок выше, то удаляем его if (target.innerText === '') { let list = target.closest('.list') let prev = list.previousElementSibling; if(prev){ list.remove(); prev.querySelector('.check-text').focus(); } } }; }); }); </script> </body> </html> |
рони,
Что-то не удаляется вообще.. Ни здесь по клику "Посмотреть", ни у меня в коде.. Было попробовано event.keyCode === 46 — ноль изменений.. Почему не работает тогда?.. |
webgraph,
может вы в 1 блоке проверяли? |
рони,
Смысл проверять в первом, если там не прописана логика удаления?) Пробовался код который в Сегодня, 08:52 был опубликован) |
рони,
А, вы имеете ввиду дивы.. — проверяли начиная со второго. Ну и дошло до того, что все блоки пробовала удалять. И создавать и удалять. Не удаляются никак... Ни в Safari, ни в Chrome) А у вас удаляются?) |
webgraph,
могу проверить только на пк, всё работает. |
Часовой пояс GMT +3, время: 16:50. |