最后程序员,富文本编辑器,肯定需要编辑源码功能,很多时候,编辑器本身的功能满足不了自己的需求,就需要编辑源码,wang编辑默认是不带查看源码的,这里就教大家如何优雅的添加编辑源码功能。
以下是官方的说法:
编辑器默认不支持“查看源码”和“修改源码”,但可以自己开发。 因为,使用编辑器的 editor.txt.html
可以 获取/设置 html 源码,有基础能力的支持。
实现的大概过程:
新建一个 <button>,点击时获取编辑器 html 源码要实现“查看源码”,则新建一个
<div>显示 html 源码,此时可以临时隐藏编辑器如果想要高亮源码,可以使用如 highlight.js之类的第三方插件
要实现“编辑源码”,则新建一个 <div> 编辑 html 源码,此时可以临时隐藏编辑器
其实看了基本等于没看,还要隐藏新建div层,多麻烦,可以看到在插入代码,插入链接等,他都会跳出来一个框,为何不能在这个框里编辑源代码呢?
以下是插入代码,跳出来的对话框
继续看官方文档,官方提供以下自定义菜单
const { $, BtnMenu, DropListMenu, PanelMenu, DropList, Panel, Tooltip } = E
我想大部分人都是只用了BtnMenu这个菜单吧,官方也仅仅给了这一个菜单的代码案例,我一开始也是拼命研究这个自定义菜单,发现无论如何也无法实现,后来想明白了,应该用PanelMenu这个自定义菜单,然后官方的文档又是等于啥都没说。
开发一个 Panel 菜单,可直接参考视频菜单的源码,比较好理解。看源码过程中需注意:
忽略 typescript 的类型,忽略index.ts中的MenuActive,忽略create-panel-conf.ts中的,getRandom方法,自己定义字符串即可,总之,看主流程,不要被一些不重要的事情所影响
不过可以看到,核心代码还是要参考index.ts和create-panel-conf.ts两个页面,好了,然后开始研究源码,核心就是
/**
* 创建 panel
* @param text 代码文本
* @param languageType 代码类型
*/
public createPanel(text: string, languageType: string): void {
const conf = createPanelConf(this.editor, text, languageType)
const panel = new Panel(this, conf)
panel.create()
}
就是实例化一个Panel,构造函数传参,再通过对象的create()方法创建弹出框,好了以下就是我的代码,主要说明都在注释里。
const editor = new W('#editor')
const { PanelMenu, Panel } = W
// 第一,菜单 class ,Button 菜单继承 BtnMenu class
class SourceMenu extends PanelMenu {
constructor(editor) {
const $elem = W.$(
`<div class="w-e-menu">
<i title="查看源码" class="el-icon-view"></i>
</div>`
)
super($elem, editor)
}
// 重点在这里,创建面板
createPanel () {
const panel = new Panel(this, {
width: 600,
height: 0,// 0代表根据tab自适应高度
// panel 中可包含多个 tab
tabs: [
{
// tab 的标题
title: '查看源码',
//模板,注意textarea和button的id,自己定义,不要与其他标签id冲突就行
tpl:`<div><textarea id="txtSource" type="text"
class="wang-textarea" placeholder="" style="height: 340px">
</textarea><div class="w-e-button-container">
<button type="button" id="btnSource" class="right">
确认</button></div></div>`,
//事件绑定
events: [
{
// <button>的id
selector: '#btnSource',
type: 'click',
// 点击button实现的方法
fn: () => {
// 使编辑的内容与源码textarea相同
editor.txt.html(document.getElementById('txtSource').value)
// 返回true,表示该事件执行完之后,panel要关闭。否则panel不会关闭
return true
}
}
]
} // tab end
]
})
panel.create()
}
// 菜单查看源码点击事件,将编辑的源码赋值给textarea
clickHandler () {
this.createPanel(editor.txt.html())
document.getElementById('txtSource').value = editor.txt.html()
}
tryChangeActive () {
this.active()
}
}
const menuKey = 'alertMenuKey' // 菜单 key ,各个菜单不能重复
W.registerMenu(menuKey, SourceMenu) // 全局注册菜单
最终实现效果如下