Добавить класс после возврата (или сопоставления) Javascript React

#javascript #reactjs

Вопрос:

я пытаюсь добавить класс после возврата карты, в основном я пытаюсь выделить текст после перевода каждого слова, я делаю это, добавляя к нему класс CSS. Я могу добавить класс, но только во все поле вместо слов, которые я изменил, я перепробовал много методов, но, думаю, я плохо понимаю функции, я пробовал сопоставлять, также пытался заменить их как предыдущий метод и пытался стилизовать их напрямую, но я все еще не могу этого добиться, я также пытался добавить функцию сразу после «возврата», но javascript завершает выполнение функции при вызове return…. :/

Спасибо, что уделили мне время!

  export default function Text() {

    var inputText;
    var mapObj = { blue: "azul", green: "verde", yellow: "amarillo" };
    
    function changeText() {
      inputText = document.querySelector("#inputF");
      document.getElementById("outputF").innerHTML = inputText.value.replaceAll(/b(blue|green|yellow)b(|,.$)/gi,
      function(matched){
      return mapObj[matched];
    })
    outputF.classList.add("mark");
    }
return (
    <div>
          <textarea id="inputF"></textarea>
          <button onClick={changeText}>Change</button>
          <textarea id="outputF"></textarea>   
    </div>
  );
};



///CSS

.mark{
  background-color:blue;}
 

Ответ №1:

Я бы рекомендовал использовать здесь больше React вместо собственного JS, особенно для управления состоянием этого компонента. Возможно, я немного переборщил, но я обновил ваш компонент до следующего:

 const Text = () => {
  const [input, setInput] = React.useState('');
  const [output, setOutput] = React.useState('');
  const mapObj = {
    blue: "azul", 
    green: "verde", 
    yellow: "amarillo" 
  };
    
  const changeText = (e) => {
    e.preventDefault();
    const changedText = input.replaceAll(
      /b(blue|green|yellow)b(|,.$)/gi,
      (matched) => `<span class="mark">${mapObj[matched]}</span>`
    )
    setOutput(changedText);
  }
  return (
    <form>
      <textarea 
        id="inputF" 
        value={input} 
        onChange={(e) => setInput(e.target.value)}
      />
      <button type="submit" onClick={changeText}>Change</button> 
      <div 
        id="outputF"
        dangerouslySetInnerHTML={{__html: output}}
      />
    </form>
  );
};
 

Скрипка: https://jsfiddle.net/3tc2xzms/

Для начала я добавил 2 useState крючка для управления вводом и выводом текста. А затем для части выделения каждое совпадающее слово, которое было изменено, оборачивается в a span.mark . Также область выходного текста была изменена на div.

Связанные Документы:

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

1. Потрясающе! Большое вам спасибо, Сегфолт Определенно, мне следует глубже разобраться в крючках и состояниях в React, а также в том, что это лучший вариант, потому что их текст сохраняется в локальной памяти пользователей.

Ответ №2:

Примененный вами стиль изменит цвет фона всего textarea , вместо этого вы можете использовать setSelectionRange() метод textarea, который даст вам результат, близкий к тому, что вы ожидаете.

     function changeText() {
      inputText = document.querySelector("#inputF");
      document.getElementById("outputF").innerHTML = inputText.value.replaceAll(/b(blue|green|yellow)b(|,.$)/gi,
      function(matched){
      return mapObj[matched];
    })
    // something like this
    // here you need to set start and end index for the highlights part, you can use the logic as per need
    outputF.setSelectionRange(0, inputText.value.length )
    }
 

а для изменения цвета подсветки вы можете использовать следующий css:

 ::selection {
  color: red;
  background: yellow;
}

::-moz-selection { /* Code for Firefox */
  color: red;
  background: yellow;
}
 

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

1. Привет, Арслан! спасибо за ваш отзыв, я попробовал ваш ответ и все еще не работает, в основном то, что я хочу сделать, это просто выделить слова, которые я изменил не каждое слово в текстовом поле