wangEditor 编辑器引入demo
文档:https://www.wangeditor.com/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>wangEditor with Custom Toolbar</title>
<!-- 引入 wangEditor 的 CSS -->
<link rel="stylesheet" href="https://unpkg.com/@wangeditor/editor/dist/css/style.css">
</head>
<body>
<!-- 工具栏容器 -->
<div id="toolbar-container"></div>
<!-- 编辑器容器 -->
<div id="editor-container" style="height: 600px;border: 1px solid;"></div>
<!-- 引入 jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- 引入 wangEditor -->
<script src="https://unpkg.com/@wangeditor/editor/dist/index.js"></script>
<script>
// 防抖 开始
let debounceTimer;
const debounce = (callback, delay) => {
return (...args) => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => callback(...args), delay);
};
};
// 防抖 结束
$(document).ready(function () {
// 从 wangEditor 获取必要的模块
const { createEditor, createToolbar,i18nChangeLanguage,i18nAddResources } = window.wangEditor;
// 创建编辑器实例
const editor = createEditor({
selector: '#editor-container', // 编辑器容器
config: {
placeholder: '请输入内容...',
autoFocus: true, // 默认是否 focus ,默认为 true
readOnly: false, // 是否只读 默认为 false
scroll: false, // 配置编辑器是否支持滚动,默认为 true 。注意,此时不要固定 editor-container 的高度,设置一个 min-height 即可
maxLength: 10000,
onMaxLength: function (editor) {
// 当达到 maxlength 限制时,触发该回调函数
console.log('达到 maxlength 限制');
},
// 创建完成
onCreated : function (editor) {
// editor created
console.log('editor created');
console.log('默认支持高亮的代码语法', editor.getMenuConfig('codeSelectLang').codeLangs);
// 使用多语言
// 添加新语言,如日语 ja
// i18nAddResources('ja', {
// 支持的一些键值:https://github.com/wangeditor-team/wangEditor/issues/5361
// // 标题
// header: {
// title: 'ヘッダー',
// text: 'テキスト',
// },
// // ... 其他语言词汇,下文说明 ...
// })
// // 切换为日语 ja
// i18nChangeLanguage('ja')
// 切换语言 zh-CN 、 en
i18nChangeLanguage('zh-CN');
},
onDestroyed : function (editor) {
// editor onDestroyed
console.log('editor onDestroyed');
},
onFocus : function (editor) {
// editor onFocus
console.log('editor onFocus');
},
onBlur : function (editor) {
// editor onBlur
console.log('editor onBlur');
},
// 自定义粘贴
customPaste : function (editor,event) {
// event 是 ClipboardEvent 类型,可以拿到粘贴的数据
// 可参考 https://developer.mozilla.org/zh-CN/docs/Web/API/ClipboardEvent
// 获取粘贴的 html
const html = event.clipboardData.getData('text/html') ;
// 获取粘贴的纯文本
const text = event.clipboardData.getData('text/plain') ;
// 获取 rtf 数据(如从 word wsp 复制粘贴)
const rtf = event.clipboardData.getData('text/rtf')
console.log(html,text,rtf)
// 阻止默认的粘贴行为
// event.preventDefault()
// return false
// 继续执行默认的粘贴行为
return true
},
onChange: debounce((editor) => {
const html = editor.getHtml();
console.log('300内容变化:', html,editor.children);
}, 300), // 300 毫秒防抖
// 自定义图片菜单项的行为
MENU_CONF: {
// 自定义链接菜单项的行为
link: {
isBlank: true, // 插入链接时默认打开新窗口
check: (text, link) => {
// 自定义链接校验逻辑
if (!/^https?:\/\//.test(link)) {
alert('链接必须以 http:// 或 https:// 开头');
return false; // 阻止插入链接
}
return true; // 允许插入
}
},
// // 字号
// fontSize:{
// fontSizeList: [
// // 元素支持两种形式
// // 1. 字符串;
// // 2. { name: 'xxx', value: 'xxx' }
// '12px',
// '16px',
// { name: '24px', value: '24px' },
// '40px',
// ]
// },
// // 字体
// fontFamily:{
// fontFamilyList: [
// // 元素支持两种形式
// // 1. 字符串;
// // 2. { name: 'xxx', value: 'xxx' }
// '黑体',
// '楷体',
// { name: '仿宋', value: '仿宋' },
// 'Arial',
// 'Tahoma',
// 'Verdana'
// ]
// },
// // 行高
// lineHeight:{
// lineHeightList: ['1', '1.5', '2', '2.5']
// },
// 表情
// emotion:{
// emotions: '😀 😃 😄 😁 😆 😅 😂 🤣 😊 😇 🙂 🙃 😉'.split(' ') // 数组
// },
// 插入链接
insertLink:{
// 检查链接,也支持 async 函数
checkLink: (text, url)=> {
if (!url) {
return ;
}
if (url.indexOf('http') !== 0) {
return '链接必须以 http/https 开头'
}
return true;
// 返回值有三种选择:
// 1. 返回 true ,说明检查通过,编辑器将正常插入链接
// 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)
// 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息
},
// 解析链接
parseLinkUrl: (url)=> {
if (url.indexOf('http') !== 0) {
return `http://${url}`
}
return url;
}
},
// 编辑链接
editLink:{
checkLink: (text, url)=> {
if (!url) {
return ;
}
if (url.indexOf('http') !== 0) {
return '链接必须以 http/https 开头'
}
return true;
// 返回值有三种选择:
// 1. 返回 true ,说明检查通过,编辑器将正常插入链接
// 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)
// 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息
},
parseLinkUrl: (url)=> {
if (url.indexOf('http') !== 0) {
return `http://${url}`
}
return url;
}
},
// 插入图片
insertImage:{
// onInsertedImage 还用来 获取已删除的图片
// onInsertedImage(imageNode) 插入图片之后的回调
// onUpdatedImage 更新图片之后的回调
// checkImage(src, alt, url): boolean | undefined | string 校验图片链接
// parseImageSrc(src): string 转换图片链接
onInsertedImage(imageNode) {
if (imageNode == null) return
const { src, alt, url, href } = imageNode
console.log('inserted image', src, alt, url, href)
}
},
// 编辑图片,同insertImage
// editImage:{}
// 上传图片
uploadImage: {
// 服务端地址 必填,否则上传图片会报错。
// 服务端返回格式
// 上传成功
// {
// "errno": 0, // 注意:值是数字,不能是字符串
// "data": {
// "url": "xxx", // 图片 src ,必须
// "alt": "yyy", // 图片描述文字,非必须
// "href": "zzz" // 图片的链接,非必须
// }
// }
// 上传失败
// {
// "errno": 1, // 只要不等于 0 就行
// "message": "失败信息"
// }
server: '/upload-image', // 图片上传接口
// form-data fieldName ,默认值 'wangeditor-uploaded-image'
fieldName: 'image', // 上传文件字段名
// 单个文件的最大体积限制,默认为 2M
maxFileSize: 5 * 1024 * 1024, // 最大文件大小 (5MB)
// 最多可上传几个文件,默认为 100
maxNumberOfFiles: 10,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes: ['image/*'],
// allowedFileTypes: ['image/jpeg', 'image/png', 'image/gif'], // 允许的文件类型
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
meta: {
token: 'xxx',
otherKey: 'yyy'
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 自定义增加 http header
headers: {
Accept: 'text/x-json',
otherKey: 'xxx'
},
// 跨域是否传递 cookie ,默认为 false
withCredentials: true,
// 超时时间,默认为 10 秒
timeout: 5 * 1000, // 5 秒
// 小于该值就插入 base64 格式(而不上传),默认为 0
base64LimitSize: 10 * 1024, // 10kb
// https://www.wangeditor.com/v5/menu-config.html#回调函数
// 上传之前触发
onBeforeUpload(file) { // JS 语法
// file 选中的文件,格式如 { key: file }
return file
// 可以 return
// 1. return file 或者 new 一个 file ,接下来将上传
// 2. return false ,不上传这个 file
},
// 上传进度的回调函数
onProgress(progress) { // JS 语法
// progress 是 0-100 的数字
console.log('progress', progress)
},
// 单个文件上传成功之后
onSuccess(file, res) { // JS 语法
console.log(`${file.name} 上传成功`, res)
},
// 单个文件上传失败
onFailed(file, res) { // JS 语法
console.log(`${file.name} 上传失败`, res)
},
// 上传错误,或者触发 timeout 超时
onError(file, err, res) { // JS 语法
console.log(`${file.name} 上传出错`, err, res)
},
// 如果你不想使用 wangEditor 自带的选择文件功能,例如你有自己的图床,或者图片选择器。
// 可以通过 customBrowseAndUpload 来自己实现选择图片、上传图片,并插入图片
// 自定义选择图片
// customBrowseAndUpload(insertFn) {
// // 自己选择文件
// // 自己上传文件,并得到图片 url alt href
// // 最后插入图片
// insertFn(url, alt, href)
// }
},
// 自定义视频菜单项的行为
// 配置同上传图片
uploadVideo: {
// 上传成功
// {
// "errno": 0, // 注意:值是数字,不能是字符串
// "data": {
// "url": "xxx", // 视频 src ,必须
// "poster": "xxx.png" // 视频封面图片 url ,可选
// }
// }
// 上传失败
// {
// "errno": 1, // 只要不等于 0 就行
// "message": "失败信息"
// }
server: '/upload-video', // 视频上传接口
fieldName: 'video', // 上传文件字段名
maxFileSize: 10 * 1024 * 1024, // 最大文件大小 (10MB)
// 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 []
allowedFileTypes: ['video/*'],
onSuccess: (file, res) => {
console.log('视频上传成功:', res);
},
onFailed: (file, res) => {
console.error('视频上传失败:', res);
}
},
},
// 可选:其他编辑器配置
// 注册自定义插件
plugins: []
},
mode: 'default', // 模式 'default' 或 'simple'
});
// 自定义工具栏配置
const toolbarConfig = {
items: [
'headerSelect', // 标题
'bold', // 加粗
'italic', // 斜体
'underline', // 下划线
'strikeThrough', // 删除线
'fontSize', // 字体大小
'fontName', // 字体
'color', // 文字颜色
'bgColor', // 背景颜色
'link', // 插入链接
'justify', // 对齐方式
'quote', // 引用
'emoticon', // 表情
'image', // 插入图片
'video', // 插入视频
'table', // 插入表格
'code', // 插入代码
'undo', // 撤销
'redo', // 重做
'lineHeight', // 行高
'indent', // 缩进
'outdent', // 减少缩进
'todo', // 任务列表
'list', // 列表
'splitLine', // 分割线
'fullScreen', // 全屏
],
// 工具栏其他配置
// 用于排除不需要的工具栏项,通过键值指定不显示的菜单项
excludeKeys: ['moreText', 'moreParagraph'],
// 允许自定义插入菜单项的位置,可以通过索引指定插入的位置
// insertKeys: {
// // 自定义插入的菜单项(高级)
// index: 1,
// keys: ['bold', 'italic'] // 插入的位置及项
// },
// 允许添加自定义按钮或功能项到工具栏。例如,可以添加一个自定义按钮,通过 onClick 事件实现功能
extraItems: [
{
key: 'customButton',
icon: '<span style="font-size: 16px;">🔍</span>',
title: '自定义按钮',
onClick: () => {
alert('自定义按钮被点击');
}
},
{
key: 'customSearch',
icon: '<span style="font-size: 16px;">🔍</span>', // 自定义图标
title: '自定义搜索',
onClick: () => {
const searchTerm = prompt('请输入搜索内容:');
if (searchTerm) {
window.open(`https://www.google.com/search?q=${encodeURIComponent(searchTerm)}`, '_blank');
}
}
},
{
key: 'insertDate',
icon: '<span style="font-size: 16px;">📅</span>',
title: '插入当前日期',
onClick: () => {
const dateStr = new Date().toLocaleDateString();
editor.insertText(dateStr);
}
}
]
// 可选:其他工具栏配置
};
// 创建工具栏实例并与编辑器关联
const toolbar = createToolbar({
editor, // 关联的编辑器实例
selector: '#toolbar-container', // 工具栏容器
config: toolbarConfig, // 工具栏配置
mode: 'default', // 工具栏模式 'default' 或 'simple'
});
});
// 获取编辑器内容
function get_editor_content() {
// https://www.wangeditor.com/v5/API.html#gethtml
const html = editor.getHtml();
const text = editor.getText();
}
</script>
</body>
</html>