JS笔记:第13、14章 事件和表单脚本

13 事件

JavaScriptHTML之间的交互是通过事件实现的。


事件流:

事件流描述的是从页面中接收事件的顺序。但有意思的是IENetscape开发团队居然提出了差不多完全相反的事件流的概念。IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流。

1)事件冒泡

IE的事件流叫事件冒泡,即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。

2)事件捕获

Netscape团队提出的另一种事件流叫做事件捕获。事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点最后接收到事件。

3DOM事件流

DOM2级事件“规定的事件流包括了三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

扫描二维码关注公众号,回复: 1717233 查看本文章


事件处理程序:

事件就是用户或浏览器自身执行的某个动作。诸如clickloadmouseover,都是事件的名字。而响应某个事件的函数就叫做事件处理程序(或事件侦听器)。为事件指定处理程序的方式有好几种。

1HTML事件处理程序

某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML特性来指定。

事件处理程序函数中有一个局部变量event,也就是事件对象。

2DOM0级事件处理程序

通过JavaScript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。这样有两个优势,一个是简单,一个是具有跨浏览器的优势。要使用JavaScript指定事件处理程序,首先必须取得一个要操作对象的引用。

每个元素(包括windowdocument)都有自己的事件处理程序属性,这些属性通常全部小写,例如onclick

Var btn = document.getElementById(“mybtn”);

btn.onclick = function(){};

使用DOM0级方法指定的事件处理程序被认为是元素的方法。换句话说,程序中的this引用当前元素。会在事件流的冒泡阶段被处理。

3DOM2级事件处理程序

DOM2级事件“定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有DOM节点都包含这两个方法,都接收3个参数:要处理的事件名、事件处理程序函数、一个布尔值。最后这个布尔值如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

Var btn = document.getElementById(“mybtn”);

btn.addEventListener(“click”,function(){},false);

通过addEventListener添加的事件处理程序只能使用removeEventListener()来移除,移除时得传入相同的参数,这意味着添加的匿名函数将无法被移除。

4IE事件处理程序

IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。

Var btn = document.getElementById(“mybtn”);

btn.attachEvent(“onclick”,function(){});

IE中使用attachEvent()与使用DOM0级方法的主要区别在于事件处理程序的作用域。使用attachEvent()方法的作用域为全局。

5)跨浏览器的事件处理程序

使用能力检测来进行判断使用哪种处理程序;


事件对象:

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。

1DOM中的事件对象

event.type可以为clickmouseovermouseout等;

要阻止特定事件的默认行为,可以使用preventDefault()方法。例如,链接的默认行为就是在被单击时会导航到其href特性指定的URL。如果你想阻止链接导航这一默认行为,那么通过链接的onclick事件处理程序可以取消它。

link.onclick = function(event){event.preventDefault();};

只有cancelable属性值设置为true的事件,才可以使用preventDefault()来取消其默认行为。

另外,stopPropagation()方法用于立即停止事件在DOM层次中的传播,即取消进一步的事件捕获或冒泡。

2IE中的事件对象

与访问DOM中的event对象不同,要访问IE中的event对象有几种不同的方式,取决于指定事件处理程序的方法。

在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。

在使用attachEvent()添加时,event对象作为参数被传入事件处理程序函数中。

3)跨浏览器的事件对象


事件类型:

DOM3级事件规定了以下几类事件:

UI事件:当用户与页面上的元素交互时触发;

焦点事件:当元素获得或失去焦点时触发;

鼠标事件:当用户通过鼠标在页面上执行操作时触发;

滚轮事件:当使用鼠标滚轮(或类似设备)时触发;

文本事件:当在文档中输入文本时触发;

键盘事件:当用户通过键盘在页面上执行操作时触发;

合成事件:当为IME(输入法编辑器)输入字段时触发;

变动事件:当底层DOM结构发生变化时触发;

1UI事件

load事件:

JavaScript中最常用的一个事件就是load。当页面完全加载后(包括所有图像、JavaScript文件、CSS文件等外部资源),就会触发window上面的load事件。

可以在<body>元素上添加一个onload特性,来指定onload事件处理程序。

图像上面也可以触发load事件。

DOM出现之前,开发人员经常使用Image对象在客户端预先加载图像。可以像使用<img>元素一样使用Image对象,只不过无法将其添加到DOM树中。

unload事件:

load事件对应的是unload事件,这个事件在文档被完全卸载后触发。只要用户从一个页面切换到另一个页面就会发生unload事件。而利用这个事件最多的情况就是清楚引用,以避免内存泄漏。

resize事件:

当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件。这个事件在window上面触发,因此可以通过JavaScript或者<body>元素中的onresize特性来指定事件处理程序。

scroll事件:

在混杂模式下,可以通过<body>元素的scrollLeftscrollTop来监控这一变化,而标准模式下,除safari之外的所有浏览器都会通过<html>元素来反映这一变化。

2)焦点事件

Blur:在元素失去焦点时触发,不冒泡。(还有DOMFocusOutfocusout,但冒泡)

Focus:在元素获得焦点时触发,不冒泡。(还有DOMFocusInfocusin,但冒泡)

3)鼠标与滚轮事件

DOM3级事件中定义了9个鼠标事件:

click:在用户单击主鼠标按钮或者按下回车键时触发。

dblclick:在用户双击主鼠标按钮时触发。

Mousedown:在用户按下了任意鼠标按钮时触发。

Mouseenter:在鼠标光标从元素外部首次移动到元素范围内时触发,不冒泡。

mouseleave:在位于元素上方的鼠标光标移动到元素范围之外时触发,不冒泡。

Mousemove:当鼠标指针在元素内部移动时重复地触发。

Mouseout:在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发。

mouseover:在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发。

mouseup:在用户释放鼠标按钮时触发。

1.客户区坐标位置:

鼠标事件都是在浏览器视口中的特定位置上发生的。这个位置信息保存在事件对象的clientXclientY属性中。注意这个值不包括页面滚动的距离。

2.页面坐标位置:

页面坐标通过事件对象的pageXpageY属性,能告诉你事件是在页面中的什么位置发生的。IE8及更早版本不支持事件对象的页面坐标,可以通过客户区坐标和滚动信息计算出来。

3.屏幕坐标位置:

鼠标事件发生时,不仅会有相对于浏览器窗口的位置,还有一个相对于整个电脑屏幕的位置。而通过screenXscreenY属性就可以确定鼠标事件发生时鼠标指针相对于整个屏幕的坐标信息。

4.修改健:

虽然鼠标事件主要是使用鼠标触发的,但是键盘有些键也会影响鼠标的行为。这些键就是ShiftCtrlAltMetawindows键)。DOM为此规定了4个属性,表示这些键的状态:shiftKeyctrlKeyaltKeymetaKey,这些属性都是布尔值,按下时为true,否则为false

5.相关元素:

DOM通过event对象的relatedTarget属性提供了相关元素的值,这个属性只对于mouseovermouseout事件才包含值,对于其他事件都是null

6.鼠标按钮:

对于mousedownmouseup事件来说,在其event对象存在一个button属性,表示按下和释放的按钮。DOMbutton属性可能有以下3个值:0表示主鼠标按钮,1表示中间的鼠标按钮,2表示次鼠标按钮。

7.更多事件信息:

DOM2级事件“规范在event对象中还提供了detail属性,对于鼠标来说,detail包含了一个数值,表示在给定位置上发生了多少次单击。

IE也通过下列属性为鼠标事件提供了更多信息:

offsetX:光标相对于目标元素边界的x坐标。

offsetY:光标相对于目标元素边界的y坐标。

8.鼠标滚轮事件

IE6.0首先实现了mousewheel事件,在垂直方向上(无论向上还是向下),就是触发mousewheel事件。这个事件可以在任何元素上触发,最终会冒泡到documentwindow对象。

mousewheel事件对应的event对象还有一个wheelDelta属性,当用户向前滚动时,wheelDelta120的倍数,当用户向后滚动时,wheelDelta-120的倍数。

Firefox支持一个名为DOMMouseScroll的类似事件,也是在鼠标滚轮滚动时触发。

9.触摸设备

两个手指放在屏幕上且页面随手指移动而滚动时会触发mousewheelscroll事件。

10.无障碍性问题

4)键盘和文本事件

用户在使用键盘时会触发键盘事件,有3个键盘事件,简述如下:

keydown:当用户按下键盘上的任意键时触发,而且如果按住不放的话,会重复触发此事件。

Keypress:当用户按下键盘上的字符键时触发,而且如果按住不放的话,会重复触发此事件,按下esc键也会触发此事件。

Keyup:当用户释放键盘上的键时触发。

虽然所有元素都支持以上3个事件,但只有在用户通过文本框输入文本时才最常用到。

当用户按了一下键盘上的字符键时,首先会触发keydown事件,然后紧跟着是keypress事件,最后触发keyup事件。

1.键码

在发生keydownkeyup事件时,event对象的keyCode属性中会包含一个代码,与键盘上一个特定的键对应。

2.字符编码

发生keypress事件意味着按下的键会影响到屏幕中文本的显示。这个事件的event对象包含一个charCode属性,这个值是按下的那个键所代表的字符的ASCII编码。在取得了字符编码之后,就可以使用String.fromCharCode()将其转换成实际的字符。

3.textInput事件

只有一个文本事件:textInput。在文本插入文本框之前会触发textInput事件。

这个与keypress有两点不同,区别之一是任何可以获得焦点的元素都可以触发keypress事件,但只有可编辑区域才能触发textInput事件;区别之二是textInput事件只会在用户按下能够输入实际字符的键时才会被触发,而keypress事件则在按下那些能够影响文本显示的键也会触发(例如退格键)。

该事件对象event中有一个data属性,这个属性的值就是用户输入的字符(而非字符编码)。

5)复合事件

复合事件是DOM3级事件中新添加的一类事件,用于处理IME的输入序列。IME(输入法编辑器)可以让用户输入在物理键盘上找不到的字符。

6)变动事件

DOM2级的变动事件能在DOM中的某一部分发生变化时给出提示。

1.删除节点

在使用removeChild()或replaceChild()从DOM中删除节点时,首先会触发DOMNodeRemoved事件。

2.插入节点

在使用appendChild()、replaceChild()或insertBefore()向DOM中插入节点时,首先会触发DOMNodeInserted事件。

7HTML5事件

1.contextmenu事件

表示何时应该显示上下文菜单,以便开发人员取消默认的上下文菜单而提供自定义的菜单。

2.beforeunload事件

之所以有发生在window对象上的beforeunload事件,是为了让开发人员有可能在页面卸载之前阻止这一操作。

3.DOMContentLoaded事件

如前所述,windowload事件会在页面中的一切都加载完毕时触发,但这个过程可能会因为要加载的外部资源过多而颇费周折。而DOMContentLoaded事件则在形成完整的DOM树之后就会触发,不理会图像、JavaScript文件、CSS文件或其他资源是否已经下载完毕。

通常这个事件既可以添加事件处理程序,也可以执行其他DOM操作。这个事件始终都会在load事件之前触发。

4.readystatechange事件

IEDOM文档中的某些部分提供了readystatechange事件,这个事件的目的是提供与文档或元素加载状态有关的信息。支持这个事件的每个对象都有一个readyState属性,可能包含下列5个值中的一个。

uninitialized(未初始化)、loading(正在加载)、loaded(加载完毕)、interactive(交互)、complete(完成)。

另外,<script>(在IEOpera中)和<link>(仅IE中)元素也会触发readystatechange事件,可以用来确定外部的JavascriptCSS文件是否已经加载完成。

5.pageshowpagehide事件

pageshow事件在页面显示时触发,在load事件触发后触发。

pagehide事件在页面卸载时触发,在unload事件之前触发。

6.hashchange事件

HTML5新增了hashchange事件,以便在URL的参数列表(及URL中“#”号后面的所有字符串)发生变化时通知开发人员。

8)设备事件

1.orientationchange事件

苹果公司为移动safari添加了该事件,以便开发人员能够确定用户何时将设备由横向查看模式切换为纵向查看模式。

2.MozOrientation事件

3.deviceorientation事件

4.devicemotion事件

9)触摸与手势事件

1.触摸事件

触摸事件会在用户手指放在屏幕上面时、在屏幕上滑动时或从屏幕上移开时触发。

touchstart:当手指触摸屏幕时触发,即使已经有了一个手指放在屏幕上也会触发;

touchmove:当手指在屏幕上滑动时连续触发,在这个事件发生期间,调用preventDefault()可以阻止滚动;

touchend:当手指从屏幕上移开时触发;

touchcancel:当系统停止跟踪触摸时触发;

在触摸屏幕上的元素时,这些事件(包括鼠标事件)发生的顺序如下:touchstartmouseovermousemove(一次)、mousedownmouseupclicktouchend

2.手势事件

当两个手指触摸屏幕时就会产生手势,手势通常会改变显示项的大小,或者旋转显示项。有三个手势事件:

gesturestart:当一个手指已经按在屏幕上而另一个手指又触摸屏幕时触发。

gesturechange:当触摸屏幕的任何一个手指的位置发生变化时触发。

gestureend:当任何一个手指从屏幕上移开时触发。

与触摸事件一样,每个手势事件的event对象都包含着标准的鼠标事件属性:bubbles\cancelable\view\clientX\clientY\screenX\screenY\detail\altKey\shiftKey\ctrlKey\metaKey

此外,还包含两个额外的属性:rotationscale。其中,rotation属性表示手指变化引起的旋转角度。而scale属性表示两个手指间距离的变化情况。


内存和性能:

Javascript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能。

1)事件委托

对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

使用事件委托,只需要在DOM树中尽量最高的层次上添加一个事件处理程序。

最适合采用事件委托技术的事件包括click\mousedown\mouseup\keydown\keyup\keypress

好处:

1.提高性能;

2.新添加的元素还会有之前的事件;

2)移除事件处理程序

内存中留有那些过时不用的“空事件处理程序”,也是造成web应用程序内存与性能问题的主要原因。

造成上述问题可能有两种情况:一种是从文档中移除带有事件处理程序的元素时,这可能是通过纯粹的DOM操作,例如使用removeChild()和replaceChild()方法,更多的是使用innerHTML替换页面中某一部分的时候。另一种情况就是卸载页面的时候,没有处理干净事件处理程序,那它们就会滞留在内存中,可以通过onunload事件来清除。


模拟事件:

1DOM中的事件模拟

可以在document对象上使用createEvent()方法创建event对象,传入一个参数,即表示要创建的事件类型的字符串。

模拟事件的最后一步就是触发事件,这一步需要使用dispatchEvent()方法,传入一个参数,即表示要触发事件的event对象。

2IE中的事件模拟


小结:

在使用事件时,需要考虑如下一些内存与性能方面的问题:

1)有必要限制一个页面中事件处理程序的数量,数量太多会导致占用大量的内存,而且也会让用户感觉页面反应不够灵敏。

2)建立在事件冒泡机制之上的事件委托技术,可以有效地减少事件处理程序的数量。

3)建议在浏览器卸载页面之前移除页面中的所有事件处理程序。



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.共有的表单字段属性

disabledformnamereadonlytabIndextypevalue

2.共有的表单字段方法

每个表单字段都有两个方法:focus()和blur()。

3.共有的表单字段事件

所有表单字段都支持下列3个事件:blurchangefocus


文本框脚本:

HTML中,有两种方式来表现文本框:一种是使用<input>元素的单行文本框,另一种是使用<textarea>的多行文本框。

1)选择文本

上述两种文本框都支持select()方法,这个方法用于选择文本框中的所有文本。

1.选择select事件

select()方法对应的,是一个select事件,在选择了文本框中的文本时,就会触发select事件。

2.取得选择的文本

HTML5通过一些扩展方案取得选择的文本,添加了两个属性:selectionStartselectionEnd

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)移动和重排选项

使用DOMappendChild()和insertBefore()方法。


表单序列化:


富文本编辑:

富文本编辑,又称为所见即所得。这一技术的本质,就是在页面中嵌入一个包含空HTML页面的iframe

1)使用contenteditable属性

可以把这个属性应用给页面中的任何元素,然后用户立即就可以编辑该元素。

2)操作富文本

与富文本编辑器交互的主要方式,就是使用document.execCommand()。这个方法可以对文档执行预定义的命令,接收3个参数:要执行的命令名称、表示浏览器是否应该为当前命令提供用户界面的一个布尔值和执行命令必须的一个值。

3)富文本选区

在富文本编辑器中,使用框架(iframe)的getSelection()方法,可以确定实际选择的文本。

4)表单与富文本

由于富文本编辑是使用iframe而非表单控件实现的,因此从技术上说,富文本编辑器并不属于表单。为此,通常可以添加一个隐藏的表单字段,让它的值等于从iframe中提取的HTML。具体来说,就是在提交表单之前,从iframe中提取出HTML,并将其插入到隐藏的字段中。

frames[‘id’].document.body.innerHTML可以取得富文本内容。


猜你喜欢

转载自blog.csdn.net/u012755393/article/details/79979034