在线所见即所得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 相关文章推荐
使用jQuery操作Cookies的实现代码
Oct 09 Javascript
关于JavaScript中原型继承中的一点思考
Jul 25 Javascript
正则表达式中特殊符号及正则表达式的几种方法总结(replace,test,search)
Nov 26 Javascript
angularjs表格分页功能详解
Jan 21 Javascript
iscroll碰到Select无法选择下拉刷新的解决办法
May 21 Javascript
JS提示:Uncaught SyntaxError:Unexpected token ) 错误的解决方法
Aug 19 Javascript
JavaScript 动态三角函数实例详解
Jan 08 Javascript
详解es6超好用的语法糖Decorator
Aug 01 Javascript
vue template中slot-scope/scope的使用方法
Sep 06 Javascript
在小程序Canvas中使用measureText的方法示例
Oct 19 Javascript
Vue之beforeEach非登录不能访问的实现(代码亲测)
Jul 18 Javascript
JQuery常用选择器功能与用法实例分析
Dec 23 jQuery
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中\r \r\n \t的区别示例介绍
2014/02/08 PHP
php+html5使用FormData对象提交表单及上传图片的方法
2015/02/11 PHP
php生成圆角图片的方法
2015/04/07 PHP
PHP 数组遍历foreach语法结构及实例
2016/06/13 PHP
PHP实现统计在线人数功能示例
2016/10/15 PHP
JS Timing
2007/04/21 Javascript
JavaScript对象之间的转换 jQuery对象和原声DOM
2011/03/07 Javascript
ext前台接收action传过来的json数据示例
2014/06/17 Javascript
js使用循环清空某个div中的input标签值
2014/09/29 Javascript
jQuery实现多按钮单击变色
2014/11/27 Javascript
JS基于myFocus库实现各种功能的tab选项卡切换效果
2015/09/19 Javascript
js实现文字闪烁特效的方法
2015/12/17 Javascript
node.js中的事件处理机制详解
2016/11/26 Javascript
jQuery源码分析之init的详细介绍
2017/02/13 Javascript
JavaScript无阻塞加载和defer、async详解
2017/02/26 Javascript
Vue自定义toast组件的实例代码
2018/08/15 Javascript
Vue监听事件实现计数点击依次增加的方法
2018/09/26 Javascript
[07:40]DOTA2每周TOP10 精彩击杀集锦vol.4
2014/06/25 DOTA
Python学习小技巧之列表项的推导式与过滤操作
2017/05/20 Python
python出现&quot;IndentationError: unexpected indent&quot;错误解决办法
2017/10/15 Python
python MysqlDb模块安装及其使用详解
2018/02/23 Python
python实现内存监控系统
2021/03/07 Python
Python爬虫常用小技巧之设置代理IP
2018/09/13 Python
解决使用PyCharm时无法启动控制台的问题
2019/01/19 Python
Python3.6 中的pyinstaller安装和使用教程
2020/03/16 Python
python自动打开浏览器下载zip并提取内容写入excel
2021/01/04 Python
css3发光搜索表单分享
2014/04/11 HTML / CSS
您的网上新华书店:文轩网
2016/08/24 全球购物
Clearly澳大利亚:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
Sneaker Studio罗马尼亚网站:购买运动鞋
2018/11/04 全球购物
速比涛英国官网:Speedo英国
2019/07/15 全球购物
商铺租赁意向书
2014/04/01 职场文书
2014酒店客房部工作总结
2014/12/16 职场文书
2016年教师师德师风心得体会
2016/01/12 职场文书
彻底理解golang中什么是nil
2021/04/29 Golang
Python scrapy爬取起点中文网小说榜单
2021/06/13 Python