1.背景:
最近接到一个需求,在一个类似chatGpt的聊天工具中,要在对话框中设置模板,后端提供了很多模板参数,然后要求将后端返回的特殊字符转成按钮,编辑完成后在相应的位置拼接成字符串。
2.效果:
在点击发送后,页面上就是如此拼接后的字符串
当然,还进一步拓展了其功能,比如可以上传文件,解析出来后和其他字符拼接
3.实现
要注意的是:你和后端约定好特殊字符的格式,比如我这里是的是:
text:"|`社工背景`| 根据信息介绍,请你写一封内容丰富的|`诱饵类型`|电子邮件"
以下是完整的实现代码
// template 部分
<div id="text-container"> </div>
// 功能部分,我封装成了三个函数,使用时updatePageWithText传入即可
function updatePageWithText(textData:any) {
const regex = /(\|`[^`]+`\|)/g; // 匹配 |` 和 `| 之间的内容
const newText = textData.replace(regex, function (match:any) {
// 去除 |` 和 `|,同时为匹配文本创建一个可点击的 span
const cleanMatch = match.replace(/\|`|`\|/g, '');
return `<span class="green-text">${cleanMatch}</span>`;
}).replace(/\+/g, ' '); // 把 `+` 替换为空格以正确显示文本
const textContainer:any = document.getElementById('text-container');
textContainer.innerHTML = newText;
// 为所有绿色文本添加点击事件监听
const greenTexts = textContainer.querySelectorAll('.green-text');
greenTexts.forEach(function (greenText:any) {
greenText.addEventListener('click', function () {
convertToInput(this);
});
});
}
function convertToInput(element:any) {
const input = document.createElement('input');
input.type = 'text';
input.value = element.textContent;
input.className = 'green-text'; // 保持输入框具有相同的类名,这样它的外观与span时相同
// 添加失焦事件处理器以在输入结束时替换文本
input.addEventListener('blur', function () {
finishInput(element, this);
});
// 添加回车键事件处理器以在按下回车时替换文本
input.addEventListener('keydown', function (event) {
if (event.key === "Enter") {
finishInput(element, this);
}
});
element.replaceWith(input); // 替换 span 元素为输入框
input.focus();
}
function finishInput(spanElement:any, inputElement:any) {
// 创建一个新的span元素来替换输入框
const newSpan = document.createElement('span');
newSpan.textContent = inputElement.value; // 使用输入框的值
newSpan.className = 'green-text'; // 恢复原来的类名,以便保持外观和行为
newSpan.addEventListener('click', function () {
convertToInput(newSpan); // 添加点击事件,使得新的span也可以被点击并转换
});
inputElement.replaceWith(newSpan); // 替换输入框为新建的span元素
}