Как написать подобное окно для ввода текста,в котором как в ворде можно будет выбирать тип шрифта

119
02 сентября 2019, 10:30

На подобии вот этого,можно ли это написать на чистом js или нужно использовать что то большее?

Answer 1

Вот как это работает под капотом:

Мы создаем div, который имитирует поле ввода. Это всего лишь див, но теперь у нас есть возможность вставлять в него теги типа <u> или <b>. Это псевдо-поле для ввода будет видимо для пользователя.

Также мы создаем textarea, который должен быть скрыт от пользователя (в моем примере он не скрыт для наглядности). Каждый раз при клике на зеркало мы фокусируемся на этом поле и весь текст отсюда переходит в зеркало.

Теперь при клике на кнопки мы смотрим какая кнопка была нажата и в зависимости от нее добавляем в наш textarea нужный нам тег, который потом при вставке в зеркало как HTML код автоматически будет распарсен браузером.

Код чисто для демонстрации и нуждается в доработках, а лучше, для таких сложных задач не изобретать велосипеды ;)

let mirror = document.getElementById("mirror"), 
  actual = document.getElementById("actual"), 
  buttons = document.getElementsByTagName("button"); 
 
mirror.addEventListener("click", e => { 
  mirror.classList.add("active"); 
  actual.focus(); 
}); 
 
actual.addEventListener("input", e => { 
  let value = e.data; 
  if (value) { 
    mirror.innerHTML = e.currentTarget.value; 
  } 
}); 
 
Array.from(buttons).forEach(item => { 
  item.addEventListener("click", e => { 
    let element = e.currentTarget; 
    switch (element.getAttribute("data-style")) { 
      case "bold": 
        actual.value = actual.value + "<b></b>"; 
        break; 
      case "italic": 
        actual.value = actual.value + "<i></i>"; 
        break; 
      case "underline": 
        actual.value = actual.value + "<u></u>"; 
        break; 
    } 
    actual.focus(); 
    actual.setSelectionRange(actual.value.length - 4, actual.value.length - 4); 
  }); 
});
body { 
  margin: 0; 
} 
 
#actual { 
  position: relative; 
  width: 80vw; 
  height: 30px; 
} 
 
#mirror { 
  position: relative; 
  border: 1px solid gray; 
  width: 80vw; 
  min-height: 30px; 
  cursor: text; 
} 
 
#mirror.active:after { 
  content: "|"; 
  margin-left: 1px; 
}
<button data-style="italic">Курсив</button> 
<button data-style="bold">Жирный</button> 
<button data-style="underline">Подчеркнутый</button> 
 
<br>Наше зеркало для ввода. Сюда нужно начать вводить текст. 
<div id="mirror"></div> 
Куда мы вводим текст на самом деле. Сюда нужно просто смотреть, но в конечном итоге вообще скрыть это поле от глаз. 
<textarea id="actual"></textarea>

READ ALSO
Не срабатывает цикл for при обходе массива

Не срабатывает цикл for при обходе массива

не могу понять в чем проблемаСмотрим простой код:

114
Как избавиться от повторной работы кода при загрузке страниц Ajax?

Как избавиться от повторной работы кода при загрузке страниц Ajax?

Дело в том, что подгружаю страницы через ajax, просто вставив тег скрипт на загружаемую страницу(таких страниц много), и первая работает нормально,...

116
Замена символов переноса на &lt;br&gt;

Замена символов переноса на <br>

Есть <span>Текст1\nТекст2</span>

128
Подружить OwlCarousel c NanoGallery2 и Bootstrap 4?

Подружить OwlCarousel c NanoGallery2 и Bootstrap 4?

Доброго всем времени суток

126