likes
comments
collection
share

textarea 文本输入框实现不同颜色字体方案

作者站长头像
站长
· 阅读数 13

在做一个短信/邮件模板配置的功能时,例如下图,需要在文本 textarea 组件内输入需要给用户发送的短信内容,但是每个人的姓名是不一样的,需要后端在发送短信时,将字符串里一些固定的变量(约定了变量用#号包裹)替换成真实的用户名。

textarea 文本输入框实现不同颜色字体方案

难点在于 textarea 内的变量需要用不同字体颜色进行展示,以便做区分,很合理的一个需求。

textarea 文本输入框实现不同颜色字体方案

富文本方案

富文本编辑器当然时终极完美的解决方案啦,富文本功能强大,如果这个短信/邮件配置模板后面有各种复杂功能时,还是建议使用富文本,说不定哪天产品经理说要支持图片素材的短信/邮件呢!

textarea 文本输入框实现不同颜色字体方案

但是富文本编辑器也有几个缺点(我强行想出来的😄)

  • 引入富文本需要加载过多资源,内存会占用大,如果只是实现变量不同字体颜色展示,有点杀鸡用牛刀感觉
  • 如果功能简单(例如只支持文本输入)的话,使用富文本可能还需要屏蔽掉富文本上的许多功能入口

contenteditable 方案

在一个html元素上设置 contenteditable = 'true'即可让元素可以变成可编辑状态,我相信这也是很多人能够想到的一种可能实现的方式。但是理想很丰富,显示很骨感,contenteditable还是有很多坑,反正实现起来还是挺复杂的,实际上有些富文本编辑器的技术也是利用了此特性来实现的,有兴趣的读者可以自己尝试去折腾下。

textarea 绝对定位方案

我在业余时间捣鼓了一种方式,在 textarea 输入框下面隐藏一份p标签,p标签内容即文本输入框输入的内容,不同的是下面的p标签内容是html格式的,可以支持颜色显示的。

 <div style="position:relative">
     <!--隐藏在下面,用于展示颜色-->
    <p style="width:400px;padding:8px;white-space:pre-wrap" v-html="inputText2" />
    <!--绝对定位在上面-->
    <p style="position: absolute;z-index: 1;top:0;left:0" class="textarea-wrap">
        <el-input
            ref="myTextArea"
            :model-value="inputText"
            autosize
            type="textarea"
            autofocus
            style="width:400px; "
            @input="textChange"
            @change="textChange"
        />
    </p>
</div>

js逻辑就是文字输入完后,将变量字符串替换成span标签,并设置span的样式,span有个核心样式: position:relative;z-index:10000;这样可以使得蓝色字体不会被输入框所遮挡住。

const textChange = (val) => {
    inputText.value = val
    inputText2.value
    = inputText.value
            .replaceAll('#姓名#', '<span style=\'color:#409eff;position:relative;z-index:10000;\'>#姓名#</span>')
            .replaceAll('#待上传文件总数#', '<span style=\'color:#409eff;position:relative;z-index:10000;\'>#待上传文件总数#</span>')
}

textarea输入框样式如下,这里以element-ui为例,其他框架雷同。

.textarea-wrap .el-textarea__inner{
     color:rgba(0,0,0,1);
     padding: 8px;
     caret-color: black;
     background: transparent;
     font-size:16px;
}

有几点需要注意,p标签内的字体大小需要和文本框字体大小一致,这样就可以完全重叠,使得用户感知不到。

此方案代码简单,实现起来比较轻量,性能好,在一些简单业务场景下还是可以使用的,但是对于复杂的配置模板需求,我建议还是使用富文本编辑器吧😏