Множественное выделение текста Range
Всем привет! Помогите, пожалуйста, гуру JS, бьюсь не первый день, в сети нет информации по этому вопросу...
В общем есть редактируемый DIV, в нем можно набрать текст, в firefox'е при зажатии Ctrl можно выделить несколько областей одновременно и с ними работать... Но вот незадача, когда корректирую один из фрагментов выделенных, остальные выделения отпускаются и мой цикл завершается... Прошу прощения, что привожу код не в песочнице, а тут, так как песком вообще не пользуюсь... for(let n = 0; n < select.rangeCount; n++){ let range = select.getRangeAt(n); let newNode = document.createElement(pressButton); newNode.appendChild(range.cloneContents()); range.insertNode(newNode); range.setStartAfter(newNode); range.deleteContents(); } Заранее всех благодарю... |
Всё работает (выдели три раза):
<body> Всем привет! Помогите, пожалуйста, гуру JS, бьюсь не первый день, в сети нет информации по этому вопросу... В общем есть редактируемый DIV, в нем можно набрать текст, в firefox'е при зажатии Ctrl можно выделить несколько областей одновременно и с ними работать... Но вот незадача, когда корректирую один из фрагментов выделенных, остальные выделения отпускаются и мой цикл завершается... Прошу прощения, что привожу код не в песочнице, а тут, так как песком вообще не пользуюсь... <script> document.documentElement.onmouseup = () => { const pressButton = 'u'; const select = getSelection(); if(select.rangeCount < 3) return; for(let n = 0; n < select.rangeCount; n++){ let range = select.getRangeAt(n); let newNode = document.createElement(pressButton); newNode.appendChild(range.cloneContents()); range.insertNode(newNode); range.setStartAfter(newNode); range.deleteContents(); } } </script> Заранее всех благодарю... </body> Нужно больше деталей где именно проблемы. Могу предложить сначала положить Range'и в массив, а потом с ним работать, но без конкретики - это гадание. P.S. Ну и я бы на тему этой фичи не заморачивался, хром так не умеет и не собирается вроде. |
Спасибо большое за ответ! Сейчас проверил и правда все работает, тогда значит у меня в коде где-то выделение снимается... А разве range не является живой коллекцией? Вернее если поместить его в массив и менять, разве остальные ключи не изменятся?
|
В общем немного разобрался, ваш код с событием на мышку работает, а в моем коде событие на нажатие кнопки в интерфейсе, но у меня фокус не теряется, с этим у меня уже была проблема я с ней разобрался ранее...
Я выделяю текст, нажимаю на кнопку, все меняется и выделение остается, но, когда создаю несколько выделений и так же нажимаю на кнопку, первое исправляется, а последующие нет и выделение с них снимается... Понимаю, что возможно задаю глупый вопрос, потому что кода привожу мало, но может у кого-то был с этим опыт? |
nail2010, без кода - можно только гадать. Нужен хотя бы твой магческий способ не терять фокус. Скорее всего он работает просто восстанавливая выделение после того как оное пропало и не учитывает вариант множественности.
|
Прошу прощения за такую большую задержку, но проект большой и частей много... Я вывел аспекты, которые касаются этого функционала и привел вот в этом, отдельно взятом html-файле...
<html> <head> <title></title> <script> document.addEventListener("DOMContentLoaded", function(){ // Перебираем кнопки for(let n = 1; n <= 3; n++){ document.getElementById("BUTTON_"+n).onclick = function(){ let select = window.getSelection(); if(select.isCollapsed){ // Ни одного выделенияя нет } else { let pressButton = this.getAttribute("data-tagName"); let countSelected = 0; // Перебераем выделения for(let n = 0; n < select.rangeCount; n++){ let range = select.getRangeAt(n); let parentElem = range.commonAncestorContainer.parentNode; let parentElemСhangeable = range.commonAncestorContainer; // Выделение в нашем блоке for(let q = 0; q <= q+1; q++){ if(parentElemСhangeable.id == "CONTENT"){ let newNode = document.createElement(pressButton); newNode.appendChild(range.cloneContents()); range.insertNode(newNode); range.setStartAfter(newNode); range.deleteContents(); break; } else { parentElemСhangeable = parentElemСhangeable.parentNode; } if(parentElemСhangeable.tagName == "BODY"){ break; } } } } } } }); </script> </head> <body> <div id="CONTENT" contenteditable="true" style="display:inline-block; border:1px dashed #999; color:#666; background:#EEE; padding:2px 5px; margin:10px 0; min-height: 10em;"> Какое-то длинное высказывание, как вводная часть текста... Выдели меня... Выдели меня... Выдели меня... Выдели меня... </div> <div> <button id="BUTTON_1" data-tagName="H1" style="margin-right: 0.5em;">Заголовок 1</button> <button id="BUTTON_2" data-tagName="H2" style="margin-right: 0.5em;">Заголовок 2</button> <button id="BUTTON_3" data-tagName="H3">Заголовок 3</button> </div> </body> </html> |
Код с виду работает, но, к сожалению, не работает для множественных выделений... Я даже не знаю, что делать... Первое выделение заменяется, а последующие нет... Мне кажется, когда выполняется setStartAfter и deleteContents остальные выделения просто перестают быть выделенными... Может есть рецепт, без этих инструкций?
|
И вот еще один момент... Использую просто
range.surroundContents(newNode); Без каких либо удалений... Но, этот метод он обрамляет все содержимое вместе с тегами и вкладывает их всех друг в друга, получается вроде этого: <h2><h3>Выдели меня...</h3></h2>но мне так не нужно... Я, конечно, могу потом почистить код, перед отправкой или уже на сервере, но как быть с тем, что этот метод можно использовать только в полных боках... Цитата:
|
Часовой пояс GMT +3, время: 20:53. |