首页 > 解决方案 > 如果特定单词出现在编辑器中,则更改它们的颜色

问题描述

我有一个石板文本编辑器。我有一个单独的组件,它是由一组预定义单词映射的 div。该部分是要使用的关键字。如果它们存在于编辑器中,我希望能够更改关键字中单词的颜色以使用不同的颜色。

我考虑这个的方式是我可以将我将要在编辑器中写的单词存储在一个状态,如果有新的东西写出来,它会不断更新。而且我已经有了一系列单词。我必须以某种方式找到在这两个数组之间进行通信的方法。

我该如何处理?

代码沙箱

标签: javascriptreactjsslatejs

解决方案


我做了这个方法,不是更好的方法,但(如果我理解问题)可能有用。

const isKeyword = (word) => {
    if (value) {
      return value.some(editorObject => {
        return !!editorObject['children'].some(children => 
          children['text'].includes(word))
        })
    }
    return false; 
  }

它将查找关键字是否存在于编辑器的数据中,您可以更改内联 css 中的颜色,如下所示:

color: isKeyword(word) ? YOUR_COLOR: 'white'

这是经过修改的完整 App.js 文件。

import React, {useMemo, useState,useEffect} from "react"
import './App.css';
import { createEditor ,Node} from "slate"
import { Slate, Editable, withReact } from "slate-react"
import { IconContext } from "react-icons";
 
import { ImUndo,ImRedo } from "react-icons/im";
import {MdFormatListBulleted, MdFormatItalic,MdFormatBold,MdRedo,MdFormatUnderlined} from "react-icons/md"


function App() {
  const initialState = [{type: 'paragraph', children: [{ text: "edit me"}]}]
  const editor = useMemo( () => withReact(createEditor()), [])
  const [value, setValue] = useState(initialState);
  const [editorValue,setEditorValue] = useState();
  const [wordCount,setWordCount] = useState(0);
   const [color,setColor] = useState(false);

  const [show, setShow] = useState(false);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  useEffect(()=>{
    setEditorValue(value.map(n => Node.string(n)).join('\n'));
  },[value]);

  useEffect(() => {
    setWordCount(editorValue && editorValue.trim().split(/\s+/).length);
  },[editorValue]);
  
  console.log(editorValue);
  const wordArray = ['never','forget','to','empty','your','vacuum','bags','never','forget','to','empty','your','vacuum','bags'];

  function keywords(){
    console.log(value.[0].children.[0].text);
    setColor(true);
  }

  useEffect(() => {
     keywords();
  }, [ ])
  const tips = () => {
    return (
      <div>
        Words with emotions in your headlines/subheadline improves SEO. Check this.
      </div>
    )
  }

  const isKeyword = (word) => {
    if (value) {
      return value.some(editorObject => {
        return !!editorObject['children'].some(children => children['text'].includes(word))
      })
    }
    return false; 
  }
  return (
    <div className="container">
          <div>
            <div class="header">
                <div class="header-left" style={{margin:'5px'}}>
                  <IconContext.Provider value={{ color: '#717170', size: '10px' }}>
                  <MdFormatBold style={{padding:'10px'}}/>
                  <MdFormatItalic  style={{padding:'10px'}}/>
                  <MdFormatUnderlined style={{padding:'10px'}}/>
                   <ImUndo style={{padding:'10px'}}/>
                  <ImRedo style={{padding:'10px'}}/>
                  <MdFormatListBulleted style={{padding:'10px'}}/>

                  </IconContext.Provider>
                </div>
               
            </div>
            <div style={{margin:'20px'}}>
            <Slate editor={editor} value={value} onChange={newVal => setValue(newVal)}>
              <Editable />
            </Slate>
            </div>
          </div>
          <div className="sidebar" style={{padding:'20px',
                overflow:'scroll',height:'900px'}}> 
              <div className="Performance"> 
                <h2 className="sidebar-heading"> Performance</h2>
                <div>
                    <div style={{border:'1px solid gray',borderRadius:'5px',fontSize:'15px',padding:'5px',width:'70%',overflow:'hidden'}}>
                    <div style={{float: 'left',paddingRight:'50px'}}>
                      <div className='performance-headings'>Power Words</div>
                      <div>2/6</div>
                    </div>
                    <div><img src="https://img.icons8.com/ios/50/000000/info--v1.png" style={{height:'20px',width:'20px',float:'right'}} onMouseEnter={tips}/></div>
                    </div>
                  
                  <div style={{border:'1px solid gray',fontSize:'15px',padding:'5px',width:'70%',overflow:'hidden'}}>
                      <div style={{float: 'left'}}>
                        <div className='performance-headings'>Readability</div>
                      <div>Fairly Complex to React</div>
                      </div>
                      <div><img src="https://img.icons8.com/ios/50/000000/info--v1.png" style={{height:'20px',width:'20px',float:'right'}} onMouseEnter={tips}/></div>
                  </div>
                  <div style={{border:'1px solid gray',borderRadius:'5px',fontSize:'15px',padding:'5px',width:'70%',boxShadow: '1px 1px #888888'}}>
                  <div className='performance-headings'>Words Count</div>
                    <div>{wordCount}</div>

                    </div>
                </div>
              </div>
              <div className="Addons">
               <h2 className="sidebar-heading"> Addons</h2>
              <div style={{border:'1px solid gray',borderRadius:'5px',padding:'10px',width:'70%',  boxShadow: '2px 2px #888888'}}>
                <button style={{backgroundColor:'#612EEA',color:'white',borderRadius:'5px',border:'0px',fontSize:'20px',padding:'10px'}}>Fact Check</button>   
              </div>
              </div>
              <div className="keywordstouse">
              <h2 className="sidebar-heading"> keywords to use</h2>
 
              {wordArray.map((word,index) => (
              <div style={{borderRadius:'7px',backgroundColor: 'red', padding:'10px',width:'fit-content',textAlign:'center',margin:'5px',color: isKeyword(word) ? 'blue': 'white'}} key ={{index}}>
                {word} 
              </div>))
              }
              </div>
          </div>
  
      
    </div>
  );
}

export default App;

推荐阅读