美文网首页
vue富文本编辑器@人功能tinymce

vue富文本编辑器@人功能tinymce

作者: yonglei_shang | 来源:发表于2021-11-11 16:48 被阅读0次

    获取光标的位置插件 caret-pos

    import { position, offset } from 'caret-pos'
    // 设置@人弹窗的位置
    const setDialogPos = () => {
                nextTick(() => {
                    const frame = document.getElementById('tinymces' + edittorIndex.value + '_ifr')
                    // 编辑器dom ,has contenteditable atrribute
                    const body = frame.contentWindow.document.body
                    const html = frame.contentWindow.document.getElementsByTagName('html')[0]
                    // markAtEl为当前光标在哪个元素,此值可设可不设
                    const startElStyle = window.getComputedStyle ? window.getComputedStyle(markAtEl.value, '') : markAtEl.value.currentStyle
                    const lineH = parseInt(startElStyle['line-height']) ? parseInt(startElStyle['line-height']) : parseInt(startElStyle['font-size']) + 10
                    // dialogEl 为弹窗dom
                    const childEle = dialogEl.value
                    const parentW = body.offsetWidth
                    const htmlH = html.clientHeight
                    const childW = dialogEl.value.offsetWidth
                    const childH = dialogEl.value.offsetHeight
                    // 因为tinymce为iframe 中,所以要获取iframe 的位置
                    const pos = position(body, { iframe: frame })
                    const off = offset(body, { iframe: frame })
                    // 弹框偏移超出父元素的宽高
                    if (parentW - pos.left < childW) {
                        childEle.style.left = off.left - childW + 'px'
                    } else {
                        childEle.style.left = off.left + 'px'
                    }
                    if (htmlH - pos.top < childH) {
                        childEle.style.bottom = htmlH - (off.top - html.scrollTop) + 10 + 'px'
                        childEle.style.top = ''
                    } else {
                        childEle.style.top = off.top - html.scrollTop + 40 + lineH + 'px'
                        childEle.style.bottom = ''
                    }
                })
            }
    

    tinymce 富文本编辑器初始化设置

    // init编辑器的配置参数
    // 要想自己删除@人的时候是整个人名删除而不是一个文字文字的删除只需要引入 noneditable 插件即可
    const settings = {
                    selector: '#tinymces' + index.value,
                    language_url: '/tinymce/zh_CN.js',
                    skin_url: '/tinymce/skins/oxide',
                    content_css: '/tinymce/skins/oxide/content.css',
                    language: 'zh_CN',
                    height: height.value,
                    plugins: 'lists wordcount noneditable',
                    toolbar: 'bold italic |  strikethrough underline | bullist numlist | mybutton',
                    valid_elements: '*[*]',
                    valid_children: '*[*]',
                    menubar: false,
                    branding: false,
                    statusbar: false,
                    SelectVal: '',
                    fontsize_formats: '12px 14px 16px 18px 24px 36px 48px 56px 72px',
                    setup: function(editor) {
                        // 功能按钮中添加自定义的button
                        editor.ui.registry.addButton('atPeople', {
                            icon: 'paste-text',
                            tooltip: '@人员',
                            text: '@',
                            onAction: function() {
                                atPeopleShowSet()
                            }
                        })
                    }
                }
    // ...
    // show@弹框设置
            const atPeopleShowSet = () => {
                state.isShow = true
                // 获取当前光标在哪个dom 中
                state.selectionStart = state.activeEditor.selection.getStart()
            }
            // @人插入到富文本编辑器
            const selectPeople = (item) => {
                // 在编辑器中插入选择的要@的人
                state.activeEditor.execCommand('mceInsertContent', false, `<span style="color: #0089ff" class="mceNonEditable">@${item.name}</span>`)
                state.isPeopleSelect = true
            }
    

    注意:
    在选择人后弹框隐藏,此时编辑器应该获取焦点,这时用 state.activeEditor.execCommand('mceInsertContent... 这个方法插入内容时编辑器会自动出发 focus事件然后blur 事件,所以要使编辑获取焦点需要在blur事件中再调用编辑获取焦点事件

    // 编辑器中插入@人后,在编辑器 blur事件中调用编辑器获取焦点方法
    const ifra = document.getElementById('tinymces' + index.value + '_ifr')
    ifra.focus()
    

    相关文章

      网友评论

          本文标题:vue富文本编辑器@人功能tinymce

          本文链接:https://www.haomeiwen.com/subject/pbpizltx.html