文章目录
- 一、实现 Input 组件
- 二、实现 Textarea 组件
- 三、React 实践案例
API参考文档:
contenteditable
: https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/contenteditableresize
:https://developer.mozilla.org/zh-CN/docs/Web/CSS/resize
一、实现 Input 组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div {
padding: 5px;
overflow: auto;
border: 1px solid #d9d9d9;
outline: 0;
}
/* 输入框为空时显示 placeholder */
div:empty:before {
content: attr(placeholder);
color: #bfbfbf;
}
/* 输入框获取焦点时移除 placeholder */
div:focus:before {
content: none;
}
</style>
</head>
<body>
<!-- contenteditable="true" 属性,使 div 元素变成用户可编辑 -->
<div contenteditable="true" placeholder="请输入内容" onkeydown="myFunction()"></div>
</body>
<script type="text/javascript">
// 禁止回车换行
function myFunction() {
if (window.event && window.event.keyCode == 13) {
window.event.returnValue = false;
}
}
</script>
</html>
- 不禁止回车换行就会变成这个样子:
二、实现 Textarea 组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div {
resize: both;
padding: 5px;
overflow: auto;
border: 1px solid #d9d9d9;
height: 100px;
outline: 0;
}
/* 输入框为空时显示 placeholder */
div:empty:before {
content: attr(placeholder);
color: #bfbfbf;
}
/* 输入框获取焦点时移除 placeholder */
div:focus:before {
content: none;
}
</style>
</head>
<body>
<!-- contenteditable="true" 属性,使 div 元素变成用户可编辑 -->
<div contenteditable="true" placeholder="请输入内容"></div>
</body>
<script type="text/javascript">
</script>
</html>
三、React 实践案例
react 使 多行文本输入框 里面的原有文案,与生成后的推理文案,用颜色区分开来
- 效果图:
- 代码实现:
import { Button } from 'antd';
import { useState } from 'react';
export default function ({ dataset }) {
const [textArea, setTextArea] = useState('');
const [textAreaDiv, setTextAreaDiv] = useState('');
const [loading, setLoading] = useState(false);
const fetchInfer = async () => {
const title = document.getElementById('contentEditableSpanTitle')?.innerHTML ?? '';
const data = document.getElementById('contentEditableSpanData')?.innerHTML ?? '';
const params = { inputs: `${title}${data}` };
console.log('params = ', title, '---', data);
setLoading(true);
try {
const data = await api(params);
setTextAreaDiv(data.replace(title, ''));
} catch (error) {}
setLoading(false);
};
return (
<div>
<div
style={{
resize: 'both',
overflow: 'auto',
padding: '5px',
border: '1px solid #d9d9d9',
minHeight: '100px',
}}
>
<span id="contentEditableSpanTitle" contentEditable="true" style={{ border: 0, outline: 0 }}>
{textArea}
</span>
<span id="contentEditableSpanData" contentEditable="true" style={{ border: 0, outline: 0, color: '#2563eb' }}>
{textAreaDiv}
</span>
</div>
<Button onClick={fetchInfer} loading={loading} style={{ margin: '10px 0' }}>
Compute
</Button>
</div>
);
}