s94-editor
v1.1.1
Published
富文本编辑器的基础模块
Downloads
16
Readme
s94-editor
富文本编辑器的基础模块,提供富文本编辑器的基础功能,界面高度自由化
安装
$ npm install s94-editor
使用
var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
属性和方法
new Editor(textarea[, config]) 构造函数,构建编辑器
range 编辑器当前的选区返回
container 编辑器的容器
textarea 编辑器的textarea,里面承载了编辑器对应的html代码
config 配置参数
menu 菜单实例对象
belongNode(dom[, test]) 向上遍历获取符合条件的节点
setRange([range]) 设定的选择范围
updateRange([range]) 更新选择范围
updateValue() 更新textarea的值
updateHtml() 更新编辑器的html内容
execCommand(name[, data]) 执行编辑命令
alignType() 文本布局类型
isbold() 是否加粗
isstrike() 是否删除线
isitalic() 是否斜体
isunderline() 是否下划线
rangePath() 路径节点列表
lastRow() 设定最后一行空白节点
encode_tag(html) 编码html中的特殊标签(form,script)
decode_tag(html) 解码encode_tag方法编译过的html
html() 当前编辑器的html代码
菜单组件属性和方法
new Editor.Menu(editor[, config]) 内置的菜单构造函数
Menu.menuList 所有注册的菜单
Editor.Menu.add(name, title, innerHTML, onclick) 注册菜单
container 菜单的容器
editor 菜单对应的编辑器
list 生成的菜单节点对象的键值对象
add(name, title, innerHTML, onclick) 添加菜单
showSelect(list[, options]) 显示自带的列表类型子菜单
showForm(list[, options]) 显示自带的表单类型子菜单
new Editor(textarea[, config])
- textarea
Node
构建编辑器容器的样本,必须为textarea元素 - config
Object
配置数据,查看详细介绍 - 返回
Editor
编辑器对象
以textarea为样本,复制textarea的所有attr来窗初编辑器的容器,同时也是用来承载编辑器对应的html代码的容器
var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
range
- 属性
Range
选择范围,查看详细介绍
获取编辑器当前的选区返回
container
- 属性
Node
编辑器的容器
获取编辑器当前所在的容器
textarea
- 属性
Node
textarea
获取编辑器构建的样本textarea元素,编辑器对应的html代码会不间断的赋值到该元素的value属性上。
但是不能完全保证该元素的value等同于
editor.html()
(例如当使用js改变了编辑器容器内的html后,没有调用updateValue
方法的时候)。所有获取编辑器内容的html依然建议调用editor.html()
方法
config
- 属性
Object
配置参数
获取编辑器当前配置参数,该对象的值是构造函数传入的
config
和默认的配置参数合并后的结果
menu
- 属性
Editor.Menu|config.Menu
菜单实例对象
编辑器的菜单实例对象
belongNode(dom[, test])
- dom
Node
开始节点 - test
Function
判断方法,方法的this
为当前判断的节点对象,方法返回true表示当前节点符合条件,默认this.nodeType===1
为判断条件 - 返回
Node|False
符合条件的节点,如果直到容器节点也没用符合的,返回false
向上遍历获取符合条件的节点
console.log(editor.belongNode(editor.range.startContainer)); //打印当前编辑的节点
setRange([range])
- range
Range
选择范围对象,查看详细介绍。默认为当前Editor
的range - 返回
Editor
编辑器对象
设定浏览器的选择范围,有获取锚地的效果。
editor.setRange();
updateRange([range])
- range
Range
选择范围对象,查看详细介绍。默认为浏览器的选择范围 - 返回
Editor
编辑器对象
更新当前
Editor
的range,该方法组件会在必要的时候自动调用
该方法调用后,会在
editor.container
上广播update:range
事件,事件对象的range属性可以获取当前Editor
的range
editor.updateRange();
updateValue()
- 返回
Editor
编辑器对象
更新textarea的value属性,该方法组件会在必要的时候自动调用,一般用于用户自定义菜单功能时,如果该功能对内容有变化的时候调用该方法,同步textarea中的值
该方法调用后,会在
editor.container
上广播update:value
事件,事件对象的value属性可以获取编辑器对应的html
editor.updateValue();
updateHtml()
- 返回
Editor
编辑器对象
更新编辑器的html内容,该方法根据textarea的value重新渲染编辑器容器的html内容。
editor.updateHtml();
execCommand(name[, data])
- name
String
执行命令名称。等同于document.execCommand
的第1个参数 - quality
mixed
执行附带参数,默认为null。等同于document.execCommand
的第3个参数,部分优化的不同 - 返回
Editor
编辑器对象
在当前编辑位置,执行编辑命令。查看详细介绍,对
document.execCommand
做了部分优化见代码示例
//createLink
editor.execCommand("createLink", "http://s94.top"); //插入 <a href="http://s94.top">http://s94.top</a>
editor.execCommand("createLink", {
text: "牧人与鱼",
href: "http://s94.top"
}); //插入 <a href="http://s94.top">牧人与鱼</a>
//foreColor、hiliteColor、bold、strikeThrough、italic、underline
editor.execCommand("bold", true); //data为true表示当选区为一个点时,在当前位置插入不占位的空白字符,方便判断当前节点是否为加粗
alignType()
- 返回
String
文本布局类型,left|center|full|right
返回当前选区的文本布局类型,是对节点的
text-align
样式结果的统一化
console.log(editor.alignType()); //left
isbold()
- 返回
Boolean
是否加粗
返回当前选区的节点文本样式是否为 加粗
console.log(editor.isbold()); //false
isstrike()
- 返回
Boolean
是否加粗
返回当前选区的节点文本样式是否为 删除线
console.log(editor.isstrike()); //false
isitalic()
- 返回
Boolean
是否加粗
返回当前选区的节点文本样式是否为 斜体
console.log(editor.isitalic()); //false
isunderline()
- 返回
Boolean
是否加粗
返回当前选区的节点文本样式是否为 下划线
console.log(editor.isunderline()); //false
rangePath()
- 返回
Array
路径节点列表,
返回当前选区的节点路径节点列表,
var nodeNamePath=[];
editor.rangePath().forEach(function(row){
nodeTypePath.push(row.nodeName);
})
console.log(nodeNamePath.join(">")); //div>p>span
lastRow()
- 返回
Node
最后一行的节点对象
检测最后一行是否为空的P标签,如果不是,添加一个空的没用样式的P标签。并返回。该方法主要用于在执行编辑内容的样式修改后,很多情况下换行后会把之前的样式带上,所以需要调用该方法获取一行没有被污染的P标签
editor.lastRow();
encode_tag(html)
- 返回
String
编码后的html代码
编码html中的特殊标签(form,script)。
编码script的目的:防止编辑的html代码里面的js代码污染
编码form的目的:当编辑器放在form表单里面的时候,如果编辑器里面存在form标签的内容,浏览器会移除form标签,造成内容丢失
console.log(editor.encode_tag('<form action=""></form><script></script>')); //<form-editor-change-tagname action=""></form-editor-change-tagname><script-editor-change-tagname></script-editor-change-tagname>
decode_tag(html)
- 返回
String
解码后的html代码
解码
encode_tag
方法编码后的html字符串
var coed = editor.encode_tag('<form action=""></form><script></script>');
var html = editor.decode_tag(code);
console.log(html); //<form action=""></form><script></script>
html()
- 返回
String
编辑器的html代码
返回当前编辑器的html代码。在
this.container.innerHTML
的基础上执行了decode_tag
和剔除了lastRow
方法加入的空白P标签
console.log(editor.html()); //.......
配置参数
- colors
Array
使用内置菜单时,设定菜单的字体颜色和背景颜色集合 - fontsizes
Array
使用内置菜单时,设定菜单的字体大小集合,长度最大为7 - image_callback
Function
使用内置菜单-图片时,此参数表示点击此菜单后的处理,确认好图片地址后,可以通过直接返回,或者执行函数接受一个参数next
然后传入图片地址,具体参考s94-js的new s94.Ready(f) - menus
Array
使用内置菜单时,设定显示的菜单列表,同时具备排序效果。 - onpaste
Function
粘贴内容处理,接收s94.fn
对象(类似jQuery对象),要求返回节点集 - Menu
Function
自定义菜单构造函数,如果传入将替换组件自带的菜单,传入当前Editor
编辑器对象
除了这些字段,开发者也可以根据自己扩展的功能,自定义配置参数字段,然后可以在
editor.config
和editor.menu.config
里面去获取。
var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'), {
colors: ['#333','rgb(194, 250, 94)'], //自定义组件菜单的字体颜色和背景颜色列表
fontsizes: ['12px','0.2rem'], //自定义字体大小列表,最多7个
menus: ['bold','color'],
onpaste: function(list){
list.forEach(function(row){
list.find('img').css("width", "100%"); //设定粘贴的图片样式
return list;
})
},
Menu: function(editor){
var dom = document.createElement('button');
dom.innerHTML = '菜单示例';
$(editor.container).after(dom);
dom.addEventListener('click', function(){
var html = `<h1>这是插入的标题</h1>`;
editor.execCommand('insertHTML', html);
editor.range = document.createRange();
var lastNode = editor.lastRow();
editor.range.setStart(lastNode, 0);
editor.range.setEnd(lastNode, 0);
editor.setRange();
})
}
});
new Editor.Menu(editor[, config])
- editor
Editor
编辑器对象 - config
Object
配置数据,类似Editor
构造函数的config
参数 - 返回
Editor.Menu
菜单实例对象
内置的菜单,一般不用不需要调用,当没有在
Editor
构造函数的config
参数设定Menu
的情况下,会自动调用,返回结果赋值到editor.menu
var menu = new Editor.Menu(editor);
Editor.Menu.menuList
- 属性
Object
全局的菜单列表
里面包含所有注册的菜单,主要用于查看已有的菜单或者修改某个菜单。如果需要自定义菜单建议调用
Editor.Menu.add(name, title, innerHTML, onclick)
方法
var Editor = require('s94-editor');
Editor.Menu.menuList['bold']['onclick'] = function(menu){
alert("这是修改后的加粗菜单功能")
}
//全局菜单的操作需要在Editor实例化之前调用
var editor = new Editor(document.querySelector('.editor-outer'));
Editor.Menu.add(name, title, innerHTML, onclick)
- name
String
组件名称,作为Menu.menuList
和menu.list
里面存储的key - title
String
鼠标放上去显示的提示信息 - innerHTML
String
组件菜单html - onclick
Function
组件菜单onclick事件回调函数,函数接收的第一个参数不是event,而是menu;this不变,为当前菜单节点对象 - 返回
Editor.Menu.menuList
所有注册的菜单键值对象
该方法用于注册菜单,一般用于全局自定义菜单,示例如下:
var Editor = require('s94-editor');
Editor.Menu.add("test", "测试菜单", '<p style="font-size: 0.6em;">测试</p>', function(menu){
var editor = menu.editor;
var html = `<h1>这是插入的标题</h1>`;
editor.execCommand('insertHTML', html);
editor.range = document.createRange();
var lastNode = editor.lastRow();
editor.range.setStart(lastNode, 0);
editor.range.setEnd(lastNode, 0);
editor.setRange();
})
//全局菜单的操作需要在Editor实例化之前调用
var editor = new Editor(document.querySelector('.editor-outer'));
container
- 属性
Node
菜单的容器
获取菜单的容器,一把用于自定义菜单位置。菜单的默认位置在编辑器容器的前方,可以使用
appendChild
方法自定义菜单位置
var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
document.querySelector('#editor-menu').appendChild(editor.menu.container); //把菜单放到#editor-menu里面去
editor
- 属性
Editor
当前菜单对应的编辑器的实例
获取当前的编辑器示例,一般用于自定义菜单里面方便调用
editor
的方法,查看详细介绍
list
- 属性
Object
生成的菜单节点对象键值对象,key为菜单的name
,{name:Node
}
菜单在实例化后,会根据
config.menus
和全局注册的菜单来生成菜单,并把生成的菜单节点对象存储在menu.list
方便调用
add(name, title, innerHTML, onclick)
- name
String
组件名称,作为menu.list
里面存储的key - title
String
鼠标放上去显示的提示信息 - innerHTML
String
组件菜单html - onclick
Function
组件菜单onclick事件回调函数,函数接收的第一个参数不是event,而是menu;this不变,为当前菜单节点对象 - 返回
Object
所有生成的菜单键值对象menu.list
添加菜单,
Menu
在实例化的时候,会遍历全局菜单列表执行此方法挨个添加菜单。同时,在实例化后,依然可以调用此方法,用于局部添加菜单,不过这样添加的菜单,不能排序,只能添加到末尾。如果需要排序,同时也不希望每个编辑器都有该菜单,请全局注册后,用config.menus
实现
var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
editor.menu.add('test2','测试2','测试',function(menu){
alert("测试2")
})
showSelect(list[, options])
- list
Array
菜单配置列表,[{innerHTML:String
, onclick:Function
}],参数说明,类似menu.add方法 - options
Object
菜单配置,{type:String
, className:String
, close:Function
}- type
String
列表布局类型,droplist
下拉菜单样式,pointlist
点阵样式。默认为droplist - className
String
自定义容器className,方便自定义样式 - close
Function
菜单关闭时的回调方法,方法this为子菜单节点对象
- type
- 返回
underfind
显示自带的列表类型子菜单,组件自带的heading、size、align、color、bgcolor都使用了该子菜单,开发者可以在自定义菜单时使用
var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
editor.menu.add('test2','测试2','测试',function(menu){
menu.showSelect([
{innerHTML: 'H1', onclick: function(menu){menu.editor.execCommand('formatBlock','h1')}},
{innerHTML: 'H2', onclick: function(menu){menu.editor.execCommand('formatBlock','h2')}},
])
})
showForm(list[, options])
list
Array
菜单配置列表,[{type:String
, name:String
, label:String
, value:String
, list:Array
, }],参数说明:- type
String
表单组件类型,可选值:textarea | select | text ,默认为text - name
String
表单组件的name,必须,在提交后,作为获取数据的键值 - label
String
表单组件的提示信息 - value
String
表单组件默认初始值 - list
Array
此字段为select
组件特有,表示下拉的option列表,格式{html:String
, value:String
}
- type
options
Object
菜单配置,{title:String
, className:String
, ok:Function
, close:Function
}- title
String
表单的标题 - className
String
自定义容器className,方便自定义样式 - ok
Function
菜单点击确定
后提交的方法,接收一个键值对对象,里面包含表单的数据,方法this为子菜单节点对象 - close
Function
菜单关闭时的回调方法,方法this为子菜单节点对象
- title
返回
underfind
显示自带的表单类型子菜单,组件自带的style、code都使用了该子菜单,开发者可以在自定义菜单时使用
var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
editor.menu.add('test2','测试2','测试',function(menu){
menu.showForm([
{name: "type", label: "操作", type: "select", value: 0, list: [
{html:"下载图片", value: 1},
{html:"直接插入图片", value: 0}
]},
{name: "src", label: "图片地址"},
], {
title: '添加图片',
ok: function(data){
if(!data.src) return;
if(data.type==0){
menu.editor.execCommand('insertImage', data.src);
}else{
//记录当前编辑位置
var range = menu.editor.range;
// TODO 此处请求服务器,下载图片,然后返回自己服务器保存地址,再插入图片。由于请求服务器一般异步操作,此处用setTimeout代替效果
setTimeout(function(){
menu.editor.setRange(range);
menu.editor.execCommand('insertImage', data.src);
},5000)
}
}
});
})