前端如何动态计算输入框内文本的起始位置?

业务场景

在用户输入了描述词语的基础上,用 gpt 进行续写或扩写。然后将其应用到给定时间长度的视频中,作为解说字幕。每个视频可以解说的字幕数量有限,如果到视频结尾还未读完字幕,便不再继续。本文生成案例的提示词以"猫咪"二字为主,视频渲染素材也均为猫咪

概念

  • 建议字数:视频在渲染后能阅读的字幕量(估值),输入框左下角展示的字数
  • 当前字数:输入框右下角展示的字数
  • 截断:如果一个视频是 15-20 秒的,那估计只能阅读 75 字左右(10%+-),超出超出后文本会被截断。也就是说如果建议字数有 75 字,但是生成、输入后一共有 100 字,可能最后 25 个字都会被截断

问题

由于视频的时长是有限的 ,可能只有 15 秒、20 秒,所以可以解说字数也是有限的,语速快一点,可能也就 100 字左右。在第一版的设计中,如果生成字数超出了建议字数限制,我们会直接将后续的内容截断 。但是从实际情况看来,生成的文本中,最后一段话往往是关键句,运营希望能在视频中进行保留,因此我们需要想个方法将最后一段文本的内容记录下来。同时,如果用户在关键句的位置进行了修改,需要保留修改后的关键句。最终,在提交渲染的时候,最后一段话会被保留,文本的截断将从关键句之前开始截断,直到满足建议字数

需求分析

将一段文本分为普通文本与关键句,关键句的位置往往在最后一段/句。如果用户修改后,保留用户修改后的关键句

解决方案

  • \n分隔其他文本与关键句,维护分隔线

接口给过来的文本,是通过 sse 连接的,以前后端每次请求 ai 扩写,只会调用 gpt 一次,现在会调用 gpt生成两次文本,以\n分隔。前端在 sse 中一次性获取,获取的文本以\n分隔,维护一个分隔线

  • 当用户更改文案的时候,动态的计算分割线 的位置,也就是关键句的起始位置。我们需要区分是在其他文本处更改,还是在关键句处更改。因为如果是在其他文本处进行了增删的操作,需要对分隔线进行前移或后移。如果在关键句处更改,不需要动分割线的位置。

比如,一段文本是这样的,"Hi,今天的天气真不错,风和日丽,阳光普照,气温舒适。\n真是个出去玩的好日子!",共 39 个字符,假设说超过 30 个字符就会被截断,但是最后一句话很关键,我们可能希望最终文本哪怕被截断,也能保留最后一句。生成后可能是这样的,"Hi,今天的天气真不错,风和日丽,真是个出去玩的好日子!"。

实现

首先,我们用全文文本搜索\n的位置,获取分割线,获取后一项。当用户在输入框内进行鼠标点击的时候,记录下光标的位置,如果是鼠标框选的,就记录选框后的起始位置

注意,window.getSelection().toString()这个 api,在火狐上似乎不支持,得用 element.selectionStart和 element.selectionEnd,但后者在 chrome 上又不支持。所以文本相关的 api 真的很多坑。

当用户更改的时候,我们去对比当前的字符串和上一次结果。如果光标的起始位置小于分隔线的位置,并且当前文本中还包含完整的关键句,就直接给分割线增减变动响应字数的数字。

效果

我们可以看到,渲染出来的视频,最后一段话是输入框内的最后一句,即关键句。在保留这句话作为关键句的基础上,从后往中间截断,虽然还是会需要截断,但是我们保留了关键句,提升了视频解说字幕的完整性。

未更改

更改过

后记

实现的时候就感觉,这个方式是不是可以应用在一些富文本的产品中,做一些标记处理?本人从来没开发过富文本,但这次稍微体会了一下富文本相关的 api 有多坑,也挺有意思。也许以后可以研究研究。

如果这篇文章对你有帮助,请点赞收藏支持一下,谢谢!!!

相关推荐
POLITE32 分钟前
Leetcode 94. 二叉树的中序遍历 104. 二叉树的最大深度 226. 翻转二叉树 101. 对称二叉树 (Day 13)
算法·leetcode·职场和发展
希赛网2 分钟前
网工面试:常问技术问题汇总(3)
服务器·前端·网络·网络工程师·ospf·网工面试·技术面
WYiQIU3 分钟前
普及一下字节前端岗需要达到的强度......
前端·javascript·vue.js·面试·职场和发展
老鼠只爱大米5 分钟前
LeetCode经典算法面试题 #2:两数相加(迭代法、字符串修改法等多种实现方案详解)
算法·leetcode·链表·两数相加·字符串修改法·两数相减·大数运算
切糕师学AI11 分钟前
Win11 如何彻底阻止 Edge 后台运行
前端·edge
小阿鑫16 分钟前
32岁程序员猝死背后,我的一些真实感受
前端·后端·程序员·代码人生
qq_124987075316 分钟前
基于Spring Boot的桶装水配送管理系统的设计与实现(源码+论文+部署+安装)
java·前端·spring boot·后端·spring·毕业设计·计算机毕业设计
季明洵18 分钟前
二分搜索、移除元素、有序数组的平方、长度最小的子数组
java·数据结构·算法·leetcode
Leweslyh18 分钟前
【实战】如何在家定位国际空间站 (ISS)? —— 坐标转换的魔法 (例题 5.9)
开发语言·javascript·ecmascript
Sheep Shaun19 分钟前
深入理解AVL树:从概念到完整C++实现详解
服务器·开发语言·数据结构·c++·后端·算法