slatejs 中文文档_js入门基础教程

slatejs 中文文档_js入门基础教程slate.js 和 Draft.js, Prosemirror, Quill一样,都是基于结构化对象,渲染富文本编辑内容。简单的说,富文本编辑器的value不再是html,而是State Object. 看着官网的例子,感觉写个简单的应该不难,正好想认真学习下,也方便定制编辑…

公司组织的活动,发篇博文。前段时间正好项目需要富文本编辑器。同事用的draft.js,用起来麻烦。谷歌了下有啥别的解决方案,发现了slate.js,正好语雀底层也是用的slate.js定制的,就捣腾了起来。

1.官网 https://docs.slatejs.org/

slate.js 和 Draft.js, Prosemirror, Quill一样,都是基于结构化对象,渲染富文本编辑内容。简单的说,富文本编辑器的value不再是html,而是State Object.

e文不大好的同学可以看看中文的文档, github.com/loveloki/sl…

本来还想复制黏贴翻译一波官网的,有中文的大家就自己看下学习下吧。

看完walkthroughs,真的感觉既简单又实用,代码还是react hook,大厂还在用,就这个了买它买它~~当然还是很耐心的看完了ConceptsAPI

API章节没有中文翻译,大家可以锻炼下自己,看着这么详细的API,那不是更该支持一波

  1. Transforms  转换是操作文档的辅助函数(Node 结点,Selection 选择区,Text 文本)

  2. Nodes Editor的几个方法比较常用,代码中需要通过函数重写的方式进行扩展

  3. Locations 位置相关的api

  4. Refs 没看懂

  5. Miscellaneous createEditor()

2.入门 – 编辑器DEMO实例

GitHub上搜了一波,看见了这个项目github.com/Canner/cann…,但是这个项目都是2年前的了(难道是我闭门太9了,以前都没听过slate.js)

看着官网的例子,感觉写个简单的应该不难,正好想认真学习下,也方便定制编辑器。写了个简单的实例,github.com/legu2009/sl…,公司组件库用的Braft Editor,所以UI借鉴了下(大家都懂的),实在是icon折腾了大半天,没有找到开箱即用的。组件用react hook写的

slatejs 中文文档_js入门基础教程

总结下踩的小坑

  1. Toolbar Button点击,editor会失去焦点,通过onKeyDown event.preventDefault()处理
  2. 判断Selection的状态,Button选中状态。对于Text,通过 marks = Editor.marks(editor) 获取当前的状态判断。对于Element,通过 Editor.nodes(editor, { match: (n) => n.type === 'xxx' })迭代进行查找
  3. Link DropDown 里面有个input,没办法onKeyDown event.preventDefault() 处理,所以通过 tmpSelection 缓存,Transforms 之前通过Transforms.select(editor, tmpSelection.current);恢复Selection, 在DropDown关闭的时候也进行恢复,并HTMLElement.focus() 

    const onDropDownHide = () => {
        if (isNewLink.current) {
            Transforms.select(editor, tmpSelection.current);
            unwrapLink(editor);
            isNewLink.current = false;
        }  
        getContainerNode().querySelector(".slate-content").focus();
    };
    //行级别元素和文本才能处在一个children中,所以需要重写
    isInlineeditor.isInline = (element) => {
        return element.type === "link" ? true : isInline(element);
    };

  4. Link 的交互和别的富文本差别  DropDown显示的时候,如果是选择了一段文本,则默认先加个空链接,在编辑url的时候,用户也能知道设置的文本。如果选择的内容和一段链接有交集的话,设置新的链接会把原来的清除
  5. 水平线HR 判断如果是文章末尾的话,就多插入一行。并且选择区移动到插入hr的后一个位置,方便删除。API不熟,可能有更简便的写法

    const insertLine = (editor) => {
        let editorEnd = Editor.end(editor, []);
        let selection = editor.selection;
        let [selectionStart, selectionEnd] = Range.edges(selection);
        let isEditorEnd = false;
        if (selection) {
            if (Point.equals(editorEnd, selectionEnd)) {
                isEditorEnd = true;
            }
        }
        if (Point.equals(selectionStart, selectionEnd) && isEditorEnd) {
            //最后一行
            if (editorEnd.offset === 0 && editorEnd.path.length === 2 && editorEnd.path[1] === 0) {
                Transforms.removeNodes(editor, {
                    at: selection
                });
            }
        }
        Transforms.insertNodes(editor, {
            type: 'hr',
            children: [{ text: '' }]
        });
        if (isEditorEnd) {
            Transforms.insertNodes(editor, {
                type: 'paragraph',
                children: [{ text: '' }]
            });
        } else {
            let anchor = editor.selection.anchor;
            let path = anchor.path.map((item) => item);
            path[path.length - 2]++;
            Transforms.select(editor, {
                path,
                offset: 0
            });
        }};
    //hr组件没有内容可以编辑,所以重写
    isVoideditor.isVoid = (element) => {
        return element.type === 'hr' ? true : isVoid(element);
    };
    //Element contentEditable={false} 控制不能编辑,image,video,mention都是通过配套设置的
    const HR = React.memo(({ attributes, children, element }) => {
        const selected = useSelected();
        const editor = useSlate();
        const fn = () => {
            Transforms.removeNodes(editor);
        };
        return (
            <div contentEditable={false} {...attributes}> <div className={'slate-hr' + (selected ? ' active' : '')}> <div className="slate-content-toolbar" onClick={fn}> <a>&#xe9ac;</a> </div> </div> {children} </div>
        );
    });
  6. 网上的中文输入法问题(忘记先Issues里搜下)。看了下页面错误效果,中文输入法会自己插入内容 和 State渲染出来的不一致,导致React VDom 和 Dom 不一致。我的解法是在onCompositionEnd的时候,给Text设置个Key,让编辑的Text触发重新渲染

    <Editable
        className="slate-content"
        renderElement={renderElement}
        renderLeaf={renderLeaf} 
        placeholder="Enter some rich text…"
        spellCheck={false}
        autoFocus
        onCompositionEnd={(e) => {
            Transforms.setNodes(
                editor,
                {
                    key: +new Date()
                },
                { match: Text.isText }
            );
        }}/>

  7. 图片功能 没有实现。图片涉及到上传接口功能。
  8. 表情功能 没有实现。只是写了个简单的插入@aaa,看看效果。项目中想是作为占位符替换文本的功能。
  9. 表格功能 没有实现。实在是太复杂了,面临的问题也都很难实现。包括表格选择-编辑状态交互,表格嵌套,表格合并列,合并行等等。只是试了下表格嵌套的效果。

3.放弃

各方面用起来的确是蛮爽的,但是github上没找到给力的项目,真的很尴尬

  1. 个人时间有限,能力也有限,在遇到Table组件这种复杂交互的开发,真的太难了。
  2. slate.js对IE的支持不好,MAC用多了,犯了个低级错误,选型的时候忘看IE兼容性了。slate-react用了比较多的IE不支持的API。虽然我觉得让用户装Chrome很合理,但是大家懂的,说服产品经理比说服自己难多了。
  3. 编辑器的dom结构很复杂,一个文本有这么多node,需要定制slate-reactslatejs 中文文档_js入门基础教程
  4. 中文输入法的问题,我不知道有没完全解决

4.其他

现在前端 Low Code, No Code, AI Code 正在流行,个人觉得所见即所得的编辑交互更加友好。大厂阿里的语雀编辑器不知道有没开源计划,期待。

特此悼念下美大,每次都感概大神的技术,努力和运气,每个大神背后肯定付出了更多。人生只有一次,想通过技术走上人生巅峰的小伙伴们,也多注意休息,锻炼身体。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13575.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注