在线所见即所得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实现禁止后退的方法
Dec 27 Javascript
jquery中的sortable排序之后的保存状态的解决方法
Jan 28 Javascript
浅析js封装和作用域
Jul 09 Javascript
给文字加上着重号的JS代码
Nov 12 Javascript
多选列表框动态添加,移动,删除,全选等操作的简单实例
Jan 13 Javascript
js实现延时加载Flash的方法
Nov 26 Javascript
在WordPress中加入Google搜索功能的简单步骤讲解
Jan 04 Javascript
JS中创建函数的三种方式及区别
Mar 13 Javascript
基于Jquery插件实现跨域异步上传文件功能
Apr 26 Javascript
Ionic + Angular.js实现验证码倒计时功能的方法
Jun 12 Javascript
使用svg实现动态时钟效果
Jul 17 Javascript
基于vue.js实现分页查询功能
Dec 29 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安装攻略:常见问题解答(一)
2006/10/09 PHP
Win2003下APACHE+PHP5+MYSQL4+PHPMYADMIN 的简易安装配置
2006/11/18 PHP
ob_start(),ob_start('ob_gzhandler')使用
2006/12/25 PHP
PHP的cURL库功能简介 抓取网页、POST数据及其他
2011/04/07 PHP
php的debug相关函数用法示例
2016/07/11 PHP
PHP数组常用函数实例小结
2018/08/20 PHP
PHP的HTTP客户端Guzzle简单使用方法分析
2019/10/30 PHP
php屏蔽错误及提示的方法
2020/05/10 PHP
解决js图片加载时出现404的问题
2020/11/30 Javascript
详解Angularjs中的依赖注入
2016/03/11 Javascript
js类式继承与原型式继承详解
2016/04/07 Javascript
JS+Canvas绘制时钟效果
2020/08/20 Javascript
javascript实现瀑布流动态加载图片原理
2016/08/12 Javascript
jquery实现自定义图片裁剪功能【推荐】
2017/03/08 Javascript
JS实现访问DOM对象指定节点的方法示例
2018/04/04 Javascript
浅析前端路由简介以及vue-router实现原理
2018/06/01 Javascript
详解React中setState回调函数
2018/06/14 Javascript
Vue实现6位数密码效果
2018/08/18 Javascript
[04:00]DOTA2解说界神雕侠侣 CJ第四天谷子现场过生日
2013/07/30 DOTA
[03:52]DOTA2英雄基础教程 酒仙
2013/12/23 DOTA
[09:40]DAC2018 4.5 SOLO赛 MidOne vs Miracle
2018/04/06 DOTA
python实现socket端口重定向示例
2014/02/10 Python
Python实现读取TXT文件数据并存进内置数据库SQLite3的方法
2017/08/08 Python
CentOS7.3编译安装Python3.6.2的方法
2018/01/22 Python
python join方法使用详解
2019/07/30 Python
python 线性回归分析模型检验标准--拟合优度详解
2020/02/24 Python
详解Python设计模式之策略模式
2020/06/15 Python
详解Python中import机制
2020/09/11 Python
CSS3教程(3):border-color网页边框色彩
2009/04/02 HTML / CSS
HTML5仿微信聊天界面、微信朋友圈实例代码
2018/01/29 HTML / CSS
小程序canvas中文字设置居中锚点
2019/04/16 HTML / CSS
直接有效的自我评价
2014/01/11 职场文书
财务主管岗位职责
2014/02/28 职场文书
倡议书范文
2014/04/16 职场文书
中国梦演讲稿3分钟
2014/08/19 职场文书
交通安全教育主题班会
2015/08/12 职场文书