CKEditor使用

2022-09-19 17:19:35 浏览数 (1)

前言

本文主要使用CKEditor4版本

CKEditor4

下载地址

https://ckeditor.com/ckeditor-4/download/

官方文档

https://ckeditor.com/docs/ckeditor4/latest/guide/dev_installation.html

CKEditor5

下载地址

https://ckeditor.com/ckeditor-5/download/

官方文档

https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/quick-start.html

该编辑器有以下几种模式

使用CKEditor

Vue Cli调用本地

把下载的包放在 public文件夹下

index.html中添加

代码语言:javascript复制
<script type="text/javascript" src="./ckeditor/ckeditor.js"></script>

页面中

代码语言:javascript复制
<div class="warp_editor">
  <textarea id="editor" rows="10" cols="80" v-model="editorData"></textarea>
</div>

样式

代码语言:javascript复制
.warp_editor {
  position: relative;
  width: 800px;
  height: 200px;
  border: 1px solid #eee;
  margin-top: 120px;
}

.cke_editable {
  width: 100%;
  height: 100%;
  overflow-y: auto;
  text-align: left;
}

初始化

代码语言:javascript复制
window.CKEDITOR.inline('editor', {height: '300px', width: '100%', toolbar: 'full'})

或者

代码语言:javascript复制
window.CKEDITOR.replace('editor', {height: '300px', width: '100%', toolbar: 'full'})

取值赋值

获取富文本

代码语言:javascript复制
let html1 = window.CKEDITOR.instances["editor"].getData();
let html2 = myeditor.getData();
console.info("html1", html1);
console.info("html2", html2);

获取纯文本内容:

代码语言:javascript复制
// inline模式(div包含)
const content = CKEDITOR.instances["editor"].container.getText();

// stand模式
const content =CKEDITOR.instances["editor"].document.getBody().getText(); //取得纯文本

如果要赋值那么就是

代码语言:javascript复制
myeditor.setData("需要赋值的内容");

监听值变化

代码语言:javascript复制
let myeditor = window.CKEDITOR.inline('editor', {height: '100%', width: '100%', toolbar: 'full'})
myeditor.on('change', () => {
  this.editorData = myeditor.getData();
});

自定义组件

InlineEditor.vue

代码语言:javascript复制
<template>
  <textarea :id="editorid" v-html="ckehtml"></textarea>
</template>

<script>

export default {
  name: "inline-editor",
  props: {
    ckehtml: {
      type: String,
      default() {
        return ""
      }
    },
    ckeid: {
      type: String,
      default() {
        return "";
      }
    }
  },
  data() {
    return {
      editorid: ""
    };
  },
  methods: {
    uuid() {
      var s = [];
      var hexDigits = "0123456789abcdef";
      for (var i = 0; i < 36; i  ) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
      }
      s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
      s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
      s[8] = s[13] = s[18] = s[23] = "-";
      return s.join("");
    }
  },
  async mounted() {
    this.editorid = this.ckeid || this.uuid();
    await this.$nextTick();
    let myeditor = window.CKEDITOR.inline(this.editorid, {
      height: '100%',
      width: '100%',
      toolbar: 'full',
      removeButtons: "Source,Save,NewPage,ExportPdf,Preview,Print,Templates,Cut,Copy,Find,Scayt,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,CreateDiv,Blockquote,Language,Link,Unlink,Anchor,Flash,Smiley,PageBreak,Iframe,ShowBlocks,Maximize,About,Paste,PasteText,PasteFromWord,Undo,Redo,Replace,SelectAll,CopyFormatting,RemoveFormat,Styles,Format,Font,FontSize,TextColor,BGColor,NumberedList,BulletedList,Outdent,Indent,BidiLtr,BidiRtl,Table,HorizontalRule,SpecialChar,Image"
    })
    myeditor.on('change', () => {
      this.$emit("change", {
        id: this.editorid,
        html: myeditor.getData()
      });
    });
  }
};
</script>

<style>
.cke_editable {
  width: 100%;
  height: 100%;
  overflow-y: auto;
  text-align: left;
}
</style>

使用

代码语言:javascript复制
<template>
  <div id="app">
    <div class="warp_editor">
      <inline-editor ckeid="my_editor" :ckehtml="editorData" @change="editor_change"></inline-editor>
    </div>
    <div class="warp_editor">
      <inline-editor :ckehtml="editorData" @change="editor_change"></inline-editor>
    </div>
  </div>
</template>

<script>
import InlineEditor from "@/components/InlineEditor";

export default {
  name: "app",
  components: {InlineEditor},
  data() {
    return {
      editorData: "<p>Content of the editor.</p>",
    };
  },
  mounted() {

  },
  methods: {
    editor_change(data) {
      console.info(data);
    }
  }
};
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

.warp_editor {
  position: relative;
  width: 600px;
  height: 200px;
  border: 1px solid #eee;
  margin-top: 120px;
}
</style>

使用ckeditor4-vue

这种方式支持的功能较少

并且扩展性不好,建议自己引用

结合VUE

代码语言:javascript复制
npm install --save ckeditor4-vue

main.js引入

代码语言:javascript复制
import CKEditor from 'ckeditor4-vue';
Vue.use(CKEditor);

页面中

代码语言:javascript复制
<template>
  <div id="app">
    <ckeditor
        class="warp_editor"
        v-model="editorData"
        :config="editorConfig"
        type="inline"
    ></ckeditor>
  </div>
</template>

<script>

export default {
  name: "app",
  data() {
    return {
      editorData: "<p>Content of the editor.</p>",
      editorConfig: {},
    };
  },
};
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

.warp_editor {
  position: relative;
  width: 400px;
  height: 200px;
  border: 1px solid #eee;
  margin-top: 120px;
}

.cke_editable {
  width: 100%;
  height: 100%;
  overflow-y: auto;
  text-align: left;
}
</style>

上传图片到服务器

默认的编辑器配置是支持粘贴的图片自动转Base64的

要想图片上传至服务器就要把 config.js中添加

代码语言:javascript复制
config.filebrowserImageUploadUrl = "";

如下

代码语言:javascript复制
CKEDITOR.editorConfig = function (config) {
  config.removeButtons = "Source,Save,NewPage,ExportPdf,Preview,Print,Templates,Cut,Copy,Find,Scayt,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,CreateDiv,Blockquote,Language,Link,Unlink,Anchor,Flash,Smiley,PageBreak,Iframe,ShowBlocks,Maximize,About,Paste,PasteText,PasteFromWord,Undo,Redo,Replace,SelectAll,CopyFormatting,RemoveFormat,Styles,Format,Font,FontSize,TextColor,BGColor,NumberedList,BulletedList,Outdent,Indent,BidiLtr,BidiRtl,Table,HorizontalRule,SpecialChar";
  config.language = "zh-cn";
  config.image_previewText = " ";
  config.exportPdf_tokenUrl = " ";
  config.removeDialogTabs = "html5video:advanced;image:advanced;image:Link"; //隐藏“超链接”与“高级选项”只留上传和预览按钮
  config.extraPlugins = "uploadimage,editorplaceholder";
  config.filebrowserImageUploadUrl = ""; //上传图片的服务器地址
  //config.filebrowserHtml5videoUploadUrl = ""; //上传视频的服务器地址";
  config.removePlugins = "elementspath,easyimage,cloudservices"; //隐藏左下角提示
  config.allowedContent = true; //允许所有标签
};

上传图片转Base64

默认的编辑器配置是支持粘贴的图片自动转Base64的

我们想点击图片上传按钮后选中图片确定也用base64保存,就要自定义插件。

plugins文件夹下添加zimage文件夹

添加以下文件

  1. plugins/zimage/plugin.js
  2. plugins/zimage/dialog/dialog.js
  3. plugins/zimage/icons/zimage.png

注意其中

第1项名称不能变。 第3项的图片名称要和定义插件时指定的名称相同,建议使用插件的名称。

plugins/zimage/plugin.js

代码语言:javascript复制
CKEDITOR.plugins.add('zimage', {
  icons: 'zimage',
  init: function (editor) {
    // 给自定义插件注册一个调用命令
    editor.addCommand('zimage', new CKEDITOR.dialogCommand('zimageDialog'));

    editor.ui.addButton('zimage', {
      // label为鼠标悬停时展示的字
      label: '添加图片',
      command: 'zimage',
      // 将插件放在哪一组toolbar, 像我这样写的话,将放在'insert'组的第一个,后面的数字是这个数据的下标
      toolbar: 'insert,0'
    });
    // 加载自定义窗口,'zimageDialog'跟上面调用命令的'zimageDialog'一致;
    CKEDITOR.dialog.add('zimageDialog', this.path   'dialog/dialog.js');
  }
});

plugins/zimage/dialog/dialog.js

代码语言:javascript复制
CKEDITOR.dialog.add('zimageDialog', function (editor) {
  return {
    title: '上传本地图片',
    minWidth: 400,
    minHeight: 100,
    contents: [
      {
        id: 'Upload',
        label: '上传',
        elements: [
          // 我这里需要一个tab页面,所以elements数组只有一个对象
          {
            // type为html表示html代码
            type: 'html',
            // 接下来html属性就可以直接写html代码了
            html: '<div>'
                '<label for="zfileupload">选择图片:</label>'
                '<input type="file" name="zfileupload" id="zfileupload">'
                '</div>',
            // 那要怎么拿到自定义窗口的元素呢?在ckeditor自带的自定义窗口里并不容易拿到,这时候我们得用到onLoad函数了
            onLoad: function () {
              // 在自定义窗口展示的时候会触发这条函数;而我们就能在这条函数里写我们的代码了;
              var ele = document.getElementById('zfileupload');
              // 给id为'zfileupload'的input绑定change事件
              ele.addEventListener('change', function () {
                // 当用户没选或者点取消的时候直接return
                if (this.files.length == 0) return;
                var imageData = this.files[0];
                // 检测后缀名
                var lastIndex = imageData.name.lastIndexOf('.');
                var imageSuffix = imageData.name.substring(lastIndex   1);
                // 判断后缀名
                if (!(imageSuffix == 'png' || imageSuffix == 'jpg' || imageSuffix == 'jpeg' || imageSuffix == 'bmp')) {
                  alert('图片格式只支持"png/jpg/jpeg/bmp格式"');
                  return
                }
                // 大小不能超过1m 
                if (imageData.size > 5 * 1024 * 1024) {
                  alert('图片大小不能超过5M');
                  return
                }
                // 使用FileReader接口读取图片
                var reader = new FileReader();
                reader.addEventListener('load', function () {
                  var imageBase64 = reader.result;
                  sessionStorage.setItem('z_image', imageBase64)
                })
                // 将图片转成base64格式
                reader.readAsDataURL(imageData)
              })
            }
          }
        ]
      }
    ],
    onOk: function () {
      // this这里就是自定窗口了,ckeditor内部封装好了。
      var dialog = this;
      // 创建img标签
      var image = editor.document.createElement('img');
      // 给img标签设置class类
      image.setAttribute('class', 'insert-image');
      var imageData = sessionStorage.getItem('z_image');
      // 将图片数据赋予img标签
      image.setAttribute('src', imageData);
      // 利用ckeditor提供的接口将标签插入到富文本框中
      editor.insertElement(image);
    },
  };
});

config.jsextraPlugins添加我们的插件名

如下

代码语言:javascript复制
CKEDITOR.editorConfig = function (config) {
  config.removeButtons = "Source,Save,NewPage,ExportPdf,Preview,Print,Templates,Cut,Copy,Find,Scayt,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,CreateDiv,Blockquote,Language,Link,Unlink,Anchor,Flash,Smiley,PageBreak,Iframe,ShowBlocks,Maximize,About,Paste,PasteText,PasteFromWord,Undo,Redo,Replace,SelectAll,CopyFormatting,RemoveFormat,Styles,Format,Font,FontSize,TextColor,BGColor,NumberedList,BulletedList,Outdent,Indent,BidiLtr,BidiRtl,Table,HorizontalRule,SpecialChar";
  config.language = "zh-cn";
  config.image_previewText = " ";
  config.exportPdf_tokenUrl = " ";
  config.removeDialogTabs = "html5video:advanced;image:advanced;image:Link"; //隐藏“超链接”与“高级选项”只留上传和预览按钮
  config.extraPlugins = "uploadimage,editorplaceholder,zimage";
  config.filebrowserImageUploadUrl = ""; //上传图片的服务器地址
  //config.filebrowserHtml5videoUploadUrl = ""; //上传视频的服务器地址";
  config.removePlugins = "elementspath,easyimage,cloudservices"; //隐藏左下角提示
  config.allowedContent = true; //允许所有标签
};

0 人点赞