#javascript #highlighting
#javascript #выделение
Вопрос:
Я пытаюсь создать простой цветной маркер, используя текстовую область, вызывающую функцию при вводе клавиши, и div для вывода результата (выделенный / цветной текст).
Выделяемые слова и связанный с ними цвет сохраняются в этом объекте :
var obj = {
"to": "green",
"code": "red",
"applet": "blue"
}
Затем входная строка разбивается на словосочетания, чтобы проверить, соответствуют ли они obj
ключам.
var splitRequest = input.value.toLowerCase().split(' ');
Если они это делают, то они должны быть выделены. Я написал простой код, который выполняет трюк (см. fiddle в конце), за исключением этой строки :
output.innerHTML = '<span style="color:' obj[splitRequest[i]] '">' splitRequest[i] " </span>";
Он печатает весь текст при каждом нажатии клавиши вместо замены текущего содержимого на новое из-за =
знака. Проблема в том, что я не могу просто использовать =
знак, потому что он будет печатать только первый элемент splitRequest
массива вместо всего массива. Я пытался использовать join()
метод, но он, очевидно, не сработал так, как я ожидал (тест).
Возможно, сам код не так хорош, и мне следует использовать другой подход, чтобы заставить его работать. Это был бы отличный способ лучше изучить javascript, но я на самом деле понятия не имею, как это сделать.
Как я могу выводить текст, который вводит пользователь, выделяя соответствующие слова, без возникновения этой проблемы?
Вот рабочая демонстрация, в которой я застрял: https://jsfiddle.net/Lau1989/9oL7umtt/1 /
Спасибо за вашу помощь
PS: Я знаю, что для подсветки синтаксиса доступны сторонние программы, но ради самообразования я пытаюсь закодировать его с нуля, используя чистый javascript (без jQuery).
Комментарии:
1.
<font>
Тег был устаревшим в HTML 4.01 . Вам больше не следует его использовать. Замените его на:<span style="color:...">...</span>
Ответ №1:
Добавить
output.innerHTML = "";
после
var output = document.getElementById('output');
в СТРОКЕ 9
Комментарии:
1. Боже мой… Я уже пробовал это, но добавил не в ту строку (внутри цикла for). Теперь все работает нормально, спасибо!
2. проблем нет. множество самых сложных ошибок вызвано самыми простыми вещами — вот почему у них есть QA
Ответ №2:
вот рабочее решение
var obj = {
"to": "green",
"code": "red",
"applet": "blue"
}
function highlight() {
var input = document.getElementById('input');
var output = document.getElementById('output'),
pattern = /s (to|code|applet)(?=s )/gi;
output.innerHTML = input.value.replace(pattern, function (x) {
return "<span style="color:" obj[x.toLowerCase().trim()]
""> " x "</span>" });
}
Комментарии:
1. Отличный ответ, я просто пытался использовать regExp в своем коде. Есть ли какой-либо способ заставить шаблон динамически соответствовать свойствам объекта, используя переменную вместо использования предопределенных ключей? Что-то вроде
for (var prop in obj) { pattern = /s (/ prop /)(?=s )/gi; }
вместо(to|code|applet)
было бы здорово. У меня возникли проблемы с поиском правильного синтаксиса, поскольку я еще не очень хорошо знаком с регулярным выражением.2. смотрите в ответе
Ответ №3:
вы можете использовать это. var obj = { «to»: «зеленый», «code»: «красный», «applet»: «синий» }
props = [];
for (var p in obj) {
props.push(p);
}
var pat = new RegExp("\s (" props.join("|") ")(?=\s )", "gi");
alert(pat);
function highlight() {
var input = document.getElementById('input');
var output = document.getElementById('output');
output.innerHTML = input.value.replace(pat, function (x) { return "<span style="color:" obj[x.toLowerCase().trim()] ""> " x "</span>" });
}
Ответ №4:
Вот пример стиля ES2015 / ES6, использующий отображение / уменьшение и строковые шаблоны.
'use strict'
const obj = {
"to": "green",
"code": "red",
"applet": "blue"
}
const output = document.getElementById('output')
document.getElementById('input')
.addEventListener('keyup', highlight)
/**
* Process text and provides provides that text in output control
*/
function highlight() {
output.innerHTML = processText(input.value.toLowerCase())
}
/**
* Process text and returns formatted HTML text to be displayed
*
* @param {string} text - text to be processed
* @return {string} - formatted HTML text
*/
function processText(text) {
return text.split(' ')
.map(x => obj[x] ? `<span style="color: ${obj[x]}">${x}</span>` : x)
.reduce((prev, cur) => `${prev} ${cur}`)
}
/**
* Trigger first time hightlight function
* so it will highlight text if there is any text in input contol
*/
highlight()
textarea {
padding: 10px;
}
div {
width: 235px;
height: 80px;
border: 1px solid black;
padding: 10px;
overflow: auto;
color: black;
}
<textarea cols="30" rows="5" id="input" autofocus>To code or not to code this Applet</textarea>
<div id="output"></div>