200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 实现一个简易的富文本编辑器(二):给富文本添加自定义事件

实现一个简易的富文本编辑器(二):给富文本添加自定义事件

时间:2022-02-05 04:05:32

相关推荐

实现一个简易的富文本编辑器(二):给富文本添加自定义事件

为富文本添加一个提交按钮,点击按钮可以获取富文本内容。但是在提交前或者提交后我想做一些操作,比如内容校验内容清空等等。

我们直接在该按钮上绑定点击事件同样可以达到目的,但是为了组件化,所以本例打算为提交按钮自定义beforeSubmit、afterSubmit两个事件。

1.创建发布订阅者对象

前文说到,事件系统是发布-订阅模式的一个实现,模式给事件发布函数与事件处理函数进行解耦,使得两者无直接调用关系。

简易发布订阅者对象实现如下:

var Event = {// _cachePool : {}, 处理函数缓存池不要写在该对象内,因为原型链继承会让子类共享引用类型数据。fire : function(type, msg) {var fns;if(!(fns = this._cachePool[type])) {return;}var len = fns.length;for(var i = 0, fn; i < len; i++) {fn = fns[i];fn.call(this, msg);}},on : function(type, callback) {if(!this._cachePool[type]) {this._cachePool[type] = [];}this._cachePool[type].push(callback);},un : function(type, callback) {var fns = this._cachePool[type];if(fns) {this._cachePool[type] = fns.filter(function(item){//注意兼容,一些低版本Array没有过滤函数return item !== callback;});}}};

这里要去掉缓存池,因为这个对象将是编辑器原型中的一份子,我们希望每个编辑器都有自己一个私有的缓存池,以避免不同编辑器实例监听到相同的事件。

2.编辑器样式

本例编辑器给命令按钮设置图片样式,并且仅实现字体加粗功能:

.editorOut {border:1px solid #ccc;width:200px;height:200px;position:relative;}.editorTool {margin:2px;width:100%;}.editorFoot {margin:2px;width:100%;position:absolute;bottom:0;}.editorOut button {height:20px;width:20px;margin:1px;border:0px solid #fff;cursor:pointer;overflow:hidden;}.editorOut button.bold{background:url(./imgs.svg) 0px 0px;background-size:140px 40px;}.editorOut button.bold:hover {background:url(./imgs.svg) 0px -20px;background-size:140px 40px;}

注:SVG是绘制矢量图的标签(XML)语言,它的特点是不受像素影响。

3.实现简易编辑器

利用js脚本,动态创建编辑器。

_create函数创建编辑器,它封装了创建编辑器命令块、底部块、输入域等创建的过程。

_createEditor为创建编辑器输入域函数。

_createTool为创建命令块函数。

_createCommandBtn为创建调用编辑器命令的按钮的函数,本例只实现一个按钮。

_createFoot创建底部块函数。

_onbeforeSubmit为启动自定义事件beforesubmit的函数。

_onaftersubmit为启动自定义事件aftersubmit的函数。

_createPrintBtn为创建输出按钮的函数。本例两个自定义事件都在这里启动。

EditorProto = {_create : function(id) {var editor = this._createEditor(id);var tool = this._createTool();var button = this._createCommandBtn();var foot = this._createFoot();var printBtn = this._createPrintBtn();this.printBtn = printBtn;tool.appendChild(button);foot.appendChild(printBtn);editor.insertBefore(tool, editor.firstChild);editor.appendChild(foot);return editor;},_createEditor : function(id) {var editor = document.getElementById(id);editor.className = "editorOut";editor.contentEditable = true;return editor;},_createTool : function() {var tool = document.createElement("div");tool.contentEditable = false;tool.className = "editorTool";return tool;},_createCommandBtn : function() {var button = document.createElement("button");button.className = "bold";button.title = "加粗";button.onclick = function(e) {document.execCommand("bold", false, null);};return button;},_createFoot : function() {var tool = document.createElement("div");tool.contentEditable = false;tool.className = "editorFoot";return tool;},_onbeforeSubmit : function(e, scope, callback) {scope.fire('beforesubmit', e);},_onaftersubmit : function(e, scope, callback) {scope.fire('aftersubmit', e);},_createPrintBtn : function() {var button = document.createElement("input"),that = this;button.type="button"button.value = "点击写出";button.onmousedown = function(e) {that._onbeforeSubmit(e, that);};button.onmouseup = function(e) {that._onaftersubmit(e, that);};return button;}};

4.实现简易拷贝函数

拷贝函数的作用是将Event对象与EditorProto对象糅合到一起。

var copyIf = function(sub, sup, config) {for(var p in sup) {if(!sub[p]) {sub[p] = sup[p];//拷贝 }}}

5.编辑器组件化

为了达到最终new一次创建一个实例的目的,我们需要将编辑器对象加工成构造函数。像ExtJS、JQuery、Mini UI等都有实现自己的extend函数,本例就不单独实现继承函数了。

copyIf(EditorProto, Event);//将Event对象拷贝给EditorProtofunction Editor(id) {this._cachePool = {};//事件处理函数的缓存池不能放到原型里this._create(id);//new 操作构造器的时候,创建编辑器实例};Editor.prototype = EditorProto;//原型链继承

6.验证beforesubmit与aftersubmit事件效果

HTML里定义两个div,做为两个编辑器的容器。

<div id="editor">print...</div><div id="s"></div>

JS里分别在HTML两个div内创建编辑器,并且第一个编辑器绑定两个自定义事件,第二个只绑定一个,测试效果。

var editor = new Editor("editor");editor.on("beforesubmit", function() {console.log("beforesubmit");});editor.on("aftersubmit", function() {console.log("aftersubmit");});var s = new Editor("s");s.on("beforesubmit", function() {console.log("s的提交前事件");});

点击第一个编辑器会打印出“beforesubmit”与“aftersubmit”;点击第二个编辑器打印出“s的提交前事件”。

为编辑器创建自定义事件目的达成!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。