Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Выделение текста contenteditable (https://javascript.ru/forum/dom-window/81226-vydelenie-teksta-contenteditable.html)

Янковиц 23.10.2020 16:52

Выделение текста contenteditable
 
Привет, хочу немного прокачать скилл на javascript. Делаю простенький WYSIWYG. Прошу помощи, как отловить событие завершения выделения?
1. Пробовал mouseup, но он пересекается с двойным кликом и кликом правой кнопкой мыши. Также mouseup плох тем, что если выделение начинаю в области редактора, а заканчиваю вне его, то event.target берётся вне редактора.
2. onselectionchange срабатывает на весь документ, так как работает только со всей страницей.

В сети ничего путного не нашел...

voraa 23.10.2020 19:29

Использовать onselectionchange, а потом смотреть что выделили в интересующем вас элементе.
https://learn.javascript.ru/selection-range
https://learn.javascript.ru/range-textrange-selection

Янковиц 23.10.2020 19:37

Да, спасибо, я иду в этом направлении. Пытаюсь получить содержимое вместе с тегами.
Вот например такой текст: "<p>Привет я <b>но<i>вы</i>й</b> редактор</p>".
Если выделить через двойной клик слово новый, html будет вида но<i>вы</i>й, без тега <b>. Как это побороть?

Янковиц 23.10.2020 19:38

Делаю так:
if ( window.getSelection ) {
	var selection = window.getSelection();
} else if ( document.selection ){
	var selection = document.selection.createRange();
}
var range = selection.getRangeAt(0);

var div = document.createElement('div');
div.appendChild( range.cloneContents() );
console.log( div.innerHTML ); // двойной клик по  слову "новый" даёт результат: но<i>вы</i>й - не хватает тегов b
console.log( div.innerHTML ); // если выделить "я новый редактор", даёт результат: я <b>но<i>вы</i>й</b> редактор


есть ещё range.commonAncestorContainer, который:
console.log( range.commonAncestorContainer ); // двойной клик по  слову "новый" даёт результат: <b>но<i>вы</i>й</b> - то что нужно
console.log( range.commonAncestorContainer ); // если выделить "я новый редактор", даёт результат: <p>Привет я <b>но<i>вы</i>й</b> редактор</p>, а не выделение.

Я думал совместить эти две функции. range.commonAncestorContainer даёт ближайшего родителя. Затем в строке range.commonAncestorContainer искать подстроку div.innerHTML, и регуляркой вытаскивать ближайшие теги. Типа такого: (/<МОЯ_ПОДСТРОКА>/ig)


Но регулярки я, к сожалению, не знаю. Да и вообще, походит на какой-то костыль. Может есть более простое и элегантное решение?

Суть в том, чтобы получить html выделенного текста вместе с внешними тегами: и по двойному клику по слову, и обычным выделением группы слов.


Часовой пояс GMT +3, время: 04:32.