第14章 表单脚本
表单的基础知识:
在HTML中,表单是由<form>元素来表示的,而在JavaScript中,表单对应的则是HTMLFormElement类型。
通过document.forms可以取得页面中的所有表单。
(1)提交表单
用户可以单击提交按钮或图像按钮来提交表单,浏览器会在将请求发送给服务器之前触发submit事件。
(2)重置表单
与提交表单一样,既可以通过html元素来重置,也可以通过javaScript来重置表单。
Form.reset();
与调用submit()方法不同,调用reset()方法会像单击重置按钮一样触发reset事件。
(3)表单字段
每个表单都有elements属性,该属性是表单中所有表单元素(字段)的集合。这个elements集合是一个有序列表,其中包含着表单中的所有字段,例如<input>、<textarea>、<button>和<fieldset>。
1.共有的表单字段属性
disabled、form、name、readonly、tabIndex、type、value。
2.共有的表单字段方法
每个表单字段都有两个方法:focus()和blur()。
3.共有的表单字段事件
所有表单字段都支持下列3个事件:blur、change、focus。
文本框脚本:
在HTML中,有两种方式来表现文本框:一种是使用<input>元素的单行文本框,另一种是使用<textarea>的多行文本框。
(1)选择文本
上述两种文本框都支持select()方法,这个方法用于选择文本框中的所有文本。
1.选择select事件
与select()方法对应的,是一个select事件,在选择了文本框中的文本时,就会触发select事件。
2.取得选择的文本
HTML5通过一些扩展方案取得选择的文本,添加了两个属性:selectionStart和selectionEnd。
textBox.value.substring(textbox.selectionStart, textbox.selectionEnd);
3.选择部分文本
HTML5也为选择文本框中的部分文本提供了解决方案,即最早由Firefox引入的setSelectionRange()方法。接收两个参数:要选择的第一个字符的索引和要选择的最后一个字符之后的字符的索引,类似于substring()方法的两个参数。
(2)过滤输入
综合运用事件和DOM手段,就可以将普通的文本框转换成能够理解用户输入数据的功能型控件。
1.屏蔽字符
因为响应向文本框中插入字符操作的是keypress事件,因此,可以通过阻止这个事件的默认行为来屏蔽此类字符。
2.操作剪贴板
HTML5把剪贴板事件纳入了规范,下列就是6个剪贴板事件:
beforecopy:在发生复制操作前触发。
Copy:在发生复制操作时触发。
Beforecut:在发生剪切操作前触发。
Cut:在发生剪切操作时触发。
Beforepaste:在发生粘贴操作前触发。
Paste:在发生粘贴操作时触发。
要访问剪贴板中的数据,可以使用clipboardData对象:在IE中,这个对象是window对象的属性;而在其他浏览器中,这个对象是event对象的属性。
3.自动切换焦点
通过监听keyup事件完成。
4.HTML5约束验证API
必填字段:required属性,这个属性适用于<input>、<textarea>和<select>字段。
HTML5为<input>元素的type属性又增加了几个值,这些新的类型不仅能反映数据类型的信息,而且还能提供一些默认的验证功能。其中,“email“和“url”是两个得到支持最多的类型。
检测有效性:使用checkValidity()方法可以检测表单中的某个字段是否有效。
禁用验证:通过设置novalidate属性,可以告诉表单不进行验证。
选择框脚本:
选择框是通过<select>和<option>元素创建的。为了方便与这个控件交互,除了所有表单字段共有的属性和方法外,HTMLSelectElement类型还提供了下列属性和方法。
Add:向控件中插入新<option>元素;
multiple:布尔值,表示是否允许多项选择;
Options:控件中的所有<option>元素;
remove(index):移除给定位置的选项;
selectedIndex:基于0的选中项的索引;
Size:选择框中可见的行数。
注意一点:选择框的change事件与其他表单字段的change事件触发的条件不一样,其他表单字段的change事件是在值被修改且焦点离开当前字段时触发,而选择框的change事件只要选中了选项就会触发。
(1)选择选项
判断选项selected属性的值
(2)添加选项
可以使用Javascript动态创建选项,并将它们添加到选择框中。第一种方式就是使用DOM操作;第二种方式是使用Option构造函数,接收两个参数,文本(text)和值(value)。第三种新添加选项的方式是使用选择框的add()方法。
(3)移除选项
(4)移动和重排选项
使用DOM的appendChild()和insertBefore()方法。
表单序列化:
富文本编辑:
富文本编辑,又称为所见即所得。这一技术的本质,就是在页面中嵌入一个包含空HTML页面的iframe。
(1)使用contenteditable属性
可以把这个属性应用给页面中的任何元素,然后用户立即就可以编辑该元素。
(2)操作富文本
与富文本编辑器交互的主要方式,就是使用document.execCommand()。这个方法可以对文档执行预定义的命令,接收3个参数:要执行的命令名称、表示浏览器是否应该为当前命令提供用户界面的一个布尔值和执行命令必须的一个值。
(3)富文本选区
在富文本编辑器中,使用框架(iframe)的getSelection()方法,可以确定实际选择的文本。
(4)表单与富文本
由于富文本编辑是使用iframe而非表单控件实现的,因此从技术上说,富文本编辑器并不属于表单。为此,通常可以添加一个隐藏的表单字段,让它的值等于从iframe中提取的HTML。具体来说,就是在提交表单之前,从iframe中提取出HTML,并将其插入到隐藏的字段中。
frames[‘id’].document.body.innerHTML可以取得富文本内容。
背景:与浏览器环境中的其他组件类似,<canvas>由几组API组成,但并非所有浏览器都支持所有这些API。除了几倍基本绘图能力的2D上下文,<canvas>还建议了一个名为WebGL的3D上下文。目前,所有支持该元素的浏览器都支持2D上下文及文本API。因此我们这篇文章就只讲2D上下文。
兼容性:IE9+以及主流浏览器
1.基本用法
要使用<canvas>元素,必须先设置其width和height属性,指定可以绘图的区域大小(也能通过CSS属性添加样式)。出现在开始和结束标签的内容是必备信息,如果浏览器不支持<canvas>元素,就会显示这些信息,类似于<img>中的alt属性。
<canvas id="drawing" width="200" height="100">Your browser doesn't support canvas tag</canvas>
要在这块画布canvas绘图,需要取得绘图上下文。传入"2d",就可以取得2D上下文
-
var drawing = document.getElementById("drawing");
-
if(drawing.getContext){
-
var context = drawing.getContext("2d");
-
....
-
}
使用toDataURL()方法,可以导出在<canvas>元素上绘制的元素。这个方法接受一个参数,即图像耳MIME类似格式("image/png"),而且适合于创建图像的任何上下文,
-
var drawing = document.getElementById("drawing");
-
if(drawing.getContext){
-
//取得图像的数据URL
-
var imgURL = drawing.toDataURL("image/png");
-
//显示图像
-
var image = document.createElement("img");
-
image.src=imgURL; //imgURL:data:image/png;base64,
-
document.body.appendChild(img);
-
}
默认情况下,浏览器会将图像编码为PNG格式,除非另行指定。例如"image/jpeg";
如果绘制到画布上的图像源自不同的域,toDataURL()方法会抛出错误
2.2D上下文
①2D上下文的两种基本绘图操作时填充和描边。填充,就是用指定的样式(颜色、渐变或图像)填充图形;描边,就是只在图形的边缘划线。操作的结果取决于两个属性:fillStyle和StrokeStyle。这个属性的值可以是字符串、渐变对象或模式对象,而且他们的默认值都是“#000000”;字符串可以是颜色值的任何格式,包括颜色明、十六进制码、rgb、rgba、hsl或hsla
-
context.strokeStyle = "red";
-
context.fillStyle = "#0000ff"
②绘制矩形
与矩形有关的方法包括fillRect()、strokeRect和clearRect()。这三个方法都能接收4个参数:矩形的x坐标、矩形的y坐标、矩形的宽度和矩形高度。这些参数的单位都是像素
-
//绘制红色矩形
-
context.fillStyle = "#ff0000";
-
conetxt.fillRect(10, 10, 50, 50);
-
//绘制半透明的蓝色矩形
-
context.fillStyle = "rgba(0, 0, 255, 0.5)";
-
context.fillRect(30, 30, 50, 50);
描边线条的宽度:lineWidth,该属性的值可以是任意整数
线条末端的形状:lineCap,这属性的值方头"butt"、源头"round"、方头"square"
线条相交的方式:lineJoin,这属性的值"round"圆交、"bevel"斜交、“miter”斜接
clearRect()方法用于清除画布上的矩形区域(经典例子:刮刮乐)
③绘制路径
首先:beginPath()方法,表示要开始绘制新路径
然后:调用下列方法来实际绘制路径
rect(x, y, width, height):从点(x,y)开始绘制一个矩形路径,宽度和高度分别由width和height决定
arc(x, y, radius, startAngle, endAngle, counterClockwIse):以(x,y)为圆心,半径为radius,startAngle和endAngle分别为起始和结束角度。最后一个参数表示startAngle和endAngle是否 按逆时针计算,值为false表示按顺时针计算,绘制成一条弧线
arcTo(x1, y1, x2, y2, radius):从上一点开始绘制一条弧线,到(x2, y2)为止,兵器以给定的半径radius穿过(x1, y1).
lineTo(x, y):从上一点开始绘制一条直线,到(x, y)为止
moveTo(x, y):将绘图游标移动到(x, y),就不是从上一点了
接下来: 调用closePath()绘制一条连接到路径起点的线条
调用fill()方法或者stroke()对路径进行填充或者描边,这取决于画笔用的是fillStyle还是strokeStyle。
最后:调用clip(),可以在路径上创建一个剪切区域
-
//开始路径
-
context.beginPath();
-
//绘制外圆,角度转弧度 PI /180 * 角度
-
context.arc(100, 100, 99, 0, 2 * Math.PI, false);
-
//绘制内圆,这里必须要先使用moveTo,因为画笔默认是从上一点开始画的,不使用会绘制出多余的线条
-
context.moveTo(194, 100);
-
context.arc(100, 100, 94 , 0, 2* Math.PI, false);
④绘制文本
绘制文本主要由两个方法:fillText() 和 strokeText(),使用fillText()更好,因为文字实心更好看,模拟了在网页中正常显示文本
两个方法都可以接收4个参数:要绘制的文本字符串、x坐标、y坐标和可选的最大像素宽度
这两个方法都以下列3个属性为基础,都是上下文的属性
font:表示文本样式、大小及字体,用CSS中指定字体的格式来写,例如"bold 14px Arial"
textAlign:表示文本对齐方式。可能的值有"start"、"end"、"left"、"right"、"center"。建议使用"start"和"end"而不是"left"和"right"
textBaseLine:表示文本的基线,可能的值有"top"、"hanging"、"middle"、“alphabetic”字母的、"ideographic"表意的和"bottom"
-
context.font = "bold 14px Arial";
-
context.textAlign = "center";
-
contetx.textBaseLine = "middle";
-
context.fillText("12", 100, 20);
这里把textAlign设置为"center",把textBaseLine设置为"middle",所以坐标(100, 20)表示的是文本水平和垂直重点的坐标。
当textBaseLine值为"hanging"、"ideographic"、"alphabetic"时分别指向字体的特定基线坐标
由于绘制文本比较复杂,特定是需要把文本控制在某一区域中的时候,2D上下文提供了辅助确定文本大小的方法measureText()。这个方法接受一个参数,即要绘制的文本。返回一个TextMetrics对象,目前只有一个width属性。例如,你想再一个140px款的矩形区域上绘制hello word!可以从100px的字体大小开始递减,最终找到合适的字体大小
⑤变换
通过上下文的变换,可以把处理后的图像绘制到画布上。
rotate(angle):围绕原点旋转图像angle弧度
scale(scaleX, scaleY):缩放图像
translate(x, y):将坐标原点移动到(x, y)。执行后,坐标(0, 0)会变成之前由(x, y)表示的点
transform(m1_1, m1_2, m2_1, m2_2, dx, dy): 直接修改变换矩阵
如果你知道将来还要返回某组属性与变换的组合,可以对上下文对象调用save()方法。调用这个方法后,当时的所有设置都会进入一个栈结构,得以妥善保管。然会对上下文进行其他修改。等想要回到之前保存的设置时,可以调用restore()方法,在保存设置的栈结构中向前返回一级,恢复之前的状态。其实我觉得重新设置也不麻烦。save()方法保存的只是对绘图上下文的设置与包换,不会保存绘图上下文的内容
⑥绘制图像
对上下文对象使用drawImage()方法。可以使用三种不同参数组合。
1.传入一个HTML<img>元素,以及绘制该图像的起点的x和y坐标。
2.如果你想要改变绘制后图像的大小,可以再多传入两个参数,分别表示目标宽度和目标高度。通过这种方法来缩放图像并不影响上下文的变换矩阵。
3.再复杂一点,可以选择把图像的某个区域绘制到上下文。这种调用方法需要传入9个参数:要绘制的图像、源图像的x坐标、源图像的y坐标、源图像的宽度、源图像的高度、目标图像的x坐标、目标图像的y坐标、目标图像的宽度、目标图像的高度。
除了给drawImage()方法传入<img>元素外,还可以传入另一个<canvas>元素作为第一个参数。这样,就可以把另一个画布内容绘制到当前画布上。
⑦阴影
2D上下文会根据以下几个属性的值,自动为形状或路径绘制出阴影
shadowColor、shadowOffsetX、shadowOffsetY、shadowBlur
⑧渐变
对上下文使用createLinearGradient()方法创建线性渐变对象。该方法接收4个参数:起点的x坐标、起点的y坐标、终点的x坐标、重点的y坐标
创建线性渐变对象后,下一部就是使用addColorStop()来指定色标。这个方法接收两个参数:色标位置和CSS颜色值。色标位置是一个0到1之间的数字。
-
var gradient = context.createLinearGradient(30, 30, 70, 70);
-
gradient.addColorStop(0, "white");
-
gradient.addColorStop(1, "black");
-
//绘制渐变矩形
-
context.fillStyle = gradient;
-
context.fillRect(30, 30, 50, 50)
如果没把渐变坐标和绘制矩形匹配的话,就会只显示一部分渐变
创建放射渐变,可以使用createRadialGradient()方法。该方法接收6个参数,对应着两个圆的圆心和半径。因为创建比较麻烦,所以径向渐变并不是那么容易控制。不过一般来说,让起点圆和重点圆保持为同心圆的情况比较多。
⑨模式
模式其实就是重复的图像,可以用来填充或描边图形。调用上下文对象的createPattern()方法并传入两个参数:一个HTML<img>元素和一个表示如何重复图像的字符串。其中,第二个参数的值与CSS的background-repeat属性值相同,包括"repeat"、"repeat-x"、"repeat-y"和"no-repeat";
-
var image = document.images[0],
-
pattern = context.createPattern(image,"repeat");
-
//绘制矩形
-
context.fillStyle = pattern;
-
context.fillRect(10, 10, 150, 150);
需要注意的是,模式与渐变一样,都是从画布的原点(0,, 0)开始的。
10.合成
2D上下文对象还有两个属性,可以应道到2D上下文中所有绘制操作的属性:globalAlpha和globalComposition-Operation
其中globalAlpha是一个介于0到1之间的值,包括0和1,用于指定所有绘制的透明度。默认为0
第二个属性globalCompositionOperation表示后绘制的图形怎样与先绘制的图形结合,可能的值很多,只列几个,详情,戳globalCompositionOperation
source-over(默认值):后绘制的图形位于绘制的图形上方