проблема с выделением текста (с нуля) на выходе

#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

https://jsfiddle.net/Lauy79kv/

Комментарии:

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>