富文本配置渲染场景问题杂谈

背景

可视化页面搭建场景,需要支持配置富文本内容并在页面中渲染,富文本编辑器SDK采用了@tinymce/tinymce-react

问题场景

问题1 :文本数据转义

富文本编辑器生成的HTML富文本在服务端存储时会对字符串进行转义,比如:

'<p>3245003</p>' ----> "&lt;p&gt;3245003&lt;/p&gt;"

解决方案:
利用浏览器默认行为,通过innerHTML方法生成dom节点进行转义,然后通过DOMParser将html文本转化成dom树
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/DOMParser

const htmlToElement = (html) => {
        const parser = new DOMParser();
        const doc = parser.parseFromString(html, 'text/html');
        return doc.body.firstChild;
 }
const transformStr = (content) => {
	let div = document.createElement('div');
     div.innerHTML = content;
     return htmlToElement(`<div>${div.innerText}</div>`)
}

问题2:SSR场景hydrate模式禁用了innerHTML或者dangerouslySetInnerHTML直接渲染

使用最原始的js API

方案1:innerHTML

const C = props => {
    const {content, isSSR} = props;
    
    const wrapRef = useRef<any>();
    useEffect(() => {
        if(wrapRef.current && !isSSR) {
            wrapRef.current.innerHTML = content;
        }
      }, []);


    return (<div ref={wrapRef} />)
}


export default C;

方案2:appendChild

const C = props => {
    const {content, isSSR} = props;
    
    const wrapRef = useRef<any>();
    useEffect(() => {
        if (wrapRef.current) {
          function htmlToElement(html) {
            const parser = new DOMParser();
            const doc = parser.parseFromString(html, 'text/html');
            console.log('htmlToElement', doc, doc.body.firstChild);
            return doc.body.firstChild;
          }
          //@ts-ignore
          if (!isSSR) {
            let div = document.createElement('div');
            div.innerHTML = content;
            wrapRef.current.appendChild(htmlToElement(`<div>${div.innerText}</div>`));
          }
        }
      }, []);


    return (<div ref={wrapRef} />)
}

问题3:生成富文本体积太大

方案1

生成的富文本内容,生成文件,然后上传至oss,富文本编辑器和渲染页面分别通过cdn拉取数据内容进行渲染,

方案2

文本简化压缩,采用类似html-minifier-terser的库对生成的html文本进行处理压缩,删除无用标签、空格等内容减少体积

方案3

成本略高,只提供思路,小型编译器通过将html内容解析转化成AST,分析css样式结构进行优化,减少css样式内容,分析dom结构减少无用dom和层级

猜你喜欢

转载自blog.csdn.net/zSY_snake/article/details/136719831