JS高级程序设计——第14章 表单脚本(表单序列化、富文本编辑)

一、表单序列化

随着 Ajax 的出现,表单序列化已经成为一种常见需求(第 21 章将讨论 Ajax)。在 JavaScript 中,可 以利用表单字段的 type 属性,连同 name 和 value 属性一起实现对表单的序列化

  1. 在编写代码之前, 有必须先搞清楚在表单提交期间,浏览器是怎样将数据发送给服务器的
    在这里插入图片描述
  2. 在表单序列化过程中,一般不包含任何按钮字段,因为结果字符串很可能是通过其他方式提交的。除此之外的其他上述规则都应该遵循。以下就是实现表单序列化的代码
    在这里插入图片描述在这里插入图片描述
  • 上面这个 serialize()函数首先定义了一个名为 parts 的数组用于保存将要创建的字符串的各个部分
  • 然后,通过 for 循环迭代每个表单字段,并将其保存在 field 变量中。
  • 获得了一个字段的引用之后,使用 switch 语句检测其 type 属性。
  • 序列化过程中最麻烦的就是<select>元素,它可能是单选框也可能是多选框。为此,需要遍历控件中的每一个选项,并在相应选项被选中的情况下向数组中添加一个值。对于单选框,只可能有一个选中项,而多选框则可能有零或多个选中项。这里的代码适用于这两种选择框,至于可选项的数量则是由浏览器控制的。
  • 在找到一个选中项之后,需要确定使用什么值。如果不存在 value 特性,或者虽然存在该特性,但值为空字符串,都要使用选项的文本来代替
  • 为检查这个特性,在 DOM 兼容的浏览器中需要使用 hasAttribute()方法,而在 IE 中需要使用特性的 specified 属性
  • 如果表单中包含<fieldset>元素,则该元素会出现在元素集合中,但没有 type 属性。因此,如果 type属性未定义,则不需要对其进行序列化。同样,对于各种按钮以及文件输入字段也是如此(文件输入字段在 表单提交过程中包含文件的内容;但是,这个字段是无法模仿的,序列化时一般都要忽略)。
  • 对于单选按钮 和复选框,要检查其 checked 属性是否被设置为 false,如果是则退出 switch 语句。如果 checked 属性为 true,则继续执行 default 语句,即将当前字段的名称和值进行编码,然后添加到 parts 数组中。
  • 函数的最后一步,就是使用 join()格式化整个字符串,也就是用和号来分隔每一个表单字段。

最后,serialize()函数会以查询字符串的格式输出序列化之后的字符串。当然,要序列化成其他 格式,也不是什么困难的事。

二、富文本编辑

1、什么是富文本编辑?
  1. 富文本编辑,又称为 WYSIWYG(What You See Is What You Get,所见即所得)。在网页中编辑富文本内容,是人们对 Web 应用程序最大的期待之一。虽然也没有规范,但在 IE 最早引入的这一功能基础上,已经出现了事实标准。而且,Opera、Safari、Chrome 和 Firefox 都已经支持这一功能。
  2. 这一技术的本质:就是在页面中嵌入一个包含空 HTML 页面的 iframe。通过设置 designMode 属性,这个空白 的 HTML 页面可以被编辑,而编辑对象则是该页面<body>元素的 HTML 代码。
  3. designMode 属性有两个可能的值"off"(默认值)和"on"在设置为"on"时,整个文档都会变得可以编辑(显示插入符 号),然后就可以像使用字处理软件一样,通过键盘将文本内容加粗、变成斜体,等等。
  4. 可以给 iframe 指定一个非常简单的 HTML 页面作为其内容来源。例如:
    在这里插入图片描述
  • 这个页面在 iframe 中可以像其他页面一样被加载要让它可以编辑,必须要将 designMode 设置 为"on",但只有在页面完全加载之后才能设置这个属性。因此,在包含页面中,需要使用 onload 事件 处理程序来在恰当的时刻设置 designMode,如下面的例子所示:
    在这里插入图片描述
    等到以上代码执行之后,你就会在页面中看到一个类似文本框的可编辑区字段。这个区字段具有与 其他网页相同的默认样式;不过,通过为空白页面应用 CSS 样式,可以修改可编辑区字段的外观
2、使用contenteditable属性
  1. 另一种编辑富文本内容的方式是使用名为 contenteditable 的特殊属性,这个属性也是由 IE 最早实现的。可以把 contenteditable 属性应用给页面中的任何元素,然后用户立即就可以编辑该元素。 这种方法之所以受到欢迎,是因为它不需要 iframe、空白页和 JavaScript,只要为元素设置 contenteditable 属性即可
    在这里插入图片描述
  2. 这样,元素中包含的任何文本内容就都可以编辑了,就好像这个元素变成了<textarea>元素一样。 通过在这个元素上设置 contenteditable 属性,也能打开或关闭编辑模式
    在这里插入图片描述
  • contenteditable 属性有三个可能的值"true"表示打开、"false"表示关闭,"inherit"表示 从父元素那里继承(因为可以在 contenteditable 元素中创建或删除元素)。支持 contenteditable 属性的元素有 IE、Firefox、Chrome、Safari 和 Opera。在移动设备上,支持 contenteditable 属性的 浏览器有 iOS 5+中的 Safari 和 Android 3+中的 WebKit。
3、操作富文本
  1. 与富文本编辑器交互的主要方式,就是使用 document.execCommand()。这个方法可以对文档执行预定义的命令,而且可以应用大多数格式
  • 可以为 document.execCommand()方法传递 3 个参数: 要执行的命令名称表示浏览器是否应该为当前命令提供用户界面的一个布尔值执行命令必须的一个值(如果不需要值,则传递 null)。
  • 为了确保跨浏览器的兼容性,第二个参数应该始终设置为 false因为 Firefox 会在该参数为 true 时抛出错误
  1. 不同浏览器支持的预定义命令也不一样。下表列出了那些被支持最多的命令
    在这里插入图片描述
    在这里插入图片描述
  • 其中,与剪贴板有关的命令在不同浏览器中的差异极大。Opera 根本没有实现任何剪贴板命令,而 Firefox 在默认情况下会禁用它们(必须修改用户的首选项来启用它们)。Safari 和 Chrome 实现了 cut 和 copy,但没有实现 paste。不过,即使不能通过 document.execCommand()来执行这些命令,但却可以通过相应的快捷键来实现同样的操作
    在这里插入图片描述
  • 同样的方法也适用于页面中 contenteditable 属性为"true"的区块,只要把对框架的引用替换成当前窗口的 document 对象即可。
    在这里插入图片描述
  • 需要注意的是,虽然所有浏览器都支持这些命令,但这些命令所产生的 HTML 仍然有很大不同。 例如,执行 bold 命令时,IE 和 Opera 会使用<strong>标签包围文本,Safari 和 Chrome 使用<b>标签,而 Firefox 则使用<span>标签。由于各个浏览器实现命令的方式不同,加上它们通过 innerHTML 实现 转换的方式也不一样,因此不能指望富文本编辑器会产生一致的 HTML
  • 除了命令之外,还有一些与命令相关的方法。第一个方法就是 queryCommandEnabled(),可以用它来检测是否可以针对当前选择的文本,或者当前插入字符所在位置执行某个命令。这个方法接收一个参数,即要检测的命令。如果当前编辑区域允许执行传入的命令,这个方法返回 true,否则返回 false。例如:
    在这里插入图片描述
    需要注意的是,queryCommandEnabled()方法返回 true,并不意味着实际上就可以执行相应命令,而只能说明对当前选择的文本执行相应命令是否合适。例如,Firefox 在默认情况下会禁用剪切操作,但执行 queryCommand- Enabled(“cut”)也可能会返回 true。
  • 另外,queryCommandState()方法用于确定是否已将指定命令应用到了选择的文本。例如,要确定当前选择的文本是否已经转换成了粗体,可以使用如下代码。
    在这里插入图片描述
    如果此前已经对选择的文本执行了"bold"命令,那么上面的代码会返回 true。一些功能全面的富文本编辑器,正是利用这个方法来更新粗体、斜体等按钮的状态的
  • 最后一个方法是 queryCommandValue(),用于取得执行命令时传入的值(即前面例子中传给 document.execCommand()的第三个参数)。例如,在对一段文本应用"fontsize"命令时如果传入了 7,那么下面的代码就会返回"7":
    在这里插入图片描述
    通过这个方法可以确定某个命令是怎样应用到选择的文本的,可以据以确定再对其应用后续命令是否合适
4、 富文本选区
  1. 在富文本编辑器中,使用框架(iframe)getSelection()方法,可以确定实际选择的文本。 这个方法是 window 对象和 document 对象的属性,调用它会返回一个表示当前选择文本的 Selection 对象每个 Selection 对象都有下列属性。
    在这里插入图片描述
  2. Selection 对象的这些属性并没有包含多少有用的信息。好在,该对象的下列方法提供了更多信息,并且支持对选区的操作。
    在这里插入图片描述
  • Selection 对象的这些方法都极为实用,它们利用了(第 12 章讨论过的)DOM 范围来管理选区。 由于可以直接操作选择文本的 DOM 表现,因此访问 DOM 范围与使用 execCommand()相比,能够对富文本编辑器进行更加细化的控制。下面来看一个例子。
    在这里插入图片描述
    以上代码会为富文本编辑器中被选择的文本添加黄色的背景。这里使用了默认选区中的 DOM 范围, 通过 surroundContents()方法【12章的方法】将选区添加到了带有黄色背景的<span>元素中。
  1. HTML5 将 getSelection()方法纳入了标准,而且 IE9、Firefox、Safari、Chrome 和 Opera 8 都实 现了它。
  • 由于历史原因,在 Firefox 3.6+中调用 document.getSelection()会返回一个字符串。为此, 可以在 Firefox 3.6+中改作调用 window.getSelection(),从而返回 selection 对象。Firefox 8 修复 了 document.getSelection()的 bug,能返回与 window.getSelection()相同的值。
  • IE8 及更早的版本不支持 DOM 范围,但我们可以通过它支持的 selection 对象操作选择的文本。 IE 中的 selection 对象是 document 的属性,本章前面曾经讨论过。要取得富文本编辑器中选择的文 本,首先必须创建一个文本范围(请参考第 12 章中的相关内容),然后再像下面这样访问其 text 属性
    在这里插入图片描述
  • 虽然使用 IE 的文本范围来执行 HTML 操作并不像使用 DOM 范围那么可靠,但也不失为一种有效的途径。要像前面使用 DOM 范围那样实现相同的文本高亮效果,可以组合使用 htmlText 属性和 pasteHTML()方法
    在这里插入图片描述
    以上代码通过 htmlText 取得了当前选区中的 HTML,然后将其放在了一对<span>标签中,最后又使用 pasteHTML()将结果重新插入到了选区中
5、表单与富文本
  1. 由于富文本编辑是使用 iframe 而非表单控件实现的,因此从技术上说,富文本编辑器并不属于表单。换句话说,富文本编辑器中的 HTML 不会被自动提交给服务器,而需要我们手工来提取并提交 HTML
  2. 为此,通常可以添加一个隐藏的表单字段,让它的值等于从 iframe 中提取出的 HTML
  • 具体来说,就是在提交表单之前,从 iframe 中提取出 HTML,并将其插入到隐藏的字段中。下面就是通过 表单的 onsubmit 事件处理程序实现上述操作的代码。
    在这里插入图片描述
    在此,我们通过文档主体的 innerHTML 属性取得了 iframe 中的 HTML,然后将其插入到了名为 "comments"的表单字段中。这样可以确保恰好在提交表单之前填充"comments"字段。如果你想在代码中通过 submit()来手工提交表单,那么一定不要忘记事先执行上面的操作
  • 对于 contenteditable 元素,也可以执行类似操作。
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值