目录
前端模拟终端(一):如果我的这款 IOTerm 不是你想要的
前端模拟终端(二):部分可输入而部分不可修改的多行文本域
前端模拟终端(三):文本显示与自动换行
前端模拟终端(四):显示、输入与光标
前端模拟终端(五):看谁用了 rm -rf / 之历史记录
前端模拟终端(六):快捷输入的好助手、终端的灵魂之补全和提示
显示、输入与光标
在前端模拟终端(二)中也介绍了关于输入与光标的内容。这一篇主要讲在 IOTerm 中是怎样实现的。
首先,显示选用的元素是 div
,但是不是直接把字符串扔进 div
里就完事了。而是给每一个字符都穿上 span
小衣服,就连空格也不放过,要包裹成<span> </span>
,为什么不是<span> </span>
呢?因为这样当空格在末尾时,会被吃掉!
末尾还要空格?是的,不仅要,而且还有大用处!光标不是一个单独的 div
,而是上面提到的每一个 span
。光标在哪,哪块的 span
的颜色就不同。当然,若是背景色和字色都不一样,那就是个矩形的光标;若是只有字色不一样,而且显示单边边框,那么光标就是个竖线。至于末尾的空格,当然也是因为最后需要有个光标啦!
在前端模拟终端(三)中,自动换行函数的返回值中 numRows
和 colOffset
就是用来指示光标位置的,表示在第几行偏左多少像素。如果是用本篇中介绍的方法设置光标,那么饿就不需要知道这个位置了。不过为了实现输入法跟随输入光标,还是需要知道光标位置的,这样才能移动 input
。但也不需要想前端模拟终端(三)中那样复杂。直接通过那个 span
就能获取想知道的位置。
需要注意的是,为了获取 span
,需要保证 div
下的子元素都是需要的 span
,不能包含换行符等不显示的符号。
使用 span
,一是为了高亮,二是为了自动换行。真正的自动换行,配上前端模拟终端(三)中提到的 line-break
属性,以及前端模拟终端(二)中提到的每段一个 div
,简单、高效地实现了我们终端的主要功能——输入与显示。下面是部分主要的代码:
- 用
span
包裹每一个字符,并且高亮。
function highlightChar(char: string, style?: string) {
if (style === void 0) {
return '<span>' + char + '</span>';
}