首先推荐如下本身的轻量无依赖富文本编辑器:html
CCEditorhtml5
以为不错,给个star支持一下,谢谢node
JavaScript最初的一个应用,就是分担服务器处理表单的责任,打破到处依赖服务器的局面。尽管目前的Web和JavaScript已经有了长足的发展,但Web表单的变化并不明显。因为Web表单没有为许多常见任务提供现成的解决手段,不少开发人员不只会在验证表单时使用JavaScript,并且还加强了一些标准表单控件的默认行为。git
在HTML中,表单是由<form>
元素来表示的,,而在JavaScript中,表单对应的则是HTMLFormElement类型。HTMLFormElement继承了HTMLElement,于是与其余HTML元素具备相同的默认属性。不过,HTMLFormElement也有它本身独有的属性和方法。github
用户单击提交按钮或图像按钮时,就会提交表单。使用<input>
或<button>
均可以定义提交按钮,只要将其type特性的值设置为submit
便可,而图像按钮则是经过将<input>
的type特性值设置为“image”来定义的。正则表达式
只要表单中存在上面列出的任何一种按钮,那么在相应表单控件拥有焦点的状况,数组
在用户单击重置按钮时,表单会被重置。使用type特性值为"reset"的<input>
或<button>
均可以建立重置按钮。浏览器
<input type='reset' value='Reset Form'>
<button type='reset'>Reset Form</button>
复制代码
这两个按钮均可以用来重置表单。在重置表单时,全部表单字段都会恢复到页面刚加载完毕时的初始值。若是某个字段的初始值为空,就会恢复为空;而带有默认值的字段,也会恢复为默认值。bash
与提交表单同样,也能够经过JavaScript来重置表单。服务器
能够像访问页面中的其余元素同样,使用原生DOM方法访问表单元素。
此外,每一个表单都有elements属性,该属性是表单中全部元素的集合。这个elements集合是一个有序列表,其中包含着表单中的全部字段
除了<fieldset>
元素以外,全部表单字段都拥有相同的一组属性。因为<input>
类型能够表示多种表单字段,所以有些属性只适用于某些字段,但还有一些属性是全部字段所共有的。表单字段共有的属性和方法以下。
可使用JavaScript动态修改其余任何属性。
// 避免屡次提交表单
form.addEventListener('submit', function (e) {
var target = e.target;
// 取得提交按钮
var btn = target.elements['submit-btn'];
//禁用它
btn.disabled = true;
})
复制代码
以上代码为表单的submit事件添加了一个事件处理程序。事件触发后,代码取得了提交按钮并将其disabled属性设置为true。
注意,不能经过onclick事件处理程序来实现这个功能,缘由是不一样浏览器之间存在“时差”:有的浏览器会在触发表单的submit事件以前触发click事件,有的浏览器则相反。对于先触发click事件的浏览器,意味着会在提交发生以前禁用按钮,结果永远都不会提交表单。所以,最好是经过submit事件来禁用提交按钮。不过,这种方式不适合表单中不包含提交按钮的状况;如前所述,只有在包含提交按钮的状况下,才有可能触发表单的submit事件。
每一个表单字段都有两个方法:focus()和blur()。其中,focus()方法用于将浏览器的焦点设置到表单字段,即激活表单字段,使其能够响应键盘事件。例如,接收到焦点的文本框会显示插入符号,随时能够接收输入。
默认状况下,只有表单字段能够得到焦点。对于其余元素而言,若是现将其tabIndex属性设置为-1,而后再调用focus()方法,也可让这些元素得到焦点。
强调: tabindex设置为-1可让不能被focus的元素变的能够focus。可是设置好后,只能经过js的focus()方法来选中,没法经过键盘的tab选中。
除了支持鼠标、键盘、更改和HTML事件以外,全部表单字段都支持下列3个事件。
<input>和<textarea>
元素,在它们失去焦点且value值改变时触发;对于<select>
,在其选项改变时触发。在HTML中,有两种方式来表现文本框:一种是使用<input>
元素的单行文本框,另外一种是使用<textarea>
的多行文本框。这两个控件很是类似,并且多数时候的行为也差很少。不过,它们之间仍然存在一些重要的区别。
若是要建立一个文本框,让它可以显示25个字符,但输入不能超过50个字符,可使用如下代码:
<input type='text' size='25' maxlength='50' value='initial value'>
复制代码
相对而言,<textarea>
元素则始终会呈现为一个多行文本框。要指定文本框的大小,可使用rows和cols特性。其中,rows特性指定的是文本框的字符行数,而cols特性指定的是文本框的字符列数。与<input>
元素不一样,<textarea>
的初始值必需要放在<textarea>
和</textarea>
之间。
另外一个与<input>
的区别在于,不能在HTML中给<textarea>
指定最大字数。
建议经过使用value属性读取或设置文本框的值,不建议使用标准的DOM方法。 缘由很简单:对value属性所做的修改,不必定会反映在DOM中。所以,在处理文本框的值时,最好不要使用DOM方法。
上述两种文本框都支持select()方法,这个方法用于选择文本框中的全部文本。在调用select() 方法时,大多数浏览器都会将焦点设置到文本框中。这个方法不接受参数,能够在任什么时候候被调用。
在文本框得到焦点时选择其全部文本,这是一种很是常见的作法,特别是在文本框包含默认值的时候。由于这样作可让用户没必要一个一个地删除文本。
与select()方法对应的,是一个select事件。在选择了文本框中的文本时,就会触发select事件。 另外,在调用select()方法时也会触发select事件。
虽然经过select事件咱们能够直到用户何时选择了文本,但仍然不知道用户选择了什么文本。 HTML5经过一些扩展方案解决了这个问题,以便更顺利地取得选择的文本。
该规范采起的办法是添加两个属性:selectionStart和selectionEnd。
这两个属性中保存的是基于0的数值,表示所选择文本的范围(即文本选区开头和结尾的偏移量)。
HTML5也为选择文本框中的部分文本提供了解决方案,即最先由firefox引入的setSelectionRange() 方法。如今除Select()方法以外,全部文本框都有一个setSelectionRange()方法。这个方法接收两个参数:要选择的第一个字符的索引和要选择的最后一个字符以后的字符的索引。
要看到选择的文本,必须在调用setSelectionRange()以前或以后当即将焦点设置到文本框。
咱们常常会要求用户在文本框中输入特定的数据,或者输入特定格式的数据。因为文本框在默认状况下没有提供多少验证数据的手段,所以必须使用JavaScript来完成此类过滤输入的操做。而综合运用事件的DOM手段,就能够将普通的文本框转换成可以理解用户输入数据的功能型控件。
响应向文本框中插入字符操做的是keypress事件。所以,能够经过阻止这个事件的默认行为 来屏蔽此类字符。
若是只想屏蔽特定的字符,则须要检测keypress事件对应的字符编码,而后再决定如何响应。
虽然理论上只应该在用户按下只应该在用户按下字符键时才触发keypress事件,但有些浏览器也会其余键触发此事件。
除此以外,还有一个问题须要处理:复制、粘贴及其余操做还要用到Ctrl键。在除IE以外的全部浏览器中,前面的代码也会屏蔽ctrl+C、ctrl+V,以及其余使用Ctrl组合件。所以,最后还要添加一个检测条件,以确保用户没有按下Ctrl键。
HTML5后来也把剪贴板事件归入了规范。下列就是6个剪贴板事件。
要访问剪贴板中的数据,可使用clipboardData对象:在IE中,这个对象是window对象的属性; 而在Firefox、Safari和Chrome中,这个对象是相应event对象的属性。
为了确保跨浏览器兼容性,最好只在发生剪贴板事件期间使用这个对象。
这个clipboardData对象有三个方法:getData(format)、setData(format, value)和clearData()。
使用JavaScript能够从多个方面加强表单字段的易用性。其中,最多见的一种方式就是在用户填写完当前字段时,自动将焦点切换到下一个字段。一般,在自动切换焦点以前,必须知道用户已经输入了既定长度的数据。
input有一个问题初始值长度超过maxlength不会被截断。
为了在将表单提交到服务器以前验证数据,HTML5新增了一些功能。有了这些功能,即使JavaScript被禁用或者用于种种缘由未能加载,也能够确保基本的验证。
换句话说,浏览器本身会根据标记中的规则执行验证,而后本身显示适当的错误消息(彻底不用JavaScript插手)。固然,这个功能只有在支持HTML5这部份内容的浏览器中才有效。
第一种状况是在表单字段中指定了required属性:
<input type='text' name='username' required>
复制代码
任何标注有required的字段,在提交表单时都不能空着。
这个属性适用于<input>、<textarea>、<select>
字段。在JavaScript中,经过对应的required 属性,能够检查某个表单字段是否为必填字段。
var isUsernameRequired = document.forms[0].elements['username'].required;
复制代码
另外,使用下面这行代码能够测试浏览器是否支持required属性。
var isRequiredSupported = 'required' in document.createElement('input');
复制代码
HTML5为<input>
元素的type属性又增长了几个值。这些新的类型不只能反映数据类型的信息,并且还能提供一些默认的验证功能。其中“email”和“url”是两个获得支持最多的类型,各浏览器也都为它们增长了定制的验证机制。
要检测浏览器是否支持这些新类型,能够在JavaScript建立一个<input>
元素,而后将type属性设置为“email”和“url”,最后再检测这个属性的值。不支持它们的旧版本浏览器会自动将未知的值设置为“text”,而支持的浏览器则会返回正确的值。
除了“email”和“url”,HTML5还定义了另外几个输入元素。这几个元素都要求填写某种基于数字的值:“number”、“range”、“datetime”、“datetime-local”、“date”、“month”、“week”还有“time”。
HTML5为文本字段新增了pattern属性。这个属性的值是一个正则表达式,用于匹配文本框中的值。
注意,模式的开头和末尾不用加^和$符号(假定已经有了)。这两个符号表示输入的值必须从头至尾都与模式匹配。
与其余输入类型类似,指定pattern也不能阻止用户输入无效的文本。这个模式应用给值,浏览器来判断值是否有效。在JavaScript中能够经过pattern属性访问模式。
var isPatternSupported = 'pattern' in document.createElement('input')
复制代码
使用checkValidity()方法。
与checkValidity()方法简单地告诉你字段是否有效相比,validity属性则会告诉你为何字段有效或无效。这个对象中包含一系列属性,每一个属性会返回一个布尔值。
经过设置novalidate属性,能够告诉表单不进行验证。
在JavaScript中使用noValidate属性能够取得或设置这个值,若是这个属性存在,值为true,若是不存在,值为false。
document.forms[0].noValidate = true; //禁用验证
复制代码
选择框是经过<select>和<option>
元素建立的。为了方便与这个控件交互,除了全部表单字段共有的属性和方法外,HTMLSelectElement类型还提供了下列属性和方法。
<option>
元素,其位置在相关项(relOption)以前。<option>
元素的HTMLCollection。选择框的type属性不是‘select-one’,就是‘select-multiple’,这取决于HTML代码中有没有multiple特性。选择框的value属性由当前选中项决定,相应规则以下:
在DOM中,每一个<option>
元素都有一个HTMLOptionElement对象表示。为便于访问数据,HTMLOptionElement对象添加了下列属性:
其中大部分属性的目的,都是为了方便对选项数据的访问。
var $selectbox = document.forms[0].elements['location'];
//不推荐
var text = selectbox.options[0].firstChild.nodeValue;
var value = selectbox.options[0].getAttribute('value');
//推荐
var text = selectbox.options[0].text; //选项的文本
var value = selectbox.options[0].value; //选项的值
复制代码
在操做选项时,咱们建议最好是使用特定于选项的属性,由于全部浏览器都支持这些属性。在将表单控件做为DOM节点的状况下,实际的交互方式则会因浏览器而异。咱们不推荐使用标准DOM技术修改<option>
元素的文本或者值。
提醒:选择框的change事件与其余表单字段的change事件触发的条件不同。其余表单字段的change事件是在值被修改且焦点离开当前字段时触发,而选择框的change事件只要选中了选项就会触发。
对于只容许选择一项的选择框,访问选中项的最简单方式,就是使用选择框的selectedIndex属性:
var selectedOption = selectbox.options[selectbox.selectedIndex];
var selectedIndex = selectbox.selectedIndex;
var selectedOption = selectbox.options[selectedIndex];
alert("Selected index: " + selectedIndex + '\nSelected text: ' +
selectedOption.text + '\nSelected value: ' + selectedOption.value);
复制代码
对于能够多选的选择框,selectedIndex会致使取消之前的全部选项并选择指定的那一项,而读取selectedIndex则只会返回选中项中第一项的索引值。
另外一种选择选项的方式,就是取得对某一项的引用,而后将其selected属性设置为true。例如,下面的代码会选中选择框中的第一项:
selectbox.options[0].selected = true;
复制代码
实际上,selected属性的做用主要是肯定用户选择了选择框中的哪一项。要取得全部选中的项,能够循环遍历选项集合,而后测试每一个选项的selected属性。
复制代码
使用DOM的方法:
var $newOption = document.createElement('option');
$newOption.appendChild(document.createTextNode('Option text'));
newOption.setAttribute(newOption);
复制代码
第二种方式是使用Option构造函数来建立选项,这个构造函数是DOM出现以前就有的。
第三种添加新选项的方式是使用选择框的add()方法。DOM规定这个方法接受两个参数:要添加的新选项和将位于新选项以后的选项。
与添加选项类型,移除选项的方式也有不少种。首先,可使用DOM的removeChild()方法,为其传入要移除的选项:
selectbox.removeChild(selectbox.options[0]); //移除第一个选项
复制代码
其次,可使用选择框的remove()方法。这个方法接受一个参数,即要移除选项的索引。
selectbox.remove(0)
复制代码
最后一种方式,就是将相应选项设置为null。这种方式也是DOM出现以前浏览器的遗留机制。
selectbox.options[0] = null; //移除第一个选项
复制代码
咱们知道,若是为appendChild()方法传入一个文档中已有的元素,那么就会先从该元素的父节点中移除它,再把它添加到指定的位置。
移动选项与移除选项有一个共同之处,即会重置每个选项的index属性。
重排选项次序的过程也十分相似,最好的方式仍然是使用DOM方法。要将选择框中的某一项移动到特定位置,最合适的DOM方法就是insertBefore();appendChild()方法只适用于将选项添加到选择框的最后。
var $lastOption = $selectDom.options[$selectDom.options.length - 1];
$selectDom.insertBefore($lastOption, $selectDom.options[0]);
复制代码
随着Ajax的出现,表单序列化已经成为一种常见需求。在JavaScript中,能够利用表单字段的type属性,连同name和value属性一块儿实现对表单的序列化。
在编写代码以前,有必须先搞清楚在表单提交期间,浏览器是怎样将数据发送给服务器的:
这一技术的本质,就是在页面中嵌入一个包含空HTML页面的iframe。经过设置designMode属性,这个空白的HTML页面能够被编辑,而编辑对象则是该页面<body>
元素的HTML代码。designMode属性有两个可能的值:“off”和“on”。在设置为“on”时,整个文档都会变得能够编辑,而后就能够像使用字处理软件同样。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>WYSIWYG</title>
</head>
<body>
<iframe name='richedit' src="blank.htm" frameborder="1" style='width:500px;height:500px;'></iframe>
<script>
window.onload = function () {
window.frames['richedit'].document.designMode = 'on';
}
</script>
</body>
</html>
复制代码
要让iframe内部能够编辑,必需要将designMode设置为“on”,但只有在页面彻底加载以后才能设置这个属性。所以,在包含页面中,须要使用onload事件处理程序来在恰当的时刻设置designMode。
等到以上代码执行以后,你就会在页面中看到一个相似文本框的可编辑区字段。这个区字段具备与其余网页相同的默认样式;不过,经过为空白页面应用CSS样式,能够修改可编辑区字段的外观。
另外一种编辑富文本内容的方式是使用名为contentieditable的特殊属性,这个属性也是由IE最先实现的。
Tips: difference between boolean attribute and enumerated attribute.
contenteditable属性有三个可能的值:“true”表示打开、“false”表示关闭,“inherit”表示从副元素那里继承。
与富文本编辑器交互的主要方式,就是使用document.execCommand()。
在富文本编辑器中,使用框架(iframe)的getSelection()方法,能够肯定实际选择的文本。这个方法是window对象和document对象的属性,调用它会返回一个表示当前文本的Selection对象。每一个Selection对象都有下列属性。
Selection对象的这些属性并无包含多少有用的信息。好在,该对象的下列方法提供了更多信息,而且支持对选区的操做。
Selection对象的这些方法都极为实用,它们利用了DOM范围来管理选区。因为能够直接操做选择文本的DOM表现,所以访问DOM范围与实用execCommand()相比,可以对富文本编辑器进行更加细化的控制。
因为富文本编辑是使用iframe而非表单控件实现的,所以从技术上说,富文本编辑并不属于表单。因此提交编辑器内容的方法是:添加一个隐藏的表单字段,让它的值等于从iframe中提取出的HTML。
虽然HTML和Web应用自诞生以来已经发生了天翻地覆的变化,但Web表单相对却没有什么改变。使用Javascript能够加强已有的表单字段,从而创造新的功能,或者提高表单的易用性。