在线所见即所得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 相关文章推荐
解决FLASH需要点击激活的代码
Dec 20 Javascript
setTimeout和setInterval的深入理解
Nov 08 Javascript
javascript文件中引用依赖的js文件的方法
Mar 17 Javascript
JavaScript判断变量是否为空的自定义函数分享
Jan 31 Javascript
解析JavaScript面向对象概念中的Object类型与作用域
May 10 Javascript
jQuery插件fullPage.js实现全屏滚动效果
Dec 02 Javascript
springmvc接收jquery提交的数组数据代码分享
Oct 28 jQuery
实例教学如何写vue插件
Nov 30 Javascript
vue axios 给生产环境和发布环境配置不同的接口地址(推荐)
May 08 Javascript
js基础之事件捕获与冒泡原理
Oct 09 Javascript
vue2.0 获取从http接口中获取数据,组件开发,路由配置方式
Nov 04 Javascript
JavaScript创建表格的方法
Apr 13 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
Dedecms V3.1 生成HTML速度的优化办法
2007/03/18 PHP
php递归实现无限分类生成下拉列表的函数
2010/08/08 PHP
解析PHP对现有搜索引擎的调用
2013/06/25 PHP
php隐藏实际地址的文件下载方法
2015/04/18 PHP
form表单传递数组数据、php脚本接收的实例
2017/02/09 PHP
PHP cookie与session会话基本用法实例分析
2019/11/18 PHP
jQuery+PHP实现图片上传并提交功能
2020/07/27 PHP
JavaScript Date对象使用总结
2009/05/14 Javascript
JavaScript操纵窗口的方法小结
2013/06/28 Javascript
纯JavaScript实现HTML5 Canvas六种特效滤镜示例
2013/06/28 Javascript
关闭页面时window.location事件未执行的原因分析及解决方案
2014/09/01 Javascript
在HTML代码中使用JavaScript代码的例子
2014/10/16 Javascript
JavaScript中数组的22种方法必学(推荐)
2016/07/20 Javascript
JS实现拖动滚动条评分的效果代码分享
2016/09/29 Javascript
JS中实现函数return多个返回值的实例
2017/02/21 Javascript
JsChart组件使用详解
2018/03/04 Javascript
Vue2.X 通过AJAX动态更新数据
2018/07/17 Javascript
JavaScript数据结构与算法之二叉树实现查找最小值、最大值、给定值算法示例
2019/03/01 Javascript
java和js实现的洗牌小程序
2019/09/30 Javascript
Vue export import 导入导出的多种方式与区别介绍
2020/02/12 Javascript
解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题
2020/08/05 Javascript
vue+iview分页组件的封装
2020/11/17 Vue.js
[01:23]2014DOTA2国际邀请赛 球迷无处不在Ti现场世界杯受关注
2014/07/10 DOTA
python的变量与赋值详细分析
2017/11/08 Python
python实现自动解数独小程序
2019/01/21 Python
djang常用查询SQL语句的使用代码
2019/02/15 Python
Python Tornado之跨域请求与Options请求方式
2020/03/28 Python
jupyter notebook 实现matplotlib图动态刷新
2020/04/22 Python
手对手的教你用canvas画一个简单的海报的方法示例
2018/12/10 HTML / CSS
Room Mate Hotels美国:西班牙酒店品牌
2018/04/10 全球购物
Chain Reaction Cycles俄罗斯:世界上最大的在线自行车商店
2019/08/27 全球购物
xml有哪些解析技术?区别是什么
2016/04/26 面试题
计算机专业毕业生求职信分享
2013/12/24 职场文书
幼儿园大班毕业评语
2014/12/31 职场文书
小学端午节活动总结
2015/02/11 职场文书
创业计划书之校园跑腿公司
2019/09/24 职场文书