Javascript-форум (https://javascript.ru/forum/)
-   Javascript под браузер (https://javascript.ru/forum/css-html/)
-   -   Установка текстового курсора в определённое место в элементе (https://javascript.ru/forum/css-html/79198-ustanovka-tekstovogo-kursora-v-opredeljonnoe-mesto-v-ehlemente.html)

Andrew K 03.01.2020 17:31

Установка текстового курсора в определённое место в элементе
 
Добрый день. Есть такая разметка:
<div contenteditable="true"><span>PDF</span></div>

Так как стоит contenteditable, то можно сделать чтобы появился текстовый курсор для набора текста. Мне нужно поставить курсор до <span>-а. То есть при наборе слово должно быть слева.



Написал такой код:
let span = document.querySelector('span'),
    selection = document.getSelection(),
    range = new Range();
range.setStartBefore(span);
selection.addRange(range);

Метод setStartBefore должен поставить курсор до <span>-а. Но по факту он ставит внутрь <span>-а.



Если в обёрке не будет <span>-а, то текстовый курсор нормально встаёт внутрь <div>-а. Так же если есть текст, то курсор можно поставить до или после текста. А вот если есть только вложенный <span>, то курсор никак не хочет вставать ДО него.

Теоретически можно поместить внутрь еще один пустой <span> и в него будет добавляться текст, затем изъять текст, удалить <span> и поставить на его место, но это уже костыли. Может есть какой-то другой способ?

Malleys 03.01.2020 17:49

Цитата:

Сообщение от Andrew K
Так как стоит contenteditable

Т. е. предполагается, что можно вставлять любое содержимое, включая части страницы? Или вы хотите вводить только текст?

Andrew K 03.01.2020 18:02

Только текст.

Malleys 03.01.2020 18:20

Цитата:

Сообщение от Andrew K
Только текст.

Если только текст то вы можете сделать при помощи <input>, т. е. расставить <input> там, где ожидается ввод текста.

Вот, как пример, хотя это может быть не совсем то, что вы делаете... https://javascript.ru/forum/events/7...tml#post505084

Цитата:

Сообщение от Andrew K
Может есть какой-то другой способ?

Что именно вы хотите сделать?

Andrew K 03.01.2020 18:53

Я делаю текстовый редактор вроде CKEditor. Пользователь будет вводить только текст и менять место ввода. А уже редактор будет ставить теги. Но и самому редактору требуется менять место ввода. И вот у меня возник затык именно в том как поставить курсор <div contenteditable="true">ВОТ В ЭТО МЕСТО<span>pdf</span></div>. Поэтому поля ввода тут не совсем уместны.

Andrew K 03.01.2020 19:01

Переформулирую. Пользователь ввёл текст в редактируемую область. Программа сгенерировала такой код:
<div contenteditable="true">pdf</div>

Затем выделил слово pdf, нажал на кнопочку и редактор обернул его в <span>.
<div contenteditable="true"><span>pdf</span></div>

И теперь пользователь хочет написать текст до <span>-а. Чтобы это сделать нужно поставить курсор <div contenteditable="true">ВОТ В ЭТО МЕСТО<span>pdf</span></div>. А это сделать не удаётся.

Aetae 03.01.2020 19:13

Попробуй не start ставить, а end.

Вообще contenteditable - это ад. Причём в каждом конкретном браузере свой. Если очень хочется пилить что-то своё, то единственное решение(без вырывания волос и (лёгкого?) сумасшествия) - изучить через какие конструкции из костылей подобное сделано в давно развивающийся редакторах.

Andrew K 03.01.2020 19:18

Цитата:

Сообщение от Aetae (Сообщение 518368)
Попробуй не start ставить, а end.

Аналогичный результат. Только ставит курсор в конце текста заключённого в <span>.

Andrew K 03.01.2020 19:53

Цитата:

Сообщение от Aetae (Сообщение 518368)
...изучить через какие конструкции из костылей подобное сделано в давно развивающийся редакторах.

Вот, кстати, такого поведения там не предусмотрено. Попробуйте создать абзац с текстом и вне <p>...</p> ввести текст: редактор не даст это сделать. Текст будет внутри <p>...</p>.

Malleys 03.01.2020 20:29

Andrew K, можно перед <span> добавить пробел нулевой ширины... (Правда, когда уже есть текст, то курсор ставится перед текстом, а не элементом, но я думаю идея понятна)

<button id="btn">Поставить курсор до &lt;span&gt;</button>
<script>
const zws = document.createTextNode("\u200B");
btn.onclick = () => {
	let span = document.querySelector("span"),
		selection = document.getSelection(),
		range = new Range();
	span.before(zws);
	range.setStartBefore(zws);
	selection.removeAllRanges();
	selection.addRange(range);
};
</script>
<style>
span { background: orange; }
</style>
<div contenteditable="true"><span>PDF</span></div>


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