Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.09.2022, 20:20
Новичок на форуме
Отправить личное сообщение для nail2010 Посмотреть профиль Найти все сообщения от nail2010
 
Регистрация: 21.09.2022
Сообщений: 6

Множественное выделение текста 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();
}


Заранее всех благодарю...
Ответить с цитированием
  #2 (permalink)  
Старый 21.09.2022, 20:43
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,251

Всё работает (выдели три раза):
<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. Ну и я бы на тему этой фичи не заморачивался, хром так не умеет и не собирается вроде.
__________________
29375, 35
Ответить с цитированием
  #3 (permalink)  
Старый 23.09.2022, 18:55
Новичок на форуме
Отправить личное сообщение для nail2010 Посмотреть профиль Найти все сообщения от nail2010
 
Регистрация: 21.09.2022
Сообщений: 6

Спасибо большое за ответ! Сейчас проверил и правда все работает, тогда значит у меня в коде где-то выделение снимается... А разве range не является живой коллекцией? Вернее если поместить его в массив и менять, разве остальные ключи не изменятся?
Ответить с цитированием
  #4 (permalink)  
Старый 23.09.2022, 20:12
Новичок на форуме
Отправить личное сообщение для nail2010 Посмотреть профиль Найти все сообщения от nail2010
 
Регистрация: 21.09.2022
Сообщений: 6

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

Я выделяю текст, нажимаю на кнопку, все меняется и выделение остается, но, когда создаю несколько выделений и так же нажимаю на кнопку, первое исправляется, а последующие нет и выделение с них снимается...

Понимаю, что возможно задаю глупый вопрос, потому что кода привожу мало, но может у кого-то был с этим опыт?
Ответить с цитированием
  #5 (permalink)  
Старый 23.09.2022, 20:46
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,251

nail2010, без кода - можно только гадать. Нужен хотя бы твой магческий способ не терять фокус. Скорее всего он работает просто восстанавливая выделение после того как оное пропало и не учитывает вариант множественности.
__________________
29375, 35
Ответить с цитированием
  #6 (permalink)  
Старый 29.09.2022, 20:48
Новичок на форуме
Отправить личное сообщение для nail2010 Посмотреть профиль Найти все сообщения от nail2010
 
Регистрация: 21.09.2022
Сообщений: 6

Прошу прощения за такую большую задержку, но проект большой и частей много... Я вывел аспекты, которые касаются этого функционала и привел вот в этом, отдельно взятом 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>
Ответить с цитированием
  #7 (permalink)  
Старый 29.09.2022, 20:54
Новичок на форуме
Отправить личное сообщение для nail2010 Посмотреть профиль Найти все сообщения от nail2010
 
Регистрация: 21.09.2022
Сообщений: 6

Код с виду работает, но, к сожалению, не работает для множественных выделений... Я даже не знаю, что делать... Первое выделение заменяется, а последующие нет... Мне кажется, когда выполняется setStartAfter и deleteContents остальные выделения просто перестают быть выделенными... Может есть рецепт, без этих инструкций?
Ответить с цитированием
  #8 (permalink)  
Старый 29.09.2022, 21:07
Новичок на форуме
Отправить личное сообщение для nail2010 Посмотреть профиль Найти все сообщения от nail2010
 
Регистрация: 21.09.2022
Сообщений: 6

И вот еще один момент... Использую просто
range.surroundContents(newNode);

Без каких либо удалений... Но, этот метод он обрамляет все содержимое вместе с тегами и вкладывает их всех друг в друга, получается вроде этого:
<h2><h3>Выдели меня...</h3></h2>
но мне так не нужно...

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

Цитата:
Чтобы этот метод сработал, диапазон должен содержать как открывающие, так и закрывающие теги для всех элементов внутри себя: не допускаются частичные диапазоны по типу <i>abc
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как с помощью скрипта высчитать ширину полосы прокрутки? LADYX Элементы интерфейса 35 13.11.2017 12:50
Выделение текста Ezhuroff Events/DOM/Window 5 03.11.2016 18:46
Отменить в выделение текста в таблице при кликах и вообще двойные клики отменить monkey_gelada Events/DOM/Window 1 21.08.2015 09:28
Textarea и выделение текста dima85 Общие вопросы Javascript 2 29.09.2014 13:48
Выделение текста в текстовом поле. Как снять выделение с пробела вконце? Roman Koff Events/DOM/Window 10 01.07.2010 16:48