Добавить 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,
могу проверить только на пк, всё работает. |
webgraph,
ошибки в консоли какие-то есть? |
рони,
У меня тоже пк — макбук.. и в iOS тоже не работает. Добавлять — добавляет, а удалять — не хочет.. прям никак не хочет.. Что же теперь делать?.. :) |
рони,
в консоли нет никаких ошибок |
webgraph,
попробуйте так заменить //list.remove(); e.removeChild(list); |
рони,
Это тоже не сработало. Я решила вывести в консоль текст при нажатии. И когда нажимаешь клавишу delete - в консоль ничего не выводится. словно он эту кнопку не считает кнопкой. ______________ Даже это не помогло: let key = event.keyCode || event.charCode || event.which; if (key === 46 || key === 'Delete' || key === 8 || key === 'Backspace' && (target = target.closest('.check-text'))) { ... } |
webgraph,
keydown в вашем коде или keypress? |
рони,
У вас было написано keydown, а до этого keypress. Т.к. при keydown не сработало — было поставлено keypress. Хы Т.к. были добавлены дополнительные коды, то теперь с keydown удаление работает!)) оказывается на macbook это вообще Backspace (код клавиши 8). НО !) При фокусе после удаления — курсор появляется в начале строки. А по логике он должен в конец текста вставать. Как сфокусировать на самом конце текста?) |
Цитата:
<!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) { e.removeChild(list); let div = prev.querySelector('.check-text'), pos = div.innerHTML.length, range = document.createRange(); range.setStart(div.childNodes[0], pos); range.collapse(true); let sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } } }; }); }); </script> </body> </html> |
Часовой пояс GMT +3, время: 14:12. |