Как узнать кликнутую букву?

Есть текст, который находится внутри div. При нажатии надо получить позицию буквы/слова, на которое произошел клик. Как такое реализовать?


Ответы (2 шт):

Автор решения: artomich

Как вариант - можно переработать текст так, чтобы каждая буква была внутри тега span с атрибутами data-word и data-letter - а также обработчиком события click.
То бишь, ввести подобную функцию:

const generateText = (text) => {
    return text.split(' ').map((word, indexWord)=>word.split('').map((letter, letterIndex)=>`<span data-word=${indexWord} data-letter=${letterIndex} onclick="clickHandler(event)">${letter}</span>`).join('')).join(' ');
}

В div нужно отправлять результат обработки вашего текста с помощью этой функции (через innerHTML, или средствами каких-либо других библиотек, если вы их используете). А вот возможный обработчик клика:

const clickHandler = (event) => {
    let wordIndex = event.target.getAttribute('data-word');
    let letterIndex = event.target.getAttribute('data-letter');
    console.log(`word: ${wordIndex}; letter: ${letterIndex}`);
}


UPD: это решение может оказаться низкопроизводительным

→ Ссылка
Автор решения: Ilshat Nasyrov

В learn.javascript.ru упоминается об объекте Range

Range – это объект, соответствующий фрагменту документа, который может включать узлы и участки текста из этого документа. Наиболее подробно объект Range описан в спецификации DOM Range.

Вам необходимо использовать свойство startOffset

Свойство startOffset (endOffset) вернёт смещение для верхней (нижней) граничной точки.

приведен код и ссылка где можно посмотреть пример:

var range = getRangeObject();
    if (range) {
        alert( range );
        alert( range.startContainer.nodeValue );
        alert( range.startOffset );
        alert( range.endOffset );
    } else {
        alert( 'Ничего не выделено' );
    }

}

UPD: для получения определенного символа необходимо использовать

range.startContainer.nodeValue.substring(range.startOffset, range.startOffset+1) 
→ Ссылка