效果:

思路: 让一个div浮动在textarea上,样式和位置保持完全一致,textarea负责输入,div负责高亮显示

代码:

.vue

<template>
<div class="highlight-contain">
<!-- 本组件是带高亮的textarea,需要接受高亮关键词数组来进行高亮 -->
<div id="highlight-area" class="input-font el-textarea" >
<div id="fake-textarea" class="el-textarea__inner" v-html="highlightHtml"></div>
</div>
<div id="input-area">
<el-input
class="input-font"
id="input-textarea"
type="textarea"
:placeholder="placeholder"
:autosize="autosize"
v-model="strValue"
@input="getHighlightHtml"
@mousemove.native="setHighlightArea('height',true)"
></el-input>
</div>
</div>
</template> <style lang="postcss">
/* 这里是为了让textarea中的文字隐藏,同时这只光标和placeholder颜色 */
#input-area .el-textarea .el-textarea__inner {
color: #606266; /* 光标的颜色*/
text-shadow: 0px 0px 0px rgba(0, 0, 0, 0); /* 文本颜色 */
-webkit-text-fill-color: transparent;
&::-webkit-input-placeholder {
color: #dcdfe6; /* 改变placeholder文本颜色 */
text-shadow: none;
-webkit-text-fill-color: initial;
}
} .highlight-contain {
position: relative;
& #highlight-area {
/* 自定义样式 */
position: absolute;
left: 0px;
top: 0px;
pointer-events: none;
& #fake-textarea {
/* color: #ec140d; */
pointer-events: none;
border: none;
resize: none;
background-color: rgba(0, 0, 0, 0);
line-height: 1.5 !important;
max-height: 590px;
overflow-y: auto;
/* 和html中的类一样,都是为了设定和textarea一模一样的样式,防止文字对接不上(这里是复制的浏览器中textarea元素属性) */
-webkit-appearance: textarea;
-webkit-rtl-ordering: logical;
-webkit-writing-mode: horizontal-tb !important;
flex-direction: column;
white-space: pre-wrap;
word-wrap: break-word;
text-rendering: auto;
letter-spacing: normal;
word-spacing: normal;
text-transform: none;
text-indent: 0px;
text-shadow: none;
text-align: start;
margin: 0em;
font: 400 14px Arial;
}
}
} /* 高亮色 */
.highlight-11 {
color: #fb4546;
}
.highlight-10 {
color: #0fed40;
}
.highlight-9 {
color: #feb71d;
}
.highlight-8 {
color: #39afea;
}
.highlight-7 {
color: #e512bf;
}
.highlight-6 {
color: #0f29ed;
}
.highlight-5 {
color: #f088c1;
}
.highlight-4 {
color: #acbb09;
}
.highlight-3 {
color: #7a152e;
}
.highlight-2 {
color: #7ca51c;
}
.highlight-1 {
color: #5e36aa;
}
.highlight-bracket {
color: #000000;
}
</style> <script lang="ts" src="./highlightTextarea.ts"></script>

.ts

import { Vue, Component, Prop } from "vue-property-decorator"
import $ from 'jquery'
@Component({}) export default class HighlightTextarea extends Vue {
/* ---- 从父元素接受参数 ---- */
@Prop()
value: string
@Prop()
placeholder: string
@Prop()
autosize: { minRows: number, maxRows: number }
@Prop()
highlightKey: string[] //要高亮的词 /* ---- 变量 ---- */
get strValue() {
return this.value ? this.value : ''
}
set strValue(val) {
this.$emit('input', val)
}
highlightHtml: string = ''; /* ---- 函数 ---- */
setHighlightArea(type: string, right?: boolean) {
if (type === 'height') {
if (right) {
let height = document.getElementById('input-textarea').style.height;
document.getElementById('fake-textarea').style.height = height;
} else {
window.setTimeout(() => {
let height = document.getElementById('input-textarea').style.height;
document.getElementById('fake-textarea').style.height = height;
}, 100);
}
} else if (type === 'scrollTop') {
if (right) {
let scroll = document.getElementById('input-textarea').scrollTop
document.getElementById('fake-textarea').scrollTop = scroll;
} else {
window.setTimeout(() => {
let scroll = document.getElementById('input-textarea').scrollTop
document.getElementById('fake-textarea').scrollTop = scroll;
}, 100);
}
}
} getHighlightHtml(val) {
if (val.split('\n').length > this.autosize.maxRows) { //超过最大行textarea有滚动时,为解决div底部不能和textarea重合,故加一个<br/>,并延时设置scrolltop
this.highlightHtml = this.highlightStr(val, this.highlightKey) + '<br/>';
this.setHighlightArea('scrollTop', false);
} else {
this.highlightHtml = this.highlightStr(val, this.highlightKey)
}
// 高亮区和输入区高度保持一致
this.setHighlightArea('height');
}
/**
* 高亮方法:
* 1.将oriStr中的高亮关键字使用“{{{关键字}}}”替换,这里防止关键词数组中有包含关系,所有用空格区分oriStr
* 2. 然后再循环highlightKey用<span class="..."></span>替换文中的{{{和}}}
* @param oriStr 要高亮的字符串
* @param highlightKey 高亮关键词
*/
highlightStr(oriStr: string, highlightKey: string[]): string {
if (!oriStr || !highlightKey || highlightKey.length === 0)
return oriStr;
let strConvert = (s: string, key: string): string => {
let rowArr = s.split('\n'); //按行进行处理
for (let i = 0; i < rowArr.length; i++) {
let strArr = rowArr[i].split(' ').filter(item => item !== '');
strArr = strArr.map(item => {
if (item === key) {
item = `{{{${item}}}}`
}
return item;
})
rowArr[i] = strArr.join(' ')
}
return rowArr.join('\n');
}
let rebuild = highlightKey.reduce(strConvert, oriStr);
let regExp;
let regStr;
for (let i = 0; i < highlightKey.length; i++) {
regStr = '\\{\\{\\{' + this.escapeString(highlightKey[i]);
regExp = new RegExp(regStr, 'g');
if (highlightKey[i] === '(' || highlightKey[i] === ')') { //小括号颜色
rebuild = rebuild.replace(regExp, `<span class="highlight-bracket">${highlightKey[i]}</span>`)
} else {
rebuild = rebuild.replace(regExp, `<span class="highlight-${i + 1}">${highlightKey[i]}`)
}
}
rebuild = rebuild.replace(/\}\}\}/g, '</span>');
return rebuild;
}
//处理字符串中可能对正则有影响的字符串
escapeString(value: string): string {
var str = value.replace(new RegExp('\\\\', 'g'), '\\\\');
var characterss = ['(', ')', '[', ']', '{', '}', '^', '$', '|', '?', '*', '+', '.'];
characterss.forEach(function (characters) {
var r = new RegExp('\\' + characters, 'g')
str = str.replace(r, '\\' + characters)
})
return str;
} /* ---- 生命周期 ---- */
mounted() {
this.highlightKey.sort((a, b) => b.length - a.length);// 为了使高亮正常,关键词长的排在前面
$('#input-textarea').scroll((e) => {
this.setHighlightArea('scrollTop', true);
});
}
}

使用:import HighlightTextarea from "..."引入后,

  <highlight-textarea
:highlightKey="['=', '<', '>', '!=', '<=', '>=', 'like', '(', ')']"
placeholder="请输入监测"
:autosize="{minRows: 4, maxRows: 10}"
v-model="str">
</highlight-textarea>

textarea怎么解析html代码,从而实现一个可高亮的输入框的更多相关文章

  1. 一步步教你为网站开发Android客户端---HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新ListView

    本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...

  2. 分析和解析PHP代码的7大工具

    PHP已成为时下最热门的编程语言之一,然而却有许多PHP程序员苦恼找不到合适的工具来帮助自己分析和解析PHP代码.今天小编就为大家介绍几个非常不错的工具,来帮助程序员们提高自己的工作效率,一起来看看吧 ...

  3. Android JSON 解析关键代码

    Android Json 解析其实还是蛮重要的知识点,为什么这么说呢,因为安卓通信大部分的协议都是使用 json 的方式传输,我知道以前大部分是使用的 xml ,但是时代在发展社会在进步,json 成 ...

  4. 使用python解析C代码

    我有一个巨大的C文件(~100k行),我需要能够解析.主要是我需要能够从其定义中获取有关每个结构的各个字段的详细信息(如结构中每个字段的字段名称和类型).是否有一个好的(开源,我可以在我的代码中使用) ...

  5. tensorflow+inceptionv3图像分类网络结构的解析与代码实现

    tensorflow+inceptionv3图像分类网络结构的解析与代码实现 论文链接:论文地址 ResNet传送门:Resnet-cifar10 DenseNet传送门:DenseNet SegNe ...

  6. 用phpQuery像jquery一样解析html代码

    简介 如何在php中方便地解析html代码,估计是每个phper都会遇到的问题.用phpQuery就可以让php处理html代码像jQuery一样方便. 项目地址:https://code.googl ...

  7. javascript 写一段代码,判断一个字符串中出现次数最多的字符串,并统计出现的次数

    javascript 写一段代码,判断一个字符串中出现次数最多的字符串,并统计出现的次数 function test(){ var bt = document.getElementById(" ...

  8. express4.0之后不会解析req.files,必须加一个插件multer

    express 4 + 用multer express4.0之后不会解析req.files,必须加一个插件multer http://www.w3school.com.cn/tags/att_form ...

  9. 双缓冲绘图和窗口控件的绘制——ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 .

    双缓冲绘图和窗口控件的绘制 ---ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 cheungmine 我们通常使用ATL COM组件,生成一个带窗口的ActiveX控件,然后 ...

随机推荐

  1. ZYNQ的Linux Linaro系统镜像制作SD卡启动

    ZYNQ的Linux Linaro系统镜像制作SD卡启动 0. 概述 ZYNQ生成uboot的时候和正常的ARM设备不太一样,ZYNQ属于二次辅助启动uboot然后由uboot启动内核,大概意思就是 ...

  2. 利用RabbitMQ、MySQL实现超大用户级别的消息在/离线收发

    由于RabbitMQ中只有队列(queue)才能存储信息,所以用RabbitMQ实现超大用户级别(百万计)的消息在/离线收发需要对每一个用户创建一个永久队列. 但是RabbitMQ节点内存有限,经测试 ...

  3. Oracle DELETE和TRUNCATE 的区别

    语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...

  4. php session存入redis

    php的会话默认以文件的形式存在,可以配知道NOSQL中,既可以提高访问速度又能好好的实现回话共享,在后期做负载均衡时实现多台服务器session 同步也是比较方便: 一:在php配置文件中改 修改p ...

  5. 180620-mysql之数据库导入导出

    文章链接:https://liuyueyi.github.io/hexblog/2018/06/20/180620-mysql之数据库导入导出/ mysql之数据库导入导出 实际工作中,需要做一下数据 ...

  6. JMeter随机上传附件

    方法一: 1.添加一个前置Beanshell 2.输入代码: File folder = new File("/path/to/your/folder/with/audiofiles&quo ...

  7. 第一模块·开发基础-第1章 Python基础语法

    Python开发工具课前预习 01 Python全栈开发课程介绍1 02 Python全栈开发课程介绍2 03 Python全栈开发课程介绍3 04 编程语言介绍(一) 05 编程语言介绍(二)机器语 ...

  8. java 实现redis缓存

    由于项目加载时请求数据量过大,造成页面加载很慢.采用redis作缓存,使二次访问时页面,直接取redis缓存. 1.redis连接参数 2.连接redis,设置库 3.配置文件开启缓存 4.mappe ...

  9. (Pyhton爬虫03)爬虫初识

    原本的想法是这样的:博客整理知识学习的同时,也记录点心情...集中式学习就没这么多好记录的了! 要学习一门技术,首先要简单认识一下爬虫!其实可以参考爬虫第一章! 整体上介绍该技术包含技能,具体能做什么 ...

  10. Spring Boot下的lombok安装 (日志) 不能识别log变量问题

    参考地址:http://blog.csdn.net/blueheart20/article/details/52909775 ps:除了要加载依赖之外 还要安装lombok插件