在线所见即所得HTML编辑器的实现原理浅析


Posted in Javascript onApril 25, 2015

如今网站开发越来越提倡用户体验,为用户提供便利的工具也越来越多,而在线的HTML内容编辑器应该算是其中比较“古老”的一个了。功能简单的可以为用户提供文本的样式控制,例如文字的颜色、字体大小等;而功能复杂的甚至可以提供类似Word一样的强大功能。虽然现在各种开源的编辑器非常多,但是真正好用的并不多,所以它们改进工作也一直在进行中。

如今网上多数的编辑器都有很强大的功能,相对而言,在使用中也需要很多的配置,当然代码也自然会比较“臃肿”。如果我们并不需要功能那么强大的编辑器,那么可以自己实现一个,因为代码并不复杂。下面是一点个人的经验,仅供参考(以ExtJS的HTMLEditor为例)。

1、初始化。当页面加载完毕后,向页面添加一个IFrame(可选)。这里要注意的是,要判断页面的状态,要等页面完全加载完毕后再进行操作,防止出现找不到某些元素的错误。

2、打开编辑功能。将IFrame设为可以编辑(下面代码来自ExtJS的HTMLEditor):

// 获取iframe的window对象

getWin : function(){

        return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];

    },
//获取iframe的document对象

getDoc : function(){

        return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);

},
//打开document对象,向其写入初始化内容,以兼容FireFox

doc = this.getDoc();

doc.open();

doc.write('<html><head><mce:style type="text/css"><!--

body{border:0;margin:0;padding:3px;height:98%;cursor:text;}

--></mce:style><style type="text/css" mce_bogus="1">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>');

//打开document对象编辑模式

 doc.designMode = "on";

doc.close();

这样就可以向这个简单那的编辑器中写入内容了。
 
3、获取编辑器的内容,代码如下:

//获取编辑器的body对象

var body = doc.body || doc.documentElement;

//获取编辑器的内容

var content = body.innerHTML;

//对内容进行处理,例如替换其中的某些特殊字符等等

//Some code
//返回内容

return content;

 4、增加样式设置。上面的编辑器虽然实现了基本功能,但是实在是有些太简单了,应该增加些简单的样式实现。document的execCommand方法使这种想法成为可能。

//统一的执行命令方法

function execCmd(cmd, value){

    //doc对象的获取参照上面的代码

     //调用execCommand方法执行命令

    doc.execCommand(cmd, false, value === undefined ? null : value);

};
//将选中字体变为黑体,Ctrl-B

execCmd('bold');

//加下划线,Ctrl-U

execCmd('underline');

//变为斜体,Ctrl-I

execCmd('italic');

//设置文字的颜色

execCmd('forecolor', Ext.isSafari || Ext.isIE ? '#'+color : color);

//在光标处插入一段内容

function insertAtCursor(text){

  //win对象的获取参考上面的代码

  if(Ext.isIE){

      win.focus();

      var r = doc.selection.createRange();

      if(r){

        r.collapse(true);

        r.pasteHTML(text);      }

    }else if(Ext.isGecko || Ext.isOpera){

      win.focus();

      execCmd('InsertHTML', text);

    }else if(Ext.isSafari){

      execCmd('InsertText', text);

    }

  }

5、再进一步。如今可以改变样式了,如果编辑器有工具栏(这应该是必然的),那么我们还想工具栏上的按钮根据光标所处位置的样式,自动处于突出或正常显示。document的queryCommandState()方法又让这种想法得以实现。

//doc对象的获取参考上面的对面

//光标处是否是粗体

var isBold = doc.queryCommandState('bold');

if(isBold){

  //改变Bold按钮的样式

}

//当然上面的代码是可以合并的,这里只不过是一个示意


//下划线

doc.queryCommandState('underline');

//斜体

doc.queryCommandState('italic');

本文只是为实现编辑器提供了简单的思路,其中的一些代码是可以直接使用的。建议,想自己实现编辑器的朋友可以参考下ExtJS中的HTMLEditor代码,既简单又比较清晰,可以在其上进行扩展。

最后提醒一点:一定要注意浏览器的兼容性问题,并且不要等接近尾声了再去测试兼容性,对于这么大量的JavaScript代码,调整是比较痛苦的事情。

Javascript 相关文章推荐
JavaScript实现生成GUID(全局统一标识符)
Sep 05 Javascript
表单验证插件Validation应用的实例讲解
Oct 10 Javascript
详解JavaScript基于面向对象之继承实例
Dec 16 Javascript
微信小程序 出现错误:{&quot;baseresponse&quot;:{&quot;errcode&quot;:-80002,&quot;errmsg&quot;:&quot;&quot;}}解决办法
Feb 23 Javascript
在ES5与ES6环境下处理函数默认参数的实现方法
May 13 Javascript
Angular4 组件通讯方法大全(推荐)
Jul 12 Javascript
jQuery 筛选器简单操作示例
Oct 02 jQuery
javascript网页随机点名实现过程解析
Oct 15 Javascript
js使用文档就绪函数动态改变页面内容示例【innerHTML、innerText】
Nov 07 Javascript
javascript中innerHTML 获取或替换html内容的实现代码
Mar 17 Javascript
vue实现可移动的悬浮按钮
Mar 04 Vue.js
JS的深浅复制详细
Oct 16 Javascript
JavaScript在Android的WebView中parseInt函数转换不正确问题解决方法
Apr 25 #Javascript
Node.js和MongoDB实现简单日志分析系统
Apr 25 #Javascript
node.js操作mongodb学习小结
Apr 25 #Javascript
JavaScript按值删除数组元素的方法
Apr 24 #Javascript
JavaScript获取一个范围内日期的方法
Apr 24 #Javascript
jQuery中next方法用法实例
Apr 24 #Javascript
JavaScript实现多个重叠层点击切换效果的方法
Apr 24 #Javascript
You might like
解析PHP中DIRECTORY_SEPARATOR,PATH_SEPARATOR两个常量的作用
2013/06/21 PHP
关于php内存不够用的快速解决方法
2013/10/26 PHP
Joomla简单判断用户是否登录的方法
2016/05/04 PHP
PHP实现对图片的反色处理功能【测试可用】
2018/02/01 PHP
PHP 应用容器化以及部署方法
2018/02/12 PHP
PHP排序算法之快速排序(Quick Sort)及其优化算法详解
2018/04/21 PHP
Laravel-添加后台模板AdminLte的实现方法
2019/10/08 PHP
js函数的延迟加载实现代码
2012/10/11 Javascript
[将免费进行到底]在Amazon的一年免费服务器上安装Node.JS, NPM和OurJS博客
2014/08/18 Javascript
从数据库读取数据后将其输出成html标签的三种方法
2014/10/13 Javascript
js中对函数设置默认参数值的3种方法
2015/10/23 Javascript
JavaScript+html5 canvas绘制的圆弧荡秋千效果完整实例
2016/01/26 Javascript
纯js和css完成贪吃蛇小游戏demo
2016/09/01 Javascript
JS中BOM相关知识点总结(必看篇)
2016/11/22 Javascript
JavaScript中的call和apply的用途以及区别
2017/01/11 Javascript
详解vue父子组件间传值(props)
2017/06/29 Javascript
微信小程序之绑定点击事件实例详解
2017/07/07 Javascript
js中获取URL参数的共用方法getRequest()方法实例详解
2018/10/24 Javascript
django自定义Field实现一个字段存储以逗号分隔的字符串
2014/04/27 Python
Python装饰器的函数式编程详解
2015/02/27 Python
python创建和删除目录的方法
2015/04/29 Python
Python守护线程用法实例
2017/06/23 Python
详解Python自建logging模块
2018/01/29 Python
对python周期性定时器的示例详解
2019/02/19 Python
Python Django Vue 项目创建过程详解
2019/07/29 Python
在python中做正态性检验示例
2019/12/09 Python
python连接mongodb数据库操作数据示例
2020/11/30 Python
Python实现钉钉/企业微信自动打卡的示例代码
2021/02/02 Python
美国维生素、补充剂、保健食品购物网站:Vitacost
2016/08/05 全球购物
师范应届生求职信
2013/11/15 职场文书
教师个人自我鉴定
2014/02/08 职场文书
青年文明号复核材料
2014/02/11 职场文书
公司寄语大全
2014/04/10 职场文书
试用期转正员工自我评价
2014/09/18 职场文书
小学校园广播稿(3篇)
2014/09/19 职场文书
平安家庭事迹材料
2014/12/20 职场文书