JavaScript高级编程笔记(4)

事件

http://www.w3school.com.cn/jsref/dom_obj_event.asp

JavaScript与HTML之间的交互式通过事件实现的。可以用侦听器(处理程序)来预定事件,在传统软件工程中被称为观察者模式的模型,支持页面的行为和页面的外观之间的松散耦合。
IE事件流是事件冒泡流,而Netscape事件流是事件捕获流。(放心使用事件冒泡)

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

JavaScript高级编程笔记(4)_第1张图片
DOM事件流.jpg
事件处理程序

函数体内有局部变量event,可以直接访问事件对象。不需要定义


在函数内部,this值等于事件的目标元素.


在HTML中指定事件处理程序有两个缺点

  • 时差问题,HTML元素一出现就触发相应的事件,而当时的事件处理程序有可能未具备执行条件。
  • 扩展事件处理程序的作用域链在不同浏览器会导致不同的结果。可能会在访问非限定对象时出错。
  • 导致HTML与JavaScript代码紧密耦合。(更换事件处理程序要改动两个地方)

DOM0级事件处理程序:

element.event = function(){}

DOM2级事件处理程序:

  • addEventListener(event_name,handler,false)
    IE: attachEvent(event_name,handler)
  • removeEventListener(event_name,handler,false) //传入的handler决定了删除哪一个handler绑定的事件
    IE: detachEvent(event_name,handler)

在IE使用attachEvent()作用于在全局作用域。this = window; 执行时按添加的相反顺序执行。

属性/方法 类型 读/写 说明
bubbles Boolean 只读 表明事件是否冒泡
stopPropagation() Function 只读 取消事件的进一步捕获或冒泡。如果bubbles为true,则可以使用这个方法
stopImmediatePropagation() Function 只读 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3级事件中新增)
cancelable Boolean 只读 表明是否可以取消事件的默认行为
preventDefault() Function 只读 取消事件的默认行为。如果cancelable是true,则可以使用这个方法
defaultPrevented Boolean 只读 为true表示已经调用了preventDefault()(DOM3级事件中新增)
currentTarget Element 只读 其事件处理程序当前正在处理事件的那个元素(currentTarget始终===this,即处理事件的元素)
target Element 只读 直接事件目标,真正触发事件的目标
detail Integer 只读 与事件相关的细节信息
eventPhase Integer 只读 调用事件处理程序的阶段:1表示捕获阶段,2表示处于目标阶段,3表示冒泡阶段
trusted Boolean 只读 为true表示事件是由浏览器生成的。为false表示事件是由开发人员通过JavaScript创建的(DOM3级事件中新增)
type String 只读 被触发的事件的类型
view AbstractView 只读 与事件关联的抽象视图。等同于发生事件的window对象

在事件处理程序内部,对象this始终等于 currentTarget 的值。target 只包含事件的实际目标。看下面例子

document.body.onclick = function(event){
  alert(event.currentTarget === document.body); //true
  alert(this === document.body);  //true
  alert(event.tagget === document.getElementById("myBtn");  //true
}

点击按钮时 thiscurrentTarget 等于 document.body ,但 target 却等于按钮元素(事件的真正目标).

  • 在需要通过一个函数处理多个事件时可以使用type属性.(event.type 返回事件对象类型)
  • 阻止特定事件的默认行为,可以使用preventDefault()方法.(当cancelable == true)
  • stopPropagation()方法用于立即停止事件在DOM层次的传播(取消冒泡或者捕获)

IE中的事件对象

  • 使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。
var btn = document.getElement("myBtn");

btn.onclick = function(){
    var event = window.event;
    alert(event.type);  //click
}

btn.attachEvent("onclick",  function(event){
      alert(event.type);
});
属相和方法 类型 读写 说明
cancelBubble Boolean 读/写 默认值为fasle,设置为true,就可以取消事件冒泡 与 DOM 中的 stopPropagation()方法的作用相同
returnValue Boolean 读/写 默认为 true, 设置为fasle。 就可以取消事件的默认行为
srcElement Element 只读 事件的目标(与DOM中的target属性相同)
type String 只读 被触发事件的类型
  • 事件处理程序的作用域是根据指定它的方式确定的,所以不能认为this会始终等于事件目标。故而,最好还是使用event.srcElement比较保险.
  • returnValue属性相当于DOM中的preventDefault()方法.它们的作用都是取消给定事件的默认行为。只要将该属性设置为false就能组织默认行为。
  • cancelBubble属性与DOM中的stopPropagation()方法作用相同,用来停止事件冒泡的。IE只能取消事件冒泡。通过将cancelBubble设置为true,就可阻止事件通过冒泡而触发的处理程序。
    s

事件类型

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

  • UI
  • 焦点
  • 鼠标
  • 滚轮
  • 文本
  • 键盘
  • 合成(IME 输入法)
  • 变动(底层DOM结构发生变化触发)
  • 变动名称事件

UI事件

  • load : 当页面完全加载后在window上面触发,当所有框架都加载完毕时在框架集上面触发,当图像加载完毕时在元素上面触发。或者当嵌入的内容加载完毕时在元素上面触发。
  • unload:当页面完全卸载后在window上面触发,当所有框架都卸载后在框架集上面触发,或者当嵌入的内容卸载完毕后在元素上面触发。
  • abort:当用户停止下载过程嵌入内容没有加载完触发。
  • error : 当发生JavasScript错误时在window上面触发,当无法加载图片时在元素上面触发,当元素加载嵌入内容时在元素上面触发,或者当有一或多个框架无法加载时在框架集上面触发。
  • select : 当用户选择文本框( or )中的一个可多个字符时触发。
  • resize : 当窗口或框架的大小变化时在window或框架上面触发;
  • scroll:当用户流动带有流动条的元素中的内容时,在该元素上面触发。元素中包含所加载页面的流动条。

焦点事件

  • blur:失去焦点时触发,这个事件不会冒泡
  • focus:获得焦点时触发,不冒泡
  • focusin:在获得焦点时触发,但他冒泡,DOM3新增
  • focusout:在失去焦点时触发,冒泡

鼠标及滚轮事件

  • click:在单击主鼠标按钮(一般是左键)或者按下回车时触发;这意味着onclick事件处理程序既可以通过鼠标也可以通过键盘执行。
  • dbclick:双击主鼠标按钮(一般是左键)或者按下回车键时触发。
  • mousedown:按下任意鼠标按钮时触发;不能通过键盘触发。
  • mouseup:释放鼠标按钮时触发;不能通过键盘触发。
  • mouseenter:在鼠标光标从元素外部首次移动到元素范围之内时触发;这个事件不冒泡,而且光标移动到元素的后代元素上不会触发;IE、Firefox9+和Opera支持这个事件。
  • mouseleave:在鼠标光标从元素上方移动到元素范围之外时触发;这个事件不冒泡,而且光标移动到元素的后代元素上不会触发;IE、Firefox9+和Opera支持这个事件。
  • mousemove:在鼠标光标在元素内部移动时重复地触发;不能通过键盘触发。
  • mouseout:在鼠标位于一个元素上方,然后移动到另一个元素时触发,另一个元素可以是这个元素的子元素;不能通过键盘触发。
  • mouseover:在鼠标位于一个元素外部,然后将其首次移动到另一个元素边界之内时触发;不能通过键盘触发。
  • (客户区坐标)鼠标事件位置信息保存在事件对象中的clientXclientY属性中.
  • (页面坐标位置)事件对象pageXpageY属性表示鼠标光标在页面中的位置,坐标运算从页面本身而非是视口的左边和顶边计算的。
  • screenXscreenY 属性确定鼠标事件发生时鼠标指针相对于整个屏幕的坐标信息。(相对于电脑屏幕的位置)
  • 修改键状态属性(判断是否按下):shiftKeyctrlKeyaltKeymetaKey(在windows是windows键,在苹果机是cmd键);
  • 对于mousedownmouseup事件来说,在其event对象存在一个button属性。(0:主鼠标按钮,1:中间鼠标按钮,2:次鼠标按钮)
  • 鼠标滚轮事件:mousewheel,返回值中的wheelDelta正负代表滚轮的方向。(Opera 9.5以前的版本正负号是颠倒的)

键盘与文本事件

  • keydown
  • keypress
  • keyup
  • 只有一个文本事件:textInput,可以用于拦截文本。(在文本输入文本框之前会触发该事件)。
  • event 对象上还有一个属性:inputMethod,返回值是文本输入到文本框中的方式。

复合事件(用于处理IME输入序列)

  • compositionstart:要开始输入
  • compositionupdate:插入新字符
  • compositionend:复合系统关闭,返回正常键盘输入状态

event.data 属性:

  • compositionstart时访问data:正在编辑的文本;
  • compositionupdate时访问data:正插入的新字符;
  • compositionend时访问data:插入的所有字符;

变动事件(貌似作废了很多变动事件,跨浏览器不好,不建议用)

  • DOMNodeInserted:在一个节点作为子节点被插入到另一个节点中时;
  • DOMNodeRemoved:在节点从其父节点中被移除时;
    其中(event.target)是被删除的节点,由于触发时节点尚未从其父节点删除,因此其parentNode属性仍然指向父节点.(和event.relatedNode相同,包含对目标节点父节点的引用).
  • DOMNodeInsertedIntoDocument:在一个节点被直接插入文档,或通过子树间接插入文档之后触发。这个事件在DOMNodeInserted之后触发;
  • DOMNodeRemovedFromDocument:在一个节点被直接从文档中移除,或通过子树间接从文档中移除之前触发。这个事件在DOMNodeRemoved之后触发;
  • DOMSubtreeModified:在DOM结构中发生任何变化时触发;
  • DOMAttrModified:在特性被修改之后触发;
  • DOMCharacterDataModified:在文本节点的值发生变化时触发;

HTML5事件

  • contentmenu : 右键调出上下文菜单事件,在兼容DOM的浏览器中,可以使用event.preventDafault()阻止元素发生的默认行为。IE将event.returnValue值设为false;
  • beforeunload: 页面卸载前的事件。这个事件会在浏览器卸载页面之前触发。
EventUtil.addHandler(window, "beforeunload", function(event){
       event = EventUtil.getEvent(event);
       var message = "I'm GGG";
       event.returnValue = message;
      return message;
}
  • DOMContentLoaded 事件 (IE:readystatechange 事件)
    windowload 事件会在页面的一切都加载完毕时触发。而DOMContentLoaded事件则在形成完整的DOM树之后就会触发,不会理会图像、JavaScript文件、CSS文件或其他资源是否已经下载完毕。
  • pageshowpagehide 事件
    Firefox 和 Opera有个特性:往返缓存,如果页面位于bfcache中,那么再次打开该页面就不会触发load事件.
  • hashchange事件
    在URL的参数列表(以及URL中#号后面的所有字符串)发生变化时通知。
    此时event对象包含两个额外属性: oldURLnewURL

设备事件

  • orientationchange 事件(Safari)
    当设备改变纵向或横向时触发事件。
    事件的值可以通过window.orientation 的返回值判断。 (0:肖像模式,-90表示向右旋转的横向模式,90表示向左旋转的横向模式,180表示头朝下)
  • MozOrientation 事件
    Firefox 为检测设备的方向引入了一个名为MozOrientation的新事件(非标准)该事件只能提供一个平面的方向变化。
    事件内event对象包含三个属性:x、y、z,值都介于1到-1之间,表示不同设备坐标轴上的方向。
    x为向左倾斜的值,向右会减少。y为向接近用户的方向倾斜的值,z检测垂直加速度,1表示静止不动,0为失重。
  • deviceorientation 事件
    和MozOrientation 类似.但意图是告诉开发人员设备在空间中朝向哪儿。
    事件对象包含以下五个属性:
    • alpha : 在围绕z轴旋转(左右),y轴的度数差;是一个介于0到360之间的浮点数。
    • beta : 在围绕x轴旋转(前后),z轴的度数差;是一个介于-180到180之间的浮点数。
    • gamma : 在围绕y轴旋转(扭转),z轴的度数差;是一个介于-90到90之间的浮点数。
    • absolute : 布尔值,表示设备是否返回一个绝对值。
    • compassCalibrated : 布尔值,表示设备的指南针是否校准过。
JavaScript高级编程笔记(4)_第2张图片
方向图.jpg
  • devicemotion 事件
    这个事件告诉开发人员设备什么时候移动,检测设备是不是往下掉或者被走着的人拿在手里
    • acceleration : 一个包含x,y,z属性的对象,不考虑重力的情况下告诉你在每个方向上的加速度。
    • accelerationIncludingGravity : 一个包含x,y,z属性的对象,在考虑z轴自然重力加速度的情况下告诉你每个方向上的加速度。
    • interval : 以毫秒表示的时间值,必须在另一个devicemotion事件触发前传入。
    • rotationRate : 一个包含表示方向的alpha、beta和gamma属性的对象
      如果读取不了他们值就会返回null,所以使用属性先检测他们的值不是null.

触摸和手势事件

触碰事件

  • touchstart : 当手指触摸屏幕时出发。即使已经有一个手指放在了屏幕上也会触发。
  • touchmove : 当手指在屏幕上滑动时连续触发。在事件期间可以调用preventDefault()来阻止滚动。
  • touchend : 当手指从屏幕上移开时触发。
  • touchcancel : 当系统停止跟踪触摸时触发。
    触摸事件不仅提供了鼠标事件常见的属性,还包含下列三个用于跟踪触摸的属性
    • touches : 表示当前跟踪触摸操作的Touch对象数组.
    • targetTouchs : 特定于事件目标的Touch对象数组.
    • changeTouches : 表示自上次触摸以来发生了什么改变的Touch对象数组。
      每个Touch对象包括下列属性:
      • clientXclientYidentifier(标识触摸的唯一ID)、pageXpageYscreenXscreenYtarget(触摸的DOM节点目标)

手势事件

当两个手指触碰屏幕时就会产生手势。

  • gesturestart : 当一个手指已经俺在屏幕上而另一个手指又触碰屏幕时触发。
  • gesturechange : 当触摸屏幕的任何一个手指的位置发生变化时触发。
  • gestureend : 当任何一个手指从屏幕上面移开时触发。
    每个手势事件对象包含标准鼠标事件属性外,还另外包含两个额外的属性:rotationscale,rotation 表示手指变化引起的旋转角度, scale属性表示两个手指间距离的变化情况。

内存和性能

在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能。
对“事件处理程序过多”问题的解决方案就是事件委托(在同一个委托函数中对id进行分类并分别处理)。

使用事件委托好处是:

  • document对象很快就可以访问,而且可以在页面生命周期的任何时点上为它添加事件处理程序(无需等待DOMContentLoadedload事件)。换句话说,只要可点击的元素呈现在页面上,就可以立即具备适当的功能。
  • 在页面中设置事件处理程序所需的时间更少。只添加一个事件处理程序所需的DOM引用更少,所花的时间也更少。
  • 整个页面占用的内存空间更少,能够提升整体性能。

使用removeChild()replaceChild()innerHTML()时,要先将元素事件处理程序移除掉,避免无法回收。
另一种情况就是卸载页面的时候。IE8或更早版本在这种情况下是问题最多的浏览器。如果在页面被卸载时没有清理干净事件处理程序有可能会滞留在内存中。

模拟事件

可以在document对象上使用createEvent()方法创建event对象.接受一个参数,即表示要创建的事件类型的字符串。这个字符串可以是下列几个字符串之一。(DOM2为英文复数形式,DOM3为单数)

  • UIEvents: 一般化的UI事件,鼠标事件和键盘事件都继承自UI事件。
  • MouseEvents: 一般化的鼠标事件。
  • MutationEvents: 一般化的DOM变动事件。
  • HTMLEvents: 一般化的HTML事件。

表单脚本

在HTML中,表单是由

元素来表示的。而在JavaScript中,表单对应的则是HTMLFormElement类型。

HTMLFormElement有它自己下列独有的属性和方法:

  • acceptCharset : 服务器能够处理的字符集,等价于HTML中的accept-charset特性。
  • action : 接受请求的URL;等价于HTML中的action特性。
  • elements : 表单中所有控件的集合(HTMLCollection)。
  • enctype : 请求的编码类型;等价于HTML中的enctype特性。
  • length : 表单中控件数量
  • name : 表单的名称,等价于HTML的name特性。
  • reset() : 将所有表单域重置为默认值。
  • submit() : 提交表单。
  • target : 用于发送请求和接受响应的窗口名称;等价于HTML的target特性。

注意事项:

  1. 提交表单,只要将其type特性的值设置为submit即可。
  2. 用这种方式提交表单时,浏览器会将请求发送给服务器之前触发submit事件,这样的话我们就有机会去验证表单事件,阻止这个事件的默认行为就可以取消表单提交。(preventDefault())
  3. 在表单中使用form.submit()也可以提交表单,但不会触发submit事件。
  4. 调用reset()方法和type设置为reset可以用来重置表单.

所有表单字段都拥有相同一组属性:

  • disabledformnamereadOnlytabIndextypevalue

文本框脚本