#javascript
#javascript
Вопрос:
Я пытаюсь запрограммировать простой текстовый редактор для развлечения. Я застрял на этой проблеме. Я хочу добавить жирный шрифт или курсив к выделенному тексту при нажатии кнопки. Я полагаю, что лучший способ сделать это — получить индекс выделенного текста, а затем добавить тег bold / italic вокруг тега в innerHTML. Однако, похоже, я не могу получить позицию / индекс выбранного тега для переноса в innerHTML. Очевидно, что код innerHTML смещен тегами. Есть ли более простой способ сделать это?
Я думал, что найти индекс выделенного текста было правильным решением. Хорошо. К сожалению, indexOf найдет только первое событие.
var word_document = document.getElementById('word-document');
/* This code is for our bold button */
var bold_button = document.getElementById('bold-button')
bold_button.addEventListener('click', (event) => {
/* Test to see if text is highlighted */
let text = window.getSelection().toString();
console.log("Selected Text: " text);
if (text.length > 0) {
// Find the position of the highlighted text in the word document.
let position = word_document.innerHTML.indexOf(text); // Not a good way of doing it
console.log("Pos: ", position);
// Replace the highlighted text from the document with the bold text
word_document.innerHTML.replace(text, "<b>" text "</b>");
}
/* If text is not highlighted, add a bold tag */
else {
// Add bold tag to bottom of document
word_document.focus();
word_document.innerHTML = "<b></b>";
word_document.selectionEnd = word_document.innerHTML.length - 6;
}
});
/* This code is for our italic button */
var italic_button = document.getElementById('italics-button');
italic_button.addEventListener('click', function() {
let text = window.getSelection().toString();
// Same issue
});
<button id="bold-button">B</button>
<button id="italics-button">I</button>
<textarea id="word-document">Starting Text</textarea>
Я полагаю, что возможным способом было бы перебрать textContent и найти, соответствует ли ему какой-либо текст до выбранного текста, а затем установить переменную для пропуска такого количества совпадений. Есть ли более простой способ сделать это. В идеале я хотел бы создать тег bold или italic и добавить его в текстовую область более правильным образом. Я поддерживаю обход DOM, вероятно, лучший способ. Есть идеи о том, как это можно было бы легче решить?
Спасибо
Я использую обычный / ванильный Javascript.
Редактировать: исправлен код. Добавление JsFiddle здесь
Комментарии:
1. Что такое
word_document
? Может быть, вы могли бы сделать это доступным для выполнения фрагментом, который иллюстрирует вашу проблему?2. @wyck О, мой плохой. Я сделаю. Добавит jsfidddle
3. getRange() возвращает объект диапазона , из которого вы можете получить начало и конец выделения. вам не обязательно использовать indexOf.
4. @Robert позвольте мне поиграть с этим и вернуться к вам.
5. @Robert, это похоже на то, что я хочу сделать. Но мне нужно выбрать родительский узел этой позиции:
Ответ №1:
Вы можете попробовать это :
<html>
<header>
</header>
<body>
<button id="bold-button" onClick="makeBold()">B</button>
<div id="word-document" contenteditable>Starting Text</div>
<script>
function makeBold() {
var inputText = document.getElementById("word-document");
var innerHTML = inputText.innerHTML;
text = window.getSelection().toString();
var index = innerHTML.indexOf(text);
if (index >= 0) {
innerHTML = innerHTML.substring(0,index) "<span style='font-weight: bold;'>" innerHTML.substring(index,index text.length) "</span>" innerHTML.substring(index text.length);
inputText.innerHTML = innerHTML;
}
}
</script>
</html>
идея здесь состоит в том, чтобы использовать поддельную текстовую область: div с редактируемым содержимым. Я надеюсь, что это поможет вам,
Удачи!
Комментарии:
1. Я не использую jQuery, и execCommand был обесценен.
2. Итак, если вы не используете jQuery, попробуйте мое второе предложение, я только что отредактировал свой пост, это может дать подсказку. Удачи, амиго.
3. я думаю, это решение не будет работать, если выделенный текст встречается несколько раз в innerHTML
Ответ №2:
простое фиктивное решение. это не работает для вложенных тегов.
Я настоятельно рекомендую прочитать этот учебник
function action({tag, classes}, event){
const text = document.getElementById("word-document");
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const before = text.innerHTML.substr(0, range.startOffset);
const after = text.innerHTML.substr(range.endOffset);
const selected = text.innerHTML.substr(range.startOffset,range.endOffset - range.startOffset );
const warpped = `<${tag} ${classes ? "class=" classes : ""}>${selected}</${tag}>`
text.innerHTML = before warpped after;
}
#word-document {
border: 1px solid black;
padding: 10px;
}
.underline{
text-decoration-line: underline;
}
<button onclick="action({tag: 'b'})">B</button>
<button onclick="action({tag: 'i'})">I</button>
<button onclick="action({tag: 'span', classes:'underline'})">Under score</button>
<div id="word-document" contenteditable>Starting Text</div>
Комментарии:
1. На самом деле я просто читал этот учебник
![]()
2. @DavidFrick итак, сложная часть будет заключаться в том, какой выбор тега начинается с startContainer и заканчивается в endContainer . А затем правильно закрыть и открыть тег, чтобы избежать несоответствия тегов
3. Итак, давайте возьмем этот javascript: « действие функции ({тег, классы}, событие) { // Получаем текстовый документ пусть text = document.getElementById(«word-document»); var start = text.SelectionStart; // получаем индекс последнего выбранного символа var finish = text.selectionEnd; // получить выделенный текст var sel = text.value.substring(start, finish); // сделать что-то с выбранным содержимым console.log(sel.parentNode); } « Поскольку я включен, я должен сделать это таким образом. К сожалению, это также связано с текстовой областью по сравнению с div, который можно редактировать, поскольку
4. Firefox это не нравится
5. вы не можете иметь вложенные теги внутри текстовой области …. вот почему contenteditable . и в firefox может быть много выбранных диапазонов, chrome not’, поэтому из-за этой разницы может возникнуть другое поведение