1.插件
npm i react-quill
2.在modules->toolbar->container加上
{ list: 'check' }
3.现在有个问题,用户要求渲染的时候也可以点击checkbox
html代码渲染(这边框架是react)
<div
className="list-content-text ql-editor"
dangerouslySetInnerHTML={{ __html:content }}
id={`meetingSummaryContentDom40`}
>
</div>
把ul这个标签的data-checked属性替换就行
页面下个延时拿到点击li标签的操作(因为每次渲染dom都会重新生成,会导致点击事件消失)
setTimeout(() => {
/*
每次渲染都要重新设置监听(每次选择父文本的dom都重新渲染了),暂时先这样处理,延时设置监听,
不过originalChatRecords数据量大就有点麻烦,暂时找不到更好方法
*/
calcContentSetOnClickDomLi();
}, 50);
function calcContentSetOnClickDomLi() {
const contentDom = document.getElementById(`meetingSummaryContentDom40`);
const liDomList = contentDom?.getElementsByTagName('li');
if (liDomList) {
for (let i = 0; i < liDomList.length; i++) {
liDomList[i].index = i;
liDomList[i].onclick = function () {
// 存在这个属性就是checkbox
if (this.parentElement?.hasAttribute('data-checked') && this.parentElement?.nodeName === 'UL') {
console.log('handleContentSetCheckbox触发', this.index);
handleContentSetCheckbox({
content:'`<ul data-checked="false"><li>第一个</li></ul><ul data-checked="false"><li>第二个</li></ul><ul data-checked="true"><li>第三个</li></ul><p>第二次</p><ul data-checked="false"><li>第一个</li></ul><ul data-checked="false"><li>第二个</li></ul><ul data-checked="true"><li>第三个</li></ul><ul><li>uel</li><li>dsad</li><li>dsad</li></ul><ol><li>212</li><li>2121</li><li>2121</li></ol>`'
}, this.index);
}
};
}
}
}
/*
chatRecord 富文本详情信息
clickLiIndex 点击li标签的index
*/
async function handleContentSetCheckbox(chatRecord, clickLiIndex) {
const { content } = chatRecord;
const ulDomList = [];
const ulRe = /<ul[^>]*>([\s\S]*?)<\/ul>/g;
let ulExecList;
while ((ulExecList = ulRe.exec(content)) !== null) {
ulDomList.push({
// 记录匹配的初始下标,方便后面修改替换
index: ulExecList.index,
content: ulExecList[0],
});
}
// 下面的逻辑需要(记录是否查找到该li标签)
let seekedLiIndex = -1;
// 是否查找到并且完成了
let isSeekedFinish = false;
// 新替换的文档内容
let contentNew = '';
ulDomList.some((ulDomItem) => {
const liDomList = ulDomItem.content.match(/<li[^>]*>([\s\S]*?)<\/li>/g);
if (Array.isArray(liDomList)) {
// 用来记录当前点击的li标签在当前ul的下标(数组下标)
let seekedCurrentLiIndex = -1;
liDomList.some((liDomItem, liDomIndex) => {
seekedLiIndex = seekedLiIndex + 1;
if (seekedLiIndex === clickLiIndex) {
seekedCurrentLiIndex = liDomIndex;
isSeekedFinish = true;
return true;
}
return false;
});
if (isSeekedFinish) {
// 截取ul前面标签信息(比如:<ul data-checked="true"> )
const onlyUlFirstContent = ulDomItem.content.replace(/(<ul[^>]*>)([\s\S]*?)<\/ul>/, '$1');
const isChecked = onlyUlFirstContent.includes('data-checked="true"');
// 当前ul在当前content的位置
const ulInContentIndex = ulDomItem.index;
const startContent = content.slice(0, ulInContentIndex);
const endContent = content.slice(ulInContentIndex + ulDomItem.content.length);
const ulContentNewList = [];
liDomList.forEach((liDomItem, liDomIndex) => {
if (liDomIndex === seekedCurrentLiIndex) {
ulContentNewList.push(`<ul data-checked="${!isChecked}">${liDomItem}</ul>`);
} else {
ulContentNewList.push(`<ul data-checked="${isChecked}">${liDomItem}</ul>`);
}
});
// 前后content跟替换完成的ul拼接
contentNew = `${startContent ? startContent : ''}${ulContentNewList.join('')}${endContent ? endContent : ''}`;
}
}
return isSeekedFinish;
});
// 如果查找到了就是修改了
if (isSeekedFinish) {
const chatRecords = [...store.originalChatRecords];
const findSelectedTaskIndex = chatRecords.findIndex((item) => item.recordId === chatRecord.recordId);
if (findSelectedTaskIndex !== -1) {
chatRecords[findSelectedTaskIndex] = { ...chatRecords[findSelectedTaskIndex], content: contentNew };
// 直接设置,不等接口拉取,避免卡顿
store.setOriginalChatRecords([...chatRecords]);
try {
await updateChatRecord({
recordId: chatRecord.recordId,
title: chatRecord.title,
content: contentNew,
});
} catch (error) {
// 失败才重新拉取
calcGetStoryChatRecord();
if (error.isCodeErr) {
message.error(`修改信息纪要失败,${error.msg}`);
} else {
message.error(`修改信息纪要失败`);
}
}
}
}
}
4.html替换demo(上面写的是本人代码里面的,可能不清晰)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
const content = `<ul data-checked="false"><li>第一个</li></ul><ul data-checked="false"><li>第二个</li></ul><ul data-checked="true"><li>第三个</li></ul><p>第二次</p><ul data-checked="false"><li>第一个</li></ul><ul data-checked="false"><li>第二个</li></ul><ul data-checked="true"><li>第三个</li></ul><ul><li>uel</li><li>dsad</li><li>dsad</li></ul><ol><li>212</li><li>2121</li><li>2121</li></ol>`;
function handleContentSetCheckbox(chatRecord, clickLiIndex) {
const { content } = chatRecord;
const ulDomList = [];
const ulRe = /<ul[^>]*>([\s\S]*?)<\/ul>/g;
let ulExecList;
while ((ulExecList = ulRe.exec(content)) !== null) {
ulDomList.push({
//记录匹配的初始下标,方便后面修改替换
index:ulExecList.index,
content:ulExecList[0]
})
}
// 下面的逻辑需要(记录是否查找到该li标签)
let seekedLiIndex = -1;
// 是否查找到并且完成了
let isSeekedFinish = false;
// 新替换的文档内容
let contentNew = '';
ulDomList.some((ulDomItem) => {
const liDomList = ulDomItem.content.match(/<li[^>]*>([\s\S]*?)<\/li>/g);
if (Array.isArray(liDomList)) {
// 用来记录当前点击的li标签在当前ul的下标(数组下标)
let seekedCurrentLiIndex = -1;
liDomList.some((liDomItem, liDomIndex) => {
seekedLiIndex = seekedLiIndex + 1;
if (seekedLiIndex === clickLiIndex) {
seekedCurrentLiIndex = liDomIndex;
isSeekedFinish = true;
return true;
}
return false;
});
if (isSeekedFinish) {
// 截取ul前面标签信息(比如:<ul data-checked="true"> )
const onlyUlFirstContent = ulDomItem.content.replace(/(<ul[^>]*>)([\s\S]*?)<\/ul>/, '$1');
const isChecked = onlyUlFirstContent.includes('data-checked="true"');
// 当前ul在当前content的位置
const ulInContentIndex = ulDomItem.index;
const startContent = content.slice(0, ulInContentIndex);
const endContent = content.slice(ulInContentIndex + ulDomItem.content.length);
const ulContentNewList = [];
liDomList.forEach((liDomItem, liDomIndex) => {
if (liDomIndex === seekedCurrentLiIndex) {
ulContentNewList.push(`<ul data-checked="${!isChecked}">${liDomItem}</ul>`);
} else {
ulContentNewList.push(`<ul data-checked="${isChecked}">${liDomItem}</ul>`);
}
});
// 前后content跟替换完成的ul拼接
contentNew = `${startContent ? startContent : ''}${ulContentNewList.join('')}${endContent ? endContent : ''}`;
}
}
return isSeekedFinish;
});
console.log("旧content。。。。。。。。。。。。。")
console.log(content)
console.log("新content。。。。。。。。。。。。。")
console.log(contentNew)
}
//将下标为4的li的checkbox替换(模拟点击了下标为4的li)
handleContentSetCheckbox({
content
},4);
</script>
</body>
</html>