项目中遇到的需求,文本框输入的内容需要实时匹配并高亮
效果如下
以下代码直接取至项目中此需求核心代码,未做整理
js代码
// 正则匹配
matching(){
let {regex,regexRestCorpus}=this.state;
try{
const reg = new RegExp(regex.trim(),'gm');
let result = regexRestCorpus.match(reg);
let value = regexRestCorpus.replace(reg,'<b>$&</b>');
if(!regex || !result){
result = [];
}
this.setState({corpus:value,corpusNum:result instanceof Array && result.length,inputTextHeight: 'auto'}, () => {
const $dom = document.querySelector('#inputText .s-input');
const inputTextHeight = $dom.clientHeight > $dom.scrollHeight ? $dom.clientHeight : $dom.scrollHeight;
this.setState({ inputTextHeight });
})
}catch(err){
message.warning('正则表达式不正确!');
console.log(err)
}
}
页面代码:
<Form.Item {...formItemLayout} label="正则表达式" >
<Input.TextArea rows={4} value={regex} onInput={({currentTarget})=>this.setState({regex:currentTarget.value},()=>this.matching())}/>
</Form.Item>
<Form.Item {...formItemLayout} label="正则测试语料" >
<span>匹配到<span style={{color: "red"}}>{corpusNum}</span>个结果</span>
<div className='textareaBox' id="inputText">
<pre style={{ height: inputTextHeight }} dangerouslySetInnerHTML={{__html:corpus}}></pre>
<Input.TextArea style={{ height: inputTextHeight }} className='s-input' rows={4} value={regexRestCorpus} onInput={({currentTarget})=>this.changeCorpus(currentTarget.value)} />
</div>
</Form.Item>
样式代码:
.textareaBox{
border: 1px solid #CCCCCC;
overflow: auto;
position: relative;
height: 110px;
border-radius: 3px;
textarea.s-input{
background: none repeat scroll 0 0 transparent;
border: 0 none;
position: absolute;
left: 0px;
top: 0px;
z-index: 2;
overflow: auto;
vertical-align: top;
outline: none;
resize: none;
padding: 0;
margin: 0;
line-height: normal;
font-size: 14px;
min-height: 100%;
width: 100%;
text-align: left;
&:focus
{
border: 0 none;
outline: none;
resize: none;
}
font: 100% "courier new", monospace;
}
pre{
color: #fff;
margin: 0;
padding: 0;
width: 100%;
line-height: normal;
font-size: 14px;
text-align: left;
font: 100% "courier new", monospace;
white-space: unset;
}
pre b{
background: none repeat scroll 0 0 #FFF000;
color: #FFF000;
font-weight: inherit;
&:nth-child(2n) {
background: none repeat scroll 0 0 #c7e3ff;
color: #c7e3ff;
}
}
}
思路:
1 textarea 和pre 同步宽、高、位置,textarea在pre上方
2 用正则匹配文本框的值,把匹配到的值外部包上html标签(如这里包上的是<b></b>),
3 保持textarea和pre的字体样式统一,设置pre的字体为白色(这里因为整体背景为白色),
4 设置之前匹配替换的标签字体颜色和背景色为黄色(用:nth-child(2n)伪类来实现颜色区分,奇数一个色,偶数一个色)