在线所见即所得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 相关文章推荐
JS event使用方法详解
Apr 28 Javascript
图片自动缩小 点击放大
Jul 07 Javascript
document节点对象的获取方式示例介绍
Dec 24 Javascript
使用iframe window的scroll方法控制iframe页面滚动
Mar 05 Javascript
3种js实现string的substring方法
Nov 09 Javascript
超精准的javascript验证身份证号的具体实现方法
Nov 18 Javascript
基于canvas的二维码邀请函生成插件
Feb 14 Javascript
Vue.js常用指令的使用小结
Jun 23 Javascript
Angular中ng-repeat与ul li的多层嵌套重复问题
Jul 24 Javascript
JS+Ajax实现百度智能搜索框
Aug 04 Javascript
微信小程序实现流程进度的图样式功能
Jan 16 Javascript
layui框架与SSM前后台交互的方法
Sep 12 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
mysql 全文搜索 技巧
2007/04/27 PHP
PHP--用万网的接口实现域名查询功能
2012/12/13 PHP
使用array_map简单搞定PHP删除文件、删除目录
2014/10/29 PHP
dedecms集成财付通支付接口
2014/12/28 PHP
php操作xml入门之cdata区段
2015/01/23 PHP
php实现购物车功能(上)
2020/07/23 PHP
thinkPHP5框架auth权限控制类与用法示例
2018/06/12 PHP
PHP 实现链式操作
2021/03/09 PHP
JavaScript中instanceof与typeof运算符的用法及区别详细解析
2013/11/19 Javascript
jquery制作居中遮罩层效果分享
2014/02/21 Javascript
JavaScript字符串对象fromCharCode方法入门实例(用于把Unicode值转换为字符串)
2014/10/17 Javascript
js学习心得_一个简单的动画库封装tween.js
2017/07/14 Javascript
详解React-Router中Url参数改变页面不刷新的解决办法
2018/05/08 Javascript
微信小程序pinker组件使用实现自动相减日期
2020/05/07 Javascript
js+css实现全屏侧边栏
2020/06/16 Javascript
解决nuxt页面中mounted、created、watch执行两遍的问题
2020/11/05 Javascript
Python中除法使用的注意事项
2014/08/21 Python
Python基于回溯法子集树模板解决最佳作业调度问题示例
2017/09/08 Python
python 批量修改/替换数据的实例
2018/07/25 Python
解决Python3 控制台输出InsecureRequestWarning问题
2019/07/15 Python
python OpenCV GrabCut使用实例解析
2019/11/11 Python
pymysql模块的操作实例
2019/12/17 Python
Pytorch实现各种2d卷积示例
2019/12/30 Python
PyCharm 2020.2.2 x64 下载并安装的详细教程
2020/10/15 Python
次世代生活态度:Hypebeast
2018/07/05 全球购物
C#面试题
2016/05/06 面试题
检查接待方案
2014/02/27 职场文书
医疗纠纷协议书
2014/04/16 职场文书
商场租赁意向书
2014/07/30 职场文书
捐款活动总结
2014/08/27 职场文书
2014小学二年级班主任工作总结
2014/12/05 职场文书
三八红旗手事迹材料
2014/12/26 职场文书
python生成可执行exe控制Microsip自动填写号码并拨打功能
2021/06/21 Python
SQL实现LeetCode(177.第N高薪水)
2021/08/04 MySQL
Python if else条件语句形式详解
2022/03/24 Python
nginx日志格式分析和修改
2022/04/28 Servers