获取光标的位置插件 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()
网友评论