|
@@ -0,0 +1,202 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <article :id="id" :style="styles">
|
|
|
+ <a id="edit-btn" href="javascript:;" @click="() => styleHandle('bold')">加粗</a>
|
|
|
+ <a id="edit-btn" href="javascript:;" @click="() => styleHandle('italic')">italic</a>
|
|
|
+ <a id="edit-btn" href="javascript:;" @click="() => styleHandle('enableInlineTableEditing')">表格</a>
|
|
|
+ <a id="edit-btn" href="javascript:;" @click="() => styleHandle('backColor', '#666')">背景颜色</a>
|
|
|
+ <a id="edit-btn" href="javascript:;" @click="() => insertTable()">插入表格</a>
|
|
|
+ <div :id="'editor_'+id" contenteditable="true" style="display:inline-block;border:1px solid #eee; width:200px; height:200px" class="editor" v-html="value">
|
|
|
+ <p>12321</p>
|
|
|
+ </div>
|
|
|
+ <!-- <div :id="'tinymce_'+id" class="editor" contenteditable="true" style="display:inline-block;border:1px solid #eee; width:300px; height:200px">
|
|
|
+ <p>12321</p>
|
|
|
+ </div> -->
|
|
|
+ <div id="menu">
|
|
|
+ <div class="menu" @click.stop="getCursorPosition">功能1</div>
|
|
|
+ <div class="menu">功能2</div>
|
|
|
+ <div class="menu">功能3</div>
|
|
|
+ <div class="menu">功能4</div>
|
|
|
+ <div class="menu">功能5</div>
|
|
|
+ </div>
|
|
|
+ </article>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ props: {
|
|
|
+ id: {
|
|
|
+ type: String,
|
|
|
+ default: '',
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ value: {
|
|
|
+ type: String,
|
|
|
+ default: '',
|
|
|
+ required: false
|
|
|
+ },
|
|
|
+ height: {
|
|
|
+ type: Number,
|
|
|
+ default: 200,
|
|
|
+ required: false
|
|
|
+ },
|
|
|
+ styles: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return { }
|
|
|
+ },
|
|
|
+ required: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ inputValue: '',
|
|
|
+ edit: false,
|
|
|
+ init: {
|
|
|
+ auto_focus: true,
|
|
|
+ language_url: '/tinymce/langs/zh_CN.js',
|
|
|
+ language: 'zh_CN',
|
|
|
+ skin_url: '/tinymce/skins/ui/oxide', // 编辑器需要一个skin才能正常工作,所以要设置一个skin_url指向之前复制出来的skin文件
|
|
|
+ height: this.height,
|
|
|
+ browser_spellcheck: true, // 拼写检查
|
|
|
+ branding: false, // 去水印
|
|
|
+ elementpath: false, // 禁用编辑器底部的状态栏
|
|
|
+ statusbar: false, // 隐藏编辑器底部的状态栏
|
|
|
+ paste_data_images: true, // 允许粘贴图像
|
|
|
+ menubar: false, // 隐藏最上方menu
|
|
|
+ fontsize_formats: '14px 16px 18px 20px 24px 26px 28px 30px 32px 36px', // 字体大小
|
|
|
+ file_picker_types: 'image',
|
|
|
+ images_upload_credentials: true,
|
|
|
+ plugins: 'lists table textcolor wordcount contextmenu', // 引入插件
|
|
|
+ toolbar: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent table | undo redo | removeformat formatselect',
|
|
|
+ table_toolbar: 'tableprops | tableinsertrowbefore tableinsertrowafter tabledeleterow | tableinsertcolbefore tableinsertcolafter tabledeletecol | tablemergecells tablesplitcells'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ value: {
|
|
|
+ handler(newV, oldV) {
|
|
|
+ this.inputValue = newV
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ const editor = document.getElementById(`editor_${this.id}`)
|
|
|
+ editor.oncontextmenu = function(e) {
|
|
|
+ console.log(11111)
|
|
|
+ // 取消默认的浏览器自带右键 很重要!!
|
|
|
+ e.preventDefault()
|
|
|
+
|
|
|
+ // 获取我们自定义的右键菜单
|
|
|
+ var menu = document.querySelector('#menu')
|
|
|
+ console.log(e)
|
|
|
+ // 根据事件对象中鼠标点击的位置,进行定位
|
|
|
+ menu.style.left = e.clientX + 'px'
|
|
|
+ menu.style.top = e.clientY + 'px'
|
|
|
+
|
|
|
+ // 改变自定义菜单的宽,让它显示出来
|
|
|
+ menu.style.width = '125px'
|
|
|
+ }
|
|
|
+ editor.onclick = function(e) {
|
|
|
+ console.log(2222, e)
|
|
|
+ console.log('第几列', e.target.cellIndex + 1, '第几行', e.target.parentNode.rowIndex + 1)
|
|
|
+ const ForeColor = document.queryCommandValue('ForeColor') // 字体颜色
|
|
|
+ const FontSize = document.queryCommandValue('FontSize') // 字体大小
|
|
|
+ const bold = document.queryCommandValue('bold') // 是否加粗
|
|
|
+ const italic = document.queryCommandValue('italic')
|
|
|
+ const BackgroundColor = document.queryCommandValue('BackColor')
|
|
|
+ console.log(ForeColor, FontSize, bold, italic, BackgroundColor, 111)
|
|
|
+ console.log('这是table', e.path[3])
|
|
|
+ const tableBox = e.path[3]
|
|
|
+ console.log(tableBox)
|
|
|
+ // 必须保存一下不然下面会变
|
|
|
+ // const idx = e.target.cellIndex
|
|
|
+ // 在一行添加一行
|
|
|
+ // tableBox.insertRow(e.target.parentNode.rowIndex)
|
|
|
+ // 插入一列
|
|
|
+ console.log(tableBox.rows)
|
|
|
+ for (let i = 0; i < tableBox.rows.length; i++) {
|
|
|
+ console.log(i, e.target.cellIndex)
|
|
|
+ // 在之后插入一列
|
|
|
+ // tableBox.rows[i].insertCell(e.target.cellIndex+1)
|
|
|
+ // 在之前一列
|
|
|
+ // 在之前一列插入
|
|
|
+ // tableBox.rows[i].insertCell(idx)
|
|
|
+ console.log(tableBox.rows[i])
|
|
|
+ }
|
|
|
+ // tableBox.rows[e.target.parentNode.rowIndex].insertCell()
|
|
|
+ // 用户触发click事件就可以关闭了,因为绑定在window上,按事件冒泡处理,不会影响菜单的功能
|
|
|
+ document.querySelector('#menu').style.width = 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ changeText(e) { // 富文本内容改变
|
|
|
+ this.inputValue = e
|
|
|
+ this.$emit('update:value', this.inputValue)
|
|
|
+ this.$emit('change', this.inputValue)
|
|
|
+ },
|
|
|
+ styleHandle(aCommandName, val) {
|
|
|
+ // const editor = document.getElementById('cc')
|
|
|
+ document.execCommand(aCommandName, false, val)
|
|
|
+ },
|
|
|
+ insertTable() {
|
|
|
+ const HTML = `<table border='1' border-collapse: collapse; style='border-color: #666;width:90%'>
|
|
|
+ <tr>
|
|
|
+ <td><span>123</span></td>
|
|
|
+ <td>1</td>
|
|
|
+ <td>3</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td><span>1233</span></td>
|
|
|
+ <td>4</td>
|
|
|
+ <td>5</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td><span>1235</span></td>
|
|
|
+ <td>6</td>
|
|
|
+ <td>7</td>
|
|
|
+ </tr>
|
|
|
+ </table>`
|
|
|
+
|
|
|
+ document.execCommand('insertHTML', false, HTML)
|
|
|
+ },
|
|
|
+ getCursorPosition(event) {
|
|
|
+ const editEl = event.target
|
|
|
+ // return console.log(editEl);
|
|
|
+ console.log(event)
|
|
|
+ if (editEl.selectionStart || editEl.selectionStart === 0) {
|
|
|
+ console.log(3333)
|
|
|
+ // 非IE浏览器
|
|
|
+ this.cursorPosition = editEl.selectionStart
|
|
|
+ } else {
|
|
|
+ console.log(4444)
|
|
|
+ // IE
|
|
|
+ const range = document.selection.createRange()
|
|
|
+ range.moveStart('character', -editEl.value.length)
|
|
|
+ this.cursorPosition = range.text.length
|
|
|
+ }
|
|
|
+ console.log(this.cursorPosition)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style scoped lang="scss">
|
|
|
+.editor {
|
|
|
+ border: 1px solid #666;
|
|
|
+}
|
|
|
+#menu{
|
|
|
+ width: 0; /*设置为0 隐藏自定义菜单*/
|
|
|
+ height: 125px;
|
|
|
+ overflow: hidden; /*隐藏溢出的元素*/
|
|
|
+ box-shadow: 0 1px 1px #888,1px 0 1px #ccc;
|
|
|
+ position: absolute; /*自定义菜单相对与body元素进行定位*/
|
|
|
+}
|
|
|
+.menu{
|
|
|
+ width: 130px;
|
|
|
+ height: 25px;
|
|
|
+ line-height: 25px;
|
|
|
+ padding: 0 10px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+</style>
|