简述

Tim Berners-Lee 1990年创建的第一个浏览器支持所见即所得( WYSIWYG )方式编辑网页。Web 被设计为可读可写的媒介。然而后来的浏览器只能读取网页,只能通过表单控件输入简单的纯文本信息。

Internet Explorer 5 又重新开始支持 WYSIWYG 编辑:designMode 属性允许用户修改整个页面。然而此属性没有得到普遍使用,也许是因为它被淹没在一堆 Windows-专用的 IE 扩展中。

最近几年微软的竞争者—— Mozilla, Safari 和 Opera ——也实现了类似的编辑功能。WHATWG-工作组正致力于标准化网页编辑系统——HTML 5中引入了 designMode 和 contentEditable DOM 属性。网页的 WYSIWYG 编辑功能将是未来 Web 的重要组成部分。

本文介绍在浏览器中使用 HTML 5 编辑功能的基本方法,及可能碰到的问题。包括以下内容:

不同的开启编辑功能的方法

编辑命令

编辑产生的 HTML 代码

与 DOM 交互

本文是两篇系列文章的第一篇,第二篇将详细介绍如何实现 HTML 编辑器。

注意: 我只介绍最新版本的浏览器(Opera 9.5, Firefox 2+ 和 Safari 3)支持的编辑功能,之前版本的浏览器充满了 bug 。IE 浏览器的编辑功能从 IE 5.5 开始就没有重大改进。)

编辑系统概览

编辑系统允许编辑整个网页或部分网页。其包含以下几个特点:

插入光标( caret )显示目前插入点。用户可通过键盘或鼠标移动光标、选择文本、输入或者删除内容。

有些浏览器提供用户界面以改变元素大小或位置;这些可编辑元素包括图像、表格和表单控件。

浏览器内建了一些标准编辑命令—— Bold, Italic, InsertLink, Paste, Undo 等。可以通过快捷键或者通过 command API 利用脚本使用这些命令。使用 command API 可以轻松的实现 HTML 编辑工具栏。

通过 Range 和 Selection API 可以任意修改 HTML 文件;可以用此方法实现自定义编辑命令。

编辑系统允许用户修改 HTML 。系统不管你如何使用修改后的 HTML 文档。比如你想把修改后的网页复制到服务器中,可通过脚本实现。

在使用编辑系统时需要注意:

编辑命令的定义不是很清晰,不同的浏览器生成的 HTML 有较大差异。

IE 编辑功能自从2000年的 IE 5.5 以后就未有重大变化。其产生的 HTML 代码可能令人吃惊——你很可能在其中发现 标签!

启用编辑功能

有两种方法可在网页中创建可编辑部分 ——designMode 和 contentEditable 属性。

通过设置 document 对象的 designMode 属性为 true ,窗口或框架就变为可编辑的。(注意:在 IE 中此操作会使文档引用失效;应从 window 对象中重新获取)。通常会产生一个编辑窗口(designMode模式的 IFrame )。

所有包含文字的元素都可以通过设置 contentEditable为 true 变为可编辑的。( Firefox 2不支持contentEditable,但是 Firefox 3 和 IE, Opera 和 Safari 支持)。

键盘编辑

和其他编辑器类似,浏览器 HTML 编辑也可以使用鼠标和键盘。当文档获取 focus 后会显示插入光标,可通过鼠标或键盘移动插入光标。可通过键盘输入或删除字符。可通过键盘或鼠标移动、删除或替换选中文本。

一个很好的特性是所有的键盘编辑动作都被记录而且可以撤销。(如何使用 Undo 命令参看下文)

按下 Enter/Return 键后的处理方法比较复杂。很难定义此动作应该产生怎样的 HTML 代码,不同的上下文将产生不同的结果;不同的浏览器产生的 HTML 代码也存在很大差异。如果插入光标位于 (非空的) p 元素中,所有浏览器都应该闭合此 p 元素,插入新的(使用相同属性) 并把插入光标置于新的 p 元素。( Mozilla 会在插入光标后插入 (多余的) br 元素。)

例子如下 (在下面的例子中|符号代表插入光标位置):

bla bla|

在 IE 或 Safari 中按下回车后:

bla bla

|

如果插入光标在 (非空) h1 元素之后,所有浏览器都会关闭 h1,但 IE 和 Opera 会插入新的 p 元素并将光标置于 p 元素中;Safari 会插入新的 h1 元素并将光标置于新元素中; Mozilla 不创建任何元素,但会在光标后插入两个 br 元素。如:

bla bla|

在 IE 或 Opera 中按下回车后:

bla bla

|

但在 Mozilla 中变为:

bla bla

|

在 Safari 中变为:

bla bla

|

如果你直接在 body 元素中输入 (而不使用其他容器元素)并点击确定,在 Mozilla 中会插入 br 元素。IE 和 Opera 会把前面的文字转换成 p 元素并插入新的 p元素;而 Safari 将插入 div 元素。

如果在 div 元素中输入“回车”, Safari, Opera 和 IE 会关闭当前的 div 并插入新的div。Mozilla 会在当前div 中插入一个br 元素。

如果光标在嵌套的块级元素中( block level element),所有浏览器都会关闭最内层的元素并把光标置于次外层块元素中。

结论:这真复杂!令人惊奇的是 IE 居然是最好的实现,其总能保证块级元素的正确性。Mozilla 最烂,总用br代替块元素,这样就无法为文字设置样式了。

光标位置

插入光标可在字符间移动。但是无法看到光标相对于标签的位置。所有浏览器的处理方法一致。光标相对于块级元素的处理方法:光标总是位于最内层的块元素。不能把光标置于两段之间。

如下所示,| 符号显示可能的插入点位置:

|P|1|

|P|2|

|P|3|

|P|4|

光标相对于 inline 元素处理方法:如果光标在文字左边则被认为在所有元素外;如果光标在文字右边则被认为在元素内:

|A|B|C|

所以如果你在加粗文字 range 左边输入文字,新文字不是加粗的。如果你在 range 右边添加字符,则新文字也是加粗的。

删除

如果删除段落边界,结果是一致的 —— 左边的块 “获胜” 右边的内容会被加入到左边元素中:

Overskrift

|Text

按删除后结果如下:

Overskrift|Text

Safari 浏览器的实现方法比较聪明 (或者比较糟糕,这取决于你的喜好):

Overskrift|Text

编辑 Object

浏览器提供用户界面以编辑特殊的 HTML 对象。

IE 允许改变图像、表格、表单元素大小,或通过拖拽改变元素位置 (当选中元素后,出现拖拽图标)。

Mozilla 允许改变图像和表格大小,并允许通过附加控件创建新的行和列。Mozilla 也支持改变元素位置,此功能的 UI 是专利保护的并只能用于 Mozilla 浏览器,且无法定制使用。

编辑命令 (Editing command)

不同浏览器支持不同编辑命令。这些命令产生的 HTML 代码没有被标准化,因此不同浏览器产生结果不同。如,在 IE 中“加粗” 命令生成代码为:

Hello!

而 Safari 生成代码为:

hello!

产生的代码都是比较老式的代码风格,至少在 IE 浏览器中如此。很多编辑命令会产生已遭弃用的 font 标签 (如23);产生的 HTML 无法通过 XHTML 验证,有时甚至不是合法的 HTML!

Opera 的 HTML 编辑命令类似于 IE,也使用 元素。Safari 通过 和内联 CSS修改文本样式。Safari 方法的优点是生成的 HTML 代码可以通过 HTML 4.01 Strict 验证。

Mozilla 支持上面两种方法——既可以和 IE/Opera 产生显示性元素,也可以如 Safari 一样产生样式属性。

如果你重视 HTML 验证,你应该在服务器端实现检查功能,以把修改后网页变为合法 (X)HTML文件(无论如何你都应该这样做,以防止 XSS-攻击)。

键盘快捷键

许多编辑命令可以通过快捷键实现:如Ctrl/Cmd + B 设置加粗,Ctrl/Cmd + Z 是撤销命令等。但不同浏览器中有不同的快捷键。

不能重新设置快捷键,但可以通过脚本截获键盘事件,以重新定义快捷键功能。

command API

比如你想实现一个文本编辑工具栏,用户可以使用此工具栏改变文字格式。这可以通过命令 API 实现。此 API 和常见的 DOM API 不同,其实际上是允许脚本的 IOleCommandTarget 接口——此接口是微软用于同步工具栏的 COM 接口。

command API 在 Document 对象中,由 execCommand 方法和一系列以 “query” 开头的方法组成(这些方法返回 command 相关信息)。

所有的方法的第一个参数是 command ID ,即是字符串形式的 command 名称。command API 的方法如下所示。

ExecCommand

对选中元素执行 command 。有些命令设置/取消属性——如 bold 命令如果作用于已经加粗的文本,则会取消加粗。有些命令要求参数值——如 forecolor 命令需要颜色值。有些命令使用标准对话框——如 link 命令会显示对话框以允许用户输入 URL。无法自定义对话框,但是可以不用:

result = document.execCommand(command, useDialog, value)

上例详细解释:

command: 字符串;命令名称。

useDialog: 布尔值;是否显示 built-in 对话框 (并不是所有命令都需要对话框)。

value: 命令参数值。并不是所有命令都需要参数值;如果使用了 built-in 对话框,则此值将来自对话框。

result:如果命令被执行了则返回 true ;否则返回 false(如用户在对话框中选择了取消,或者命令无法执行)。

如果未选中任何内容 (只有插入光标),不同浏览器对于文本格式命令的解释不同。 如果插入光标位于单词中,IE 会将格式命令作用于整个词;而其他浏览器只作用于下一个字符。

QueryCommands

查询命令主要用于获取关于选中内容的信息。

QueryCommandEnabled

查询此命令是否能用于当前选中内容。如只有选中元素位于链接中才能使用 “删除链接” 命令。如果所选内容并非位于可编辑区域中,所有的命令都将被禁用。

QueryCommandState

查询此命令是否已经作用过选中内容。如当前选中内容为粗体,则 bold 命令的返回值为 true 。

QueryCommandValue

此函数返回值即为 execCommand 命令中使用的值,如ForeColor 返回当前选中内容的颜色值 (字符串形式) 。

不同浏览器的返回值格式不同。如 ForeColor 在IE中返回十六进制颜色码 (如 #ff0000),而在其他浏览器中返回 RGB 形式的颜色值,如 Rgb(255,0,0)。

有些返回值甚至根据浏览器 locale不同而不同,如 FormatBlock在 IE 中返回浏览器所用语言表示的段落名称。

像 bold 这样的命令没有返回值,只返回 false。(API 另外包含两个方法,queryCommandSupported 和 queryCommandIndeterminate,但这两个函数实现普遍质量不高,不堪重用。)

Range 和 Selection API

built-in 命令对处理一些简单问题比较有用,但无法随心所欲编辑网页。通过 Range 和 Selection API 可以任意的修改 HTML ,也可以实现自定义命令。

所有通过 DOM 的网页修改都会破坏撤销栈( undo-stack ),撤销栈用于实现撤销/重做命令。这虽然很不方便,但却是为了实现自定义命令必须付出的代价。

range/selection API 有两个核心类:

Range——网页中的字符之集。Range 可以跨多个元素。Range 有起点和终点。如果起点和终点相同,则称 range 为收缩的(collapsed)。

Selection ——代表当前选中内容。selection 包含一个高亮显示的 range 。如果选中的 range 是收缩的,则显示为一个插入光标(caret)。

(Range 和 selection 只能用于可编辑区域内。可在只读文档中创建 selection 。但是只读文档中的selection 不能是收缩的,因为只读文档无法显示 caret。)

这些概念在所有浏览器中都是一样的,但是具体的 API 却不完全相同——与其他浏览器不同,IE 使用自己定义的 range 和 selection API,而其他浏览器使用的是W3C DOM Range API 和未标准化的 selection API。

最大的不同时 IE 中 range 内容是字符串型式的 HTML 标记代码。而在 W3C DOM Range API 中 Range 内容通过 DOM 树访问。

Range 示例

下面是两种不同的实现方法:

在 IE (editWindow 即是 designMode模式下的框架)中:

var rng = editWindow.document.selection.createRange();

rng.pasteHTML("" + rng.htmlText + "");

在 Mozilla中

var rng = editWindow.getSelection().getRangeAt(0);

rng.surroundContents(document.createElement("code"));

Control 选择

IE 支持控件选择,但和 range 选择不同。点击如图形、表单控件或表格边框等对象时将被视为控件选择。

可以通过 Ctrl 键在 IE 中选择多个控件。其他浏览器中不存在控件选择概念;在这些浏览器中所有选择都是 text range 。

什么浏览器可以修改html,浏览器 HTML 编辑: (1) | Opera 中国相关推荐

  1. 修改360浏览器 标题栏 显示的文字

    作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com E-mail: 313134555 @qq.com 修改360浏览器 标题栏 显示的文字 === ...

  2. DreamweaverCS6 - BUG(2) —— 编辑浏览器列表无法添加浏览器

    需求分析 DWCS6安装成功,由于默认使用IE 为了便捷运行网页和使用习惯的浏览器,例如:Firefox和Google, 我们通常会在编辑浏览器列表添加新的主浏览器 还原现场 1.点击浏览器中预览/调 ...

  3. dwcs6中php为什么浏览不了,dreamweaver CS6编辑浏览器列表无法添加浏览器的解决处理...

    各位朋友们想知道dreamweaver编辑浏览器列表无法添加浏览器应该怎样处理吗?你们可以跟随小编一起去下文教程中学习一下dreamweaver编辑浏览器列表无法添加浏览器的详细操作流程. dream ...

  4. 修改百分浏览器(centbrowser)、谷歌和火狐浏览器默认字体的方法

    修改百分浏览器(centbrowser).谷歌和火狐浏览器默认字体的方法 1,百分浏览器(centbrowser) 在浏览器的安装位置D:\Program Files\Cent Browser\Use ...

  5. html不能默认IE浏览器,教你设置IE浏览器无法修改主页的处理方法

    发打开网页的操作技巧有很多的,小伙伴们可以使用电脑自带的IE浏览器来进行上网还有直接打开网站在查看,有小伙伴在IE浏览器的使用中提问自己的电脑中想要直接添加修改IE浏览器中的主页为自己经常使用的一个但 ...

  6. html注册表,通过注册表修改IE浏览器

    通过注册表修改IE浏览器 给IE5添加多个HTML编辑器 HKEY_CURRENT_USER\ Software\Microsoft\Internet Explorer\Default HTML Ed ...

  7. vsCode中代码保存自动刷新页面,open with live server,可修改打开浏览器

    前言 在我们使用vscode写代码的时候,每次修改都要先保存,再刷新浏览器才能看到代码变动后的效果,如果只要保存,浏览器会自动刷新岂不是更好,下面这种方法就可以做到. 插件市场安装live serve ...

  8. vue项目-点击添加或者修改按钮浏览器的屏幕变黑,再次点击屏幕之后浏览器恢复正常(火狐浏览器、ChromeCoreLauncher双核浏览器)

    今天在写springboot+vue项目的时候发现了一个bug,之前写的项目就没有这种情况,bug如下: 点击添加或者修改按钮浏览器的屏幕变黑,再次点击屏幕之后浏览器恢复正常 点击修改按钮 屏幕变黑 ...

  9. 如何修改IE浏览器的User-Agent用户代理字符串信息

    每款浏览器都有一个专属的 User-Agent 字符串信息, 通过 User-Agent 网站可以检测用户所使用的浏览器版本.某些网站为了让用户获得更好的浏览体验,通过检测用户的浏览器版本,以确认用户 ...

最新文章

  1. 发布 128 核 Altra Max,自研内核,明年推出 5nm 处理器,“性能怪兽”Ampere 搞大事?...
  2. 面试官问:服务的心跳机制与断线重连,Netty底层是怎么实现的?懵了
  3. Java知识点总结(JavaIO-合并流类)
  4. 人工智能能否在对抗虚假新闻战争中完胜?
  5. 基于 EntityFramework 的数据库主从读写分离架构(2)- 改进配置和添加事务支持...
  6. 2011 总结 2012 计划
  7. 哈佛大学推荐的20个快乐习惯
  8. 【数据竞赛】图像赛排行榜拉开100名差距的技巧
  9. 【计算机组成原理】数据表示和运算
  10. javascript --- js中的事件
  11. 说说python程序的执行过程_表示说的词语
  12. 小说网jsp源码_基于jsp+mysql的JSP小说网
  13. Vue报错:3 errors and 0 warnings potentially fixable with the `--fix` option.
  14. ARCH-LINUX 折(安)腾(装)记
  15. Hive Managed Table与 External Table区别
  16. CCF201812-4 数据中心(100分)【Kruskal算法】
  17. iStat Menus 6.51 mac中文版
  18. d3.js中点可以用图片吗_WebGL 直线直吗?
  19. 61850协议服务器端开发,基于IEC61850标准的服务端程序的设计与实现
  20. 【期权机理与python实践】

热门文章

  1. Atik工业相机应用案例研究——涡轮叶片氧化铝检测成像系统
  2. 常见的一些:文件类型
  3. 读取海康工业相机(gige)数据流
  4. C#和Halcon联合编程完成海康工业相机数据转化
  5. 读书笔记:3层神经网络的Python实现 ← 斋藤康毅
  6. banq的设计模式资料
  7. 数字电压电流表VCB
  8. BMZCTF Reverse3
  9. 2月24日android学习笔记——ListView
  10. 可穿戴设备数据监测登榜2016十大医疗创新