Как непрерывно выделять текст в div при вводе - PullRequest
1 голос
/ 31 марта 2020

У меня есть приложение для работы, и меня попросили добавить больше функций, таких как: добавить несколько кнопок для текста, выделенного жирным шрифтом и текста Itali c. На входе после нажатия кнопки «Полужирный» текст, который будет набираться жирным шрифтом, оставляя прежний текст (тот, что был до нажатия кнопки «Полужирный») обычным. Я понял, что нет способа выделить часть текста на входе, поэтому я имитировал вход с помощью div:

const div = document.querySelector('div');

div.innerHTML = '';

const bold = document.getElementById('boldBtn');
const italic = document.getElementById('italicBtn')

bold.style.backgroundColor = 'white';

let previousText = '';
let boldString = '';

boldBtn.addEventListener('click', () => {
    boldBtn.classList.toggle('bold-selected');
    if (boldBtn.classList.contains('bold-selected')) {
        boldBtn.style.backgroundColor = "gray";
        previousText = div.innerHTML;
        console.log(previousText)
        div.addEventListener('keydown', boldText)
    }
    else {
        bold.style.backgroundColor = "white";
        div.removeEventListener('keydown', boldText);
    }
})

function boldText(e) {
    div.innerHTML = div.innerHTML.substr(1)
    console.log("Previous text: " + previousText);
    const NOT_ALLOWED = ['Backspace', 'Shift', 'Control', 'Alt'];
    if (!NOT_ALLOWED.includes(e.key)) {
        boldString += e.key;
        console.log("Bold text: " + boldString)
        console.log(previousText + boldString)
        div.innerHTML = previousText + "<strong>" + boldString + "</strong>"
    }
}
div {
    border: 1px solid black;
    width: 200px;
    height: 20px;
  }
  
.font-style {
    border: 1px solid blue
  }
<div contenteditable="true"></div>
<button id="boldBtn" class="font-style">Bold</button>
<button id="italicBtn" class="font-style">Italic</button>

Попробуйте написать что-то вроде «круто» в div, затем нажмите кнопку Bold, а затем введите букву. Вы увидите, что div получает этот внутренний HTML: буква + круто + полужир. И курсор установлен в начале содержимого div. Пожалуйста, помогите мне или, по крайней мере, дайте подсказку о совершенном желаемом поведении! Я провел уже 3-4 часа, и я готов сдаться ...

РЕДАКТИРОВАТЬ: я думаю, что я не дал понять: я не хочу, чтобы все содержание div было жирным , но только часть / раздел / часть этого. Если ни одна кнопка не нажата, то текст, который будет написан, должен быть обычным, если нажата кнопка «Жирный шрифт», то текст, который будет написан, должен быть жирным, как и кнопка «Itali c». Возможно, если жирный шрифт и Itali c выбраны одновременно, будущий текст должен быть выделен жирным шрифтом и itali c. Но это другой вопрос ... Пример того, что я хочу, это https://html-online.com/editor/. Удалите текст по умолчанию и просто напишите слова на левой панели, и попробуйте использовать полужирные, itali c кнопки выше. На левой панели будет сгенерированный код HTML. Мне нужна такая же функциональность ...

Ответы [ 2 ]

0 голосов
/ 03 апреля 2020

Чтобы сделать текст жирным, когда вы выбираете «жирный», получите диапазон из текущего выделения и вставьте в него элемент «сильный».

  let range=window.getSelection.getRangeAt(0);
  let elem=document.createElement('strong');
  elem.innerHTML='&#8203;'
  range.insertNode(elem);

это сделает текст жирным, то же самое относится и к вариант itali c тоже. Теперь проблема возникает, когда вам нужно отключить его, для этого мне пришлось очистить текущие диапазоны в выделении и установить диапазон в конец «div» и вставить новый элемент «span» (я использовал span для обычного текста).

Точно так же я обрабатывал и следующие случаи

  1. , когда жирный шрифт и италий c сжаты вместе (в этом случае необходимо сохранить предыдущий элемент)
  2. , когда нажата клавиша enter (div создавался и создавал проблемы, поэтому мне пришлось установить слушатель keydown и использовать document.execCommand, чтобы не создавать div, а создавать br)

Если кто-то заинтересован в обновлении моего решения, чтобы сделать его эффективным, вы добро пожаловать

var boldButton=document.querySelector('#boldBtn'),
 italicButton=document.querySelector('#italicBtn'),
contentDiv=document.querySelector('#content'),
bold=false,italic=false,range,prevElement,selection;
;
contentDiv.addEventListener('keydown',function(e){
 if (e.keyCode === 13) {
       window.document.execCommand('insertLineBreak', false, null);
       range=window.getSelection().getRangeAt(0);
       range.collapse();
       prevElement=undefined;
       if(bold) addElement('strong');
       if(italic) addElement('i');
       e.preventDefault();
      return false;
    }
    return true;
});
boldButton.addEventListener('click',function(){
    debugger
    bold=!bold;
    boldButton.classList.toggle('border-black');
    if(!bold)
      disable('bold');
    else
      addElement('strong');
});
italicButton.addEventListener('click',function(){
   debugger;
   italic=!italic;
   italicButton.classList.toggle('border-black');
   if(!italic)
       disable('italic');
    else
      addElement('i');
});
function addElement(element){
  if(!selection)selection=window.getSelection()
  range=selection.getRangeAt(0);
  let elem=document.createElement(element);
  elem.innerHTML='&#8203;'
  if(prevElement)
    range.selectNodeContents(prevElement);
  range.collapse();
  range.insertNode(elem);
  elem.focus();
  prevElement=elem;
}
function disable(elem){
 if(italic && bold) return;
setRangeAtEnd();
 let element=document.createElement('span');
 if(italic)
   element=document.createElement('i');
 else if(bold)
   element=document.createElement('strong');
 element.innerHTML='&#8203;'
 range.insertNode(element);
 range.setStart(element,1);
 element.focus();
}
function setRangeAtEnd(){
 let childNodes=contentDiv.childNodes;
 range=document.createRange();
 range.setStartAfter(childNodes[childNodes.length-1]);
 prevElement=undefined;
 if(!selection)selection=window.getSelection();
 selection.removeAllRanges();
 selection.addRange(range);

}
#content{
border:1px solid black;
height:150px;

}
.border-black{
border:2px dotted black;
}
<div id="content" contenteditable="true"></div><br>
<button id="boldBtn"  class="font-style">Bold</button>
<button id="italicBtn"  class="font-style">Italic</button>
0 голосов
/ 31 марта 2020

Да, есть выход для этого, так как вы можете использовать jquery для этого, например

<script>
$(document).ready(function () { 
$("#boldBtn").click( function() { 
$("your input id or class").keyup(function () { 
$("your input id or class").css("fontWeight", "bold");
  });
 });
});
</script>

Где указано your input id or class, если у вас есть класс, тогда укажите его как .classname или, если у вас есть запись идентификатора имеет вид #id.

Надеюсь, это поможет вам.

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