http://www.army8735.org/2009/09/25/126.html
翻译的一篇文章,服务广大人民群众。这里贴不出来格式。
---
原文标题:《Rich HTML editing in the browser: part 1》
原文地址:http://dev.opera.com/articles/view/rich-html-editing-in-the-browser-part-1/
介绍
时光倒流。在世界上最早的浏览器——提姆·伯纳·李(Tim Berners-Lee)发布于1990年——诞生的时候,我们可以直接在所见即所得模式下编辑网页的内容,那时的网页被构思为一种可读可写的媒介。后来经过一段时间的发展,浏览器基本上变得只读了,除了只能在form控件中输入一些纯文本而已。
Internate Explorer 5的发布将浏览器的所见即所得编辑特性带回了主流:新的设计模式(designMode)属性允许用户编辑整个文档(document)。一开始这一特性显得多少有些疏忽,因为它最初是Windows操作系统下IE专有的。
近些年来,另一些可以和IE抗衡的浏览器——Mozilla、Safari和Opera——跟随并实现了这一IE独有的特性。排版引擎比较组织(WHATWG-group)也致力于编辑系统标准的建立——HTML5中设计模式和可编辑内容文档对象模型属性(contentEditable DOM properties)的介绍。看起来在浏览器中,所见即所得编辑最终将成为网页整体的一部分。
这篇文章利用HTML5的可编辑特性来评审现今浏览器的基本概念和挑战。这些科目包括:
* 不同的可编辑模式
* 编辑命令
* 编辑产生的HTML代码
* 和DOM的配合
这篇文章是两篇系列文章的第一篇,第二篇内容将覆盖到一个详细的例子来实现一个编辑器。
注意:我只考虑到最近的主流浏览器所支持的特性:Opera 9.5、Firefox 2+和Safari 3,较旧的版本有太多的bug和不稳定的地方了。IE中的实现直到5.5版本才有了明显的变化。
可编辑系统预览
可编辑系统允许用户编辑页面或者页面中的一部分,它有如下几个方面:
* 光标(caret)标识当前的插入点。用户可以输入、删除等。使用键盘或鼠标可以移动光标或者选区。
* 一些浏览器提供UI组件用户缩放重定位图片、表格和其它可重定位的元素(elements)。
* 内置了一系列独立的编辑命令:粗体、斜体、插入链接、粘贴、撤消等。这些可以被快捷键、脚本命令接口(script command API)调用。使用API可以轻易实现一个编辑器的工具栏(toolbar)。
* 使用范围和选区接口(range and selection API),你可以写出自己的脚本来修改任意html代码。这一特性通常用来实现自定义编辑命令。
* 可编辑系统允许你改变html代码。一旦你创建了它,它并不会真正地修改你网页的内容。举例来说,除非你写了保存修改的脚本命令,否则是无法将修改的内容存回服务器的。
这里还有两条关于可编辑系统的警告:
* 命令和编辑行为的产生是不可预知的,而产生的html代码结果在不同的浏览器中可能大相径庭。
* 直到2000年5.5版本的出现,IE浏览器中的实现才有了大幅度的变化。系统产生的html代码可能会让一些敏感的人颤栗——如果你看到最后的字体节点(<font>tag),你肯定会大吃一惊!
开启可编辑特性
这里有两种方法在网页上来创建一块可编辑的选区——设计模式(designMode)和可编辑内容(contentEditable)属性。
一个窗口(window)或者框架(frame)是以设置文档(document)对象上的设计模式属性为真(true)来开启的。(警告:在IE 中,这个属性在文档上是不存在的,必须从窗口对象上获取。)典型的可编辑框是将一个内嵌框架(iframe)的设置为设计模式。
一个包含文本的元素想要可编辑的话必须设置设计模式属性为真。(Firefox 2并不支持设计模式属性,但是在Firefox 3中却得到了支持。当然IE、Safari、Opera都早已支持。)
可编辑按键
在一个简单编辑器中,你或多或少会期望能够使用键盘和鼠标来进行编辑内容。当文档获得焦点(focus)时,光标就会显示,它可以上下左右移动。键入或者删除字符也会改变光标的位置。文本选区可以被移动、删除以及覆盖。
一个人性化的设定是所有按键编辑行为都可以自动被记录并且撤消。(后面会提到如何使用撤消工功能。)
复杂的问题出现了:当我们按下了回车键该怎么办?这样做的话并不会立刻显示所产生html代码,而且各个浏览器的结果还会根据上下文有所不同。如果光标在一个非空的p元素内,所有浏览器都会关闭这个元素,并且产生一个拥有相同属性的新元素,最后把光标定位到它里面。(Mozilla会在光标后附带插入一个多余的br换行元素。)例如(这些例子中都用竖线来表示光标所在位置):
html 代码
关于
1. <p>bla bla|</p>
<p>bla bla|</p>
按下回车键后IE和Safari会变为:
html 代码
关于
1. <p>bla bla</p>
2. <p>|</p>
<p>bla bla</p>
<p>|</p>
假如光标在一个非空的h1元素中,所有的浏览器都会关闭它。但是IE和Opera却会插入一个新的p元素,并且将光标位置置入其中。Safari会插入一个新的h1
元素并将光标位置设定在里面。Mozilla不会产生任何元素,但却会插入两个换行元素在光标后面。例如:
html 代码
关于
1. <h1>bla bla|</h1>
<h1>bla bla|</h1>
按下回车键后Opera会变为:
html 代码
关于
1. <h1>bla bla|</h1>
2. <p>|</p>
<h1>bla bla|</h1>
<p>|</p>
但在Mozilla中却会是:
html 代码
关于
1. <h1>bla bla|</h1>
2. |<br><br>
<h1>bla bla|</h1>
|<br><br>
在Safari中则是:
html 代码
关于
1. <h1>bla bla|</h1>
2. <h1>|</h1>
<h1>bla bla|</h1>
<h1>|</h1>
如果你直接在body元素中输入文本(并不包含其它元素),再按下回车键的话,Mozilla会插入一个br元素,IE和Opera会转换前面的文本放入一个p元素中并且插入一个新的p元素,Safari会插入一个新的div元素。
当在一个div元素中键入时,Safari、Opera和IE将关闭当前div元素并且插入一个新的div元素,Mozilla将插入一个br元素并且仍然呆在这个div元素中。
如果在光标外有嵌套的块级(block)元素,所有浏览器都会关闭(并且复制)最深的元素。光标依然会呆在外部块级元素内。
最关键的:令人惊讶的是,在块级元素的处理上,IE反而是最标准的!Mozilla会在部分情况下使用br元素代替块级元素,从而使得原文的显示保持正常。
光标位置
光标是在字符之间移动的。它在标签之间的定位是不可见的。逻辑上看起来所有浏览器是一致的。有关块级元素:光标总会被定位到最深的块级元素上,没法让光标位于两端之间。
例如,看下面,竖线代表所有光标可能处于的位置:
html 代码
关于
1. <p>|P|1|</p><p>|p|2|</p>
2. <div><p>|P|3|</p><div><p>|P|4|</p></div></div>
<p>|P|1|</p><p>|p|2|</p>
<div><p>|P|3|</p><div><p>|P|4|</p></div></div>
关于行级(inline)元素,假如光标在文字左侧,它会在所有行级元素边界之外;假如光标在文字右侧,则会在边界之内。例如:
html 代码
关于
1. <p>|A|<strong><em>B|</em></strong>C|</p>
<p>|A|<strong><em>B|</em></strong>C|</p>
所以假如你直接在粗体文本左侧输入字符的话,新输入的字符并不会是粗体;相反在右侧输入则会是粗体。
删除
如果你直接删除一个段落的边界,结果可想而知:左边的块(block)“获胜”了,块右边的内容被包含在了左边:
html 代码
关于
1. <h1>Overskrift</h1><p>|Text</p>
<h1>Overskrift</h1><p>|Text</p>
如果按下了回退键(backspace),结果是:
html 代码
关于
1. <h1>Overskrift|Text</h1>
<h1>Overskrift|Text</h1>
然而Safari却耍了个小聪明(或者说让人讨厌,这完全取决于你的心情),让右边段落的内容保持原来的风格(style):
html 代码
关于
1. <h1>Overskrift|<span class="Apple-style-span" style="font-size:16px;font-weight:normal;">Text</span></h1>
<h1>Overskrift|<span class="Apple-style-span" style="font-size:16px;font-weight:normal;">Text</span></h1>
对象编辑
浏览器支持一些特殊的UI特性编辑。
IE允许你用鼠标拖动对象的4个角来拉伸图像、表格、表单控制元素或者完全重定位元素(当对象获得焦点并被选择后,鼠标靠近句柄就会出现)。
Mozilla也允许你拉伸表和和图像,只是附带地允许用户创建新行新列。Mozilla还附带允许你重定位绝对定位的元素。但这些特性都是浏览器完全私有的,并且不能被自定义。
编辑命令
不同浏览器支持不同编辑命令。由命令所产生的html代码在不同浏览器中并不一样,且不一定符合标准。例如,在IE中,粗体命令会产生这样代码:
html 代码
关于
1. <strong>Hello!</strong>
<strong>Hello!</strong>
Safari则会产生这样的:
html 代码
关于
1. <span class="Apple-style-span" style="font-weight:bold;">Hello!</span>
<span class="Apple-style-span" style="font-weight:bold;">Hello!</span>
所产生的代码有些过时,至少在IE中是这样。令人畏惧的标签(如<FONT color=#ff0000>123</FONT>)会被一系列命令产生,并且生成的html代码并不符合xhtml标准有时甚至不符合html标准!
Opera的html实现接近(并不相等)IE,使用font元素等等。Safari产生格式化的span元素并用内联css。Safari这一行为的优点是所产生的html代码能通过HTML 4.01 Strict校验。
Mozilla支持两种模式——既可以产生像IE/Opera的元素也可以像Safari那样使用style属性。
如果你担心html校验的话,可以在服务器端做一些过滤清理,将那些标签杂烩转换为标准的xhtml(你可能很需要这样做,以防XSS漏洞攻击)。
快捷键
一些编辑命令支持快捷键,如Ctrl/Cmd + B是粗体、Ctrl/Cmd + B是撤消等等。然而这些快捷键变量在不同浏览器中位置还不完全一样。
快捷键的对照关系图不能被修改,但是却可以在在按键事件中截取到来重写它们。
命令程序接口
你可能想要实现一个工具栏来允许用户运行一些编辑命令,这些可以用API来完成。这些API看起来并不像典型的DOM API,它实际上是实现了IOleCommandTarget接口——这是一个微软应用程序中应用的COM接口,用来同步编辑文档的工具。
命令API基于文档对象之上并且是由一个叫执行命令(execCommand)方法实现的,并且一串以“query”开始的方法会返回命令的信息。
所有的方法都以命令ID为第一个参数——代表命令名称的字符串,剩余的是要执行的方法。
执行命令(ExecCommand)
在当前选取上执行命令,一些命令会切换状态,例如你在选取一段粗体文本之后执行粗体命令,它们就会变回普通样式。其它一些命令需要传入值参,例如foreclor需要颜色代码。
一些命令提供独立的对话框,例如链接(link)命令显示一个对话框来输入url地址,这些对话框不能被自定义,但是却可以被禁止掉。例如:
js 代码
关于
1. result = document.execCommand(command, useDialog, value);
result = document.execCommand(command, useDialog, value);
不同参数的含义:
* command:String,命令的名字。
* useDialog:Boolean,显示内建对话框(并不是所有命令都有对话框)。
* value:命令所需要的值,并不是所有命令都需要值;假如一个内建的对话框被显示了,那么值是从对话框里获取的。
* 结果:如果命令成功执行,则返回true;如果被用户所取消(用户取消了对话框)或者执行失败,则返回false。
当没有选择文字的情况下(只有一个光标),所有浏览器都支持文本格式化命令。假如光标在一个单词中间,IE会将整个单词格式化掉,而其它浏览器仅仅格式化下一个将要输入的字符,除非光标提前移动了。
查询命令(QueryCommand)
相对于和文档选区(document selection)相关的工具栏按钮来说,使用查询命令来查询它们的状态,这可能是所有浏览器中最健全的支持了。
开启查询命令(QueryCommandEnabled)
根据当前选区的命令是否可以运行,查询命令处于开启或关闭的状态下。例如:“解除链接(unlink)”只有当光标在一个链接(link)选区内才可用。而当光标处于不可编辑的区域中的话,所有命令都不可用。
查询命令状态(QueryCommandState)
它标识着当前选区内是否已经运行过相关命令了。例如在一个粗体选区中,粗体命令(bold command)的状态就是true。
查询命令返回值(QueryCommandValue)
它是目标选区执行命令后返回的值,对应于执行命令中传入的参数值。如foreColor返回当前选区的颜色代码(String)。
不同浏览器之间的格式化命令是不同的。例如,foreColor命令在IE中会返回一个16进制的颜色代码(如#ff0000),其它浏览器则返回一个rbg表达式(如rgb(255,0,0))。
一些返回值是建立在浏览器本地基础上的。例如在IE中,格式化块(FormatBlock)会根据浏览器的UI语言返回段落的名称。
像粗体这样的命令,返回值总是false。(api包含两个附加的方法,queryCommandSupported和queryCommandIndeterminate,但是它们用起来极不可靠。)
范围和选区API
内建的命令经常被用在实际的选区上,但是却不能修改它们的行为或者自定义实现。使用范围和选区(Range and Selection)API,你可以实现自主的html转换,就像模拟自定义实现一样。
需要说明的是,一些转换破坏了经常被撤销/重做(undo/redo)命令使用的撤销栈(undo stack),这是非常不友好的。但是它却实现了自定义命令的功能,是否值得这样做取决于你的你的页面建立目标。
范围和选区API包含两个核心类:
* 范围——一个文档中连续的字符串范围。范围可能会在元素边界上重叠。一个范围拥有开始点(start point)和结束点(end point)。如果开始点的位置和结束点相等的话,我们就说这个范围是折叠的。
* 选区——描述当前用户选取的文档选区。一个选区包括唯一的一个高亮范围。如果范围是折叠的,那么选区就以光标形态显示。
(范围和选区可以用在可编辑区域之外,你可以在只读的文档上创建选区,但是这样的话它不能被折叠,并且只读选区并不显示光标。)
这些概念在所有浏览器中通用,但是可用的API却在IE和其它浏览器中有区别。IE使用它私有的范围选区API,其它浏览器则使用W3C标准的范围API和非标准的选区API。
最主要的差别还是:IE的范围是以存储包括html标记在内的String为基础的;而W3C标准则是存储DOM节点树。
范围例子:
为了展示二者不同之处,这有一个在当前选区插入行内元素code的代码。
IE中(editWindow是个对处于designMode的frame的引用):
js 代码
关于
1. var rng = editWindow.document.seletion.createRange();
2. rng.parseHTML("" + rng.htmlText + "");
var rng = editWindow.document.seletion.createRange();
rng.parseHTML("" + rng.htmlText + "");
Mozilla中:
js 代码
关于
1. var rng = editWindow.getSelection().getRangeAt(0);
2. rng.surroundContents(document.createElement("code"));
var rng = editWindow.getSelection().getRangeAt(0);
rng.surroundContents(document.createElement("code"));
控制选区(Control selection)
IE支持控制选区,它和普通的范围选区不一样。当你在一副图片上、表单上、表格的边线上点击的时候,控制选区就产生了。
并且你可以按下Ctrl键来达到一次性选择多个控制选区的目的,其它浏览器并不支持——它们仍会当作一个文本选区来看待。
总结
本文带你浏览了基于浏览器的可编辑概念。系列文章的第二篇将给你展示一个很有价值例子——如何利用这些API来实现可编辑的页面。
- 浏览: 565148 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (618)
- java (109)
- Java web (43)
- javascript (52)
- js (15)
- 闭包 (2)
- maven (8)
- 杂 (28)
- python (47)
- linux (51)
- git (18)
- (1)
- mysql (31)
- 管理 (1)
- redis (6)
- 操作系统 (12)
- 网络 (13)
- mongo (1)
- nginx (17)
- web (8)
- ffmpeg (1)
- python安装包 (0)
- php (49)
- imagemagic (1)
- eclipse (21)
- django (4)
- 学习 (1)
- 书籍 (1)
- uml (3)
- emacs (19)
- svn (2)
- netty (9)
- joomla (1)
- css (1)
- 推送 (2)
- android (6)
- memcached (2)
- docker、 (0)
- docker (7)
- go (1)
- resin (1)
- groovy (1)
- spring (1)
最新评论
-
chokee:
...
Spring3 MVC 深入研究 -
googleyufei:
很有用, 我现在打算学学Python. 这些资料的很及时.
python的几个实用网站(转的) -
hujingwei1001:
太好了找的就是它
easy explore -
xiangtui:
例子举得不错。。。学习了
java callback -
幻影桃花源:
太好了,謝謝
Spring3 MVC 深入研究
发表评论
-
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之三
2014-12-09 10:33 786原文地址:http://www.techo ... -
241个jquery插件—jquery插件大全
2014-12-09 10:26 802原文地址:http://blog.csdn.net/adsda ... -
前端ui的js框架
2014-09-04 16:45 594原文地址:http://www.quickui.net/v3/ ... -
2014 年最火的21个JavaScript框架
2014-09-03 17:25 478原文地址:http://www.iteye.com/news/ ... -
Bootstrap 栅格系统
2014-08-08 15:53 518原文地址:http://www.cnblogs.com/lin ... -
自定义Bootstrap
2014-08-08 10:14 686原文地址:http://www.w3cplus.com/css ... -
使用python/casperjs编写终极爬虫-客户端App的抓取
2014-08-06 18:09 9551.缘起 随着移动互 ... -
使用Selenium和PhantomJS解析带JS的网页
2014-08-06 17:57 1048有的网页,不能直接通过wget/curl等命令、或者直接使用P ... -
数据抓取的艺术(一):Selenium+Phantomjs数据抓取环境配置
2014-08-06 17:56 621原文地址:http://blog.chin ... -
ubuntu12.04 下安装nodejs【整理】
2014-06-12 14:38 733ubuntu12.04 下安装nodejs【整理】 作者:杭州 ... -
Ubuntu安装nodeJS
2014-06-12 14:38 513Ubuntu安装nodeJS 安装环境 ubuntu12. ... -
纯js页面跳转整理
2014-05-20 18:06 527纯js页面跳转整理 js页面跳转 js方式的页面跳转 1. ... -
细说Cookie
2013-09-29 15:14 650细说Cookie 阅读目录 开始 ... -
JavaScript Source Map 详解
2013-08-30 09:49 808JavaScript Source Map 详解 ... -
主题:50个令人惊奇的jQuery插件
2013-05-29 18:17 989jQuery拥有强大的有创造性的程序员群体。 然而,它很难通 ... -
jquery触发事件
2013-05-23 17:25 612Snandy Stop, thinking is th ... -
jquery事件命名空间
2013-05-23 17:13 518JQUERY事件命名空间 2012 ... -
jQuery的事件命名空间-Namespaced Events
2013-05-23 17:12 633jQuery的事件命名空间-Namespaced Event ... -
JQuery自定义事件的应用 JQuery最佳实践
2013-05-23 16:54 800本文主要介绍JQuery框架里面支持的自定义事件模型,通过实 ... -
jquery插件开发
2013-05-13 15:01 715此文引自:http://www.cnblogs.com/to ...
相关推荐
Draft.js则是React生态中的优秀富文本编辑器,基于 Immutable.js 和 React 库构建,适用于需要高性能和高灵活性的项目。 在实际应用中,富文本编辑器的使用需要注意以下几点: 1. 数据存储:富文本编辑器生成的内容...
标题中的“一款基于vue3+typescript+element plus的HTML5富文本编辑器”揭示了这个项目的核心技术栈,包括Vue.js的最新版本Vue 3、TypeScript以及Element Plus UI库。Vue 3是当前非常流行的前端框架,它提供了组件化...
这个实例展示了一个纯HTML实现的富文本编辑器,这意味着它不依赖于特定的服务器端技术,如JSP、ASP或PHP,而是可以直接嵌入到这些语言创建的页面中。这样做的好处是提高了跨平台兼容性,使得开发者可以方便地在各种...
**WPF.HtmlEditor富文本编辑器Demo**是一个用于Windows Presentation Foundation (WPF)应用程序的示例项目,它展示了如何在WPF环境中实现一个功能丰富的HTML编辑器。这个编辑器允许用户进行基本的文本编辑,查看HTML...
富文本编辑器是一种在网页或应用程序中用于创建和编辑复杂文本格式的工具,它提供了丰富的文本格式化选项,如加粗、斜体、下划线、颜色调整、字体选择、段落样式等。在前端开发中,富文本编辑器是构建内容管理系统、...
在Web开发中,富文本编辑器是不可或缺的一部分,它们通常被用作后台管理系统、论坛、博客和其他需要用户输入复杂格式文本的地方。 富文本编辑器的核心功能包括: 1. **文本格式化**:用户可以对文本进行加粗、斜体...
富文本编辑器是一种用于网页和应用程序的工具,它允许用户以类似于Word文档的方式输入、编辑和格式化文本。这类编辑器通常支持多种功能,如字体样式调整、颜色修改、插入图片、链接添加以及表情符号的使用。在描述中...
在这个富文本编辑器中,`prefixfree.min.js`是一个用于自动处理浏览器前缀的JavaScript库,它使得开发者无需手动添加像`-webkit-`或`-moz-`这样的浏览器特定前缀,从而简化了CSS代码,并提高了代码的可维护性。...
富文本编辑器是一种用于网页和应用程序的工具,它允许用户以类似于Word的界面编辑文本,提供了丰富的格式化选项,如字体、字号、颜色、对齐方式、插入图片、链接等。这种编辑器使得用户在网页上创建和编辑内容时无需...
"sdEditor富文本编辑器 v1.1.1.zip" 是一个包含富文本编辑器相关资源的压缩包,主要用于提供用户界面友好的文本编辑功能。这个编辑器可能被用于网站内容管理、论坛发帖、博客撰写等场景,适用于网页开发和计算机应用...
百度Ueditor是一款由百度公司开发的开源、免费的在线富文本编辑器,主要用于Web应用中提供便捷的文本编辑功能。它以其强大的功能、良好的用户体验以及易于集成的特点,被广泛应用在各类网站和项目中。 ### 主要特点...
虽然没有一个统一的标准,但对于最基本的功能,各浏览器提供的 API 基本一致,从而使编写一个跨浏览器的富文本编辑器成为可能。 在很多开发者看来,富文本编辑器的编写是一件很神秘或者复杂的事情。神秘倒没有,复杂...
在现代Web开发中,富文本编辑器是必不可少的工具,特别是在需要用户输入格式化内容的场景下,如博客、论坛、评论系统等。H5(HTML5)作为最新的Web标准,提供了更多的API和功能,使得富文本编辑器的实现更加方便和...
总结起来,富文本编辑器是网页应用中不可或缺的一部分,它简化了内容创作和管理的过程。"富文本编辑器 .zip"可能是一个包含该编辑器源码或构建文件的压缩包,适合开发人员下载并集成到自己的项目中。在选择和使用富...
"jQuery富文本编辑器Notebook"是一个专为创建简洁、整洁且美观的所见即所得(WYSIWYG)编辑器而设计的工具。这款编辑器利用了流行的jQuery库,旨在提供一个用户友好的界面,使得内容创作者可以轻松地进行文字编辑、...
这个库使得开发者能够方便地在应用程序中集成一个功能齐全的富文本编辑框,提供与桌面级富文本编辑器相似的体验。它的主要特点包括: 1. **样式支持**:cwac-richedit支持插入和编辑各种文本样式,如粗体、斜体、...
TinyMCE是一款强大的开源富文本编辑器,广泛应用于网页内容编辑和内容管理系统中。它提供了丰富的功能,使得用户可以像在Word中一样编辑文本,包括字体样式、字号、颜色、对齐方式、列表、图像插入、链接添加等。...