JavaScript高级程序设计(第三版)学习笔记13、14章
第13章,事件
事件冒泡
事件捕获:
HTML事件处理程序
<input type="button" value="Click Me" onclick="alert('Clicked')" />
单击,显示警告框。onclick特性的值不能使用未经转移的HTML语法字符:&,",<,>。若想使用双引号:
<input type="button" value="Click Me" onclick="alert("Clicked")" />
<!-- 输出 “click” -->
<input type="button" value="Click Me" onclick="alert(event.type)" />
通过event变量,可以直接访问事件对象,且,在函数内部,this值等于事件的目标元素,例:
<!-- 输出 “Click Me” -->
<input type="button" value="Click Me" onclick="alert(this.value)" />
还可以使用扩展作用域,在函数内部可以像访问局部对象一样访问document及该元素本身,so可以如下使用with扩展作用域:
function(){
with(document){
with(this){
//元素属性值
}
}
}
如此一来,事件处理程序访问属性就简单多了:
<!-- 输出 “Click Me” -->
<input type="button" value="Click Me" onclick="alert(value)" />
可能是form表单输入元素,则作用域还会包含表单元素(父元素)的入口:
function(){
with(document){
with(this.form){
with(this){
//元素属性值
}
}
}
}
实际上只是为了让事件处理程序无需引用表单元素就能访问其他表单字段:
<form>
<input type="text" name="username" value="">
<input type="button" value="Echo Username" onclick="alert(username.value)">
</form>
<input type="button" value="Click Me" onclick="try{showMessage();}catch(ex){}" />
DOM0级事件处理程序
var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert("Clicked");
};
使用DOM0级事件处理程序被认为是元素的方法,为此是在元素作用域中运行,即,程序中的this引用当前元素,例:
var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert(this.id); //"myBtn"
};
btn.onclick = null; //删除事件处理程序
DOM2级事件处理程序
定义两个方法用于处理指定和删除事件处理程序的操作:addEventListener(),removeEventListener(),所有DOM节点都包含这两个方法,且都接收3个参数:要处理的事件名,作为事件处理程序的函数,布尔值。布尔值为true,捕获阶段调用函数,false,冒泡阶段调用函数
var btn = document.getElementById("myBtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
使用DOM2级好处:添加多个程序,触发顺序按添加顺序
var btn = document.getElementById("myBtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
btn.addEventListener("click",function(){
alert("hello");
},false);
通过addEventListener添加,只能通过removeEventListener删除,删除时传入参数与添加时参数相同,即若是添加时使用了匿名函数,则无法移除:
//无效的事件处理程序移除
var btn = document.getElementById("myBtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
//其他代码
btn.removeEventListener("click",function(){ //无效
alert(this.id);
},false);
//有效的事件处理程序移除
var btn = document.getElementById("myBtn");
var handle = function(){
alert(this.id);
}
btn.addEventListener("click",handle,false);
//其他代码
btn.removeEventListener("click",handle,false); //有效
IE事件处理程序
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick",function(){
alert(this.id);
});
跨浏览器的事件处理程序
//跨浏览器事件处理程序
var EventUtil = {
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false); //DOM2级
}else if(element.attachEvent){
element.attachEvent("on" + type,handler); //兼容IE8及更早版本,加上“on”,IE方法
}else{
element["on" + type] = handler; //DOM0
}
}, removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false);//DOM2级
}else if(element.detachEvent){
element.detachEvent("on" + type,handler) //兼容IE8及更早版本,加上“on”,IE方法
}else{
element["on" + type] = null;
}
}
};
使用示例:
//使用示例
var btn = document.getElementById("myBtn");
var handler = function(){
alert("hello");
};
EventUtil.addHandler(btn,"click",handler);
//其他代码
EventUtil.removeHandler(btn,"click",handler);
事件对象
属性/方法 | 类型 | 读/写 | 说明 |
bubbles | Boolean | 只读 | 是否冒泡 |
cancelable | Boolean | 只读 | 会否可取消默认行为 |
currentTarget | Element | 只读 | 当前处理的元素 |
defaultPrevented | Boolean | 只读 | true表示已调用preventDefault方法(DOM3新增) |
detail | Integer | 只读 | 与事件相关细节信息 |
eventPhase | Integer | 只读 | 1、捕获阶段,2、处于目标,3、冒泡阶段 |
preventDefault | Function | 只读 | 取消时间默认行为,cancelable为true可使用 |
stopImmediatePropagation | Function | 只读 | 取消事件的进一步捕获或冒泡,并阻止事件处理程序调用(DOM3新增) |
stopPropagation | Function | 只读 | 取消事件进一步捕获或冒泡,若bubbles为true,可使用此方法 |
target | Element | 只读 | 事件目标 |
trusted | Boolean | 只读 | true事件由浏览器生成,false事件由js生成(DOM3新增) |
type | String | 只读 | 被触发事件类型 |
view | AbstractView | 只读 | 与事件关联的抽象视图,等同于发生事件的window对象 |
在事件处理程序内部,this始终等于currentTarget,target只包含事件实际目标(个人理解:就是事件在哪个元素产生,就是那个元素),若直接将事件处理程序指定给目标元素,则三者相同值,例:
var btn = document.getElementById("myBtn");
btn.onclick = function(event){
alert(event.currentTarget === this); //true
alert(event.target === this); //true
}
若事件在按钮父节点,则不一样:
document.body.onclick = function(event){
alert(event.currentTarget === document.body); //true
alert(this === document.body); //true
alert(event.target === document.getElementById("myBtn")); //true
}
在需要一个函数处理多个事件时,可以使用type属性:
//一个函数处理多个事件
var btn = document.getElementById("myBtn");
var handler = function(event){
switch(event.type){
case "click":
alert("click");
break;
case "mouseover":
alert("mouseover");
break;
case "mouseout":
alert("mouseout");
break;
}
};
btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;
IE中的事件对象
var btn = document.getElementById("myBtn");
btn.onclick = function(){
var event = window.event;
alert(event.type); //"click"
};
事件处理程序使用attachEvent添加,那么会有个event对象传入:
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick",function(event){
alert(event.type); //"click"
});
若通过HTML指定事件处理程序还可以通过一个名叫event的变量访问event对象,例:
<input type="button" value="Click Me" onclick="alert(event.type)">
属性/方法 | 类型 | 读/写 | 说明 |
cancelBubble | Boolean | 读/写 | 默认false,设为true,取消事件冒泡 |
returnValue | Boolean | 读/写 | 默认true,设为false可以取消事件默认行为,与DOM的preventDefault方法一样 |
serElement | Element | 只读 | 事件目标,与DOM的target相同 |
type | String | 只读 | 被触发的事件类型 |
因为事件处理程序的作用域是根据指定它的方式来确定的,所以不能认为this会始终等于事件目标,为此,最好使用event.serElement比较保险,例:
var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert(window.event.srcElement === this); //true
};
btn.attachEvent("onclick",function(event){
alert(event.srcElement === this); //false
});
跨浏览器事件对象:
//跨浏览器事件对象
var EventUtil = {
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false); //DOM2级
}else if(element.attachEvent){
element.attachEvent("on" + type,handler); //兼容IE8及更早版本,加上“on”,IE方法
}else{
element["on" + type] = handler; //DOM0
}
}, getEvent:function(event){ //返回对event对象的引用
return event?event:window.event;
}, getTarget:function(event){ //返回事件的目标
return event.target||event.srcElement;
}, preventDefault:function(event){ //取消事件默认行为
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
}, removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false);//DOM2级
}else if(element.detachEvent){
element.detachEvent("on" + type,handler) //兼容IE8及更早版本,加上“on”,IE方法
}else{
element["on" + type] = null;
}
}, stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
}; //使用示例
btn.onclick = function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
}; var link = document.getElementById("myLink");
link.onclick = function(event){ //可确保在所有浏览器中单击该链接都不会打开另一个页面
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);
}; //由于IE不支持事件捕获,所以只能用来阻止事件冒泡
var btn = document.getElementById("myBtn");
btn.onclick = function(event){
alert("Clicked");
event = EventUtil.getEvent(event);
EventUtil.stopPropagation(event);
};
document.body.onclick = function(event){
alert("body clicked");
};
事件类型
UI事件
//浏览器是否支持DOM3级事件定义的事件
var isSupported = document.implementation.hasFeature("UIEvent","3.0");
1、load事件
EventUtil.addHandler(window,"load",function(event){
alert("Loaded");
});
第二种指定onload事件处理程序方式是为<body>添加onload属性:
<!DOCTYPE html>
<html>
<head>
<title>Load Event Example</title>
</head>
<body onload="alert('Loaded!')"> </body>
</html>
EventUtil.addHandler(window,"load",function(){
var script = document.createElement("script");
EventUtil.addHandler(script,"load",function(event){
alert("Loaded");
});
script.src = "example.js";
document.body.appendChild(script);
});
2、unload事件
3、resize事件
4、scroll事件
焦点事件
//确定浏览器是否支持焦点事件
var isSUpported = document.implementation.hasFeature("FocusEvent","3.0");
鼠标与滚轮事件
//确定浏览器是否支持DOM2级鼠标事件
var isSUpported = document.implementation.hasFeature("MouseEvents","2.0");
//确定浏览器是否支持所有鼠标事件
var isSUpported = document.implementation.hasFeature("MouseEvent","3.0"); //差了个s
1、客户区坐标位置
2、页面坐标位置
var div = document.getElementById("myDiv");
EventUtil.addHandler(div,"click",function(event){
event = EventUtil.getEvent(event);
var pageX = event.pageX;
pageY = event.pageY; if(pageX == undefined){
pageX = event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);
} if(pageY == undefined){
pageY = event.clientY + (document.body.scrollTop || document.documentElement.scrollTop);
} alert("Page coordinates: " + pageX + "," + pageY);
});
3、屏幕坐标位置
4、修改键
5、相关元素
var EventUtil = {
//其他代码 getRelatedTarget:function(event){
if(event.relatedTarget){
return event.relatedTarget;
}else if(event.toElement){
return event.toElement;
}else if(event.fromElement){
return event.fromElement;
}else {
return null;
}
}, //其他代码
};
6、鼠标按钮
var EventUtil = {
//其他代码 getButton:function(event){
if(document.implementation.hasFeature("MouseEvents","2.0")){ //检测MouseEvents特性可以知道event对象存在的button属性是否包含正确的值,失败,说明是IE
return event.button;
}else{
switch(event.button){
case 0:
case 1:
case 3:
case 5:
case 7:
return 0;
case 2:
case 6:
return 2;
case 4:
return 1;
}
}
}, //其他代码
}
7、更多的事件信息
8、鼠标滚轮事件
var EventUtil = {
//其他代码 getWheelDelta:function(event){
if(event.wheelDelta){
return (client.engine.opera && client.engine.opera < 9.5 ?
-event.wheelDelta : event.wheelDelta);
}else{
return -event.detail * 40;
}
}, //其他代码
}
9、触摸设备
10、无障碍性问题
键盘与文本事件
3个键盘事件:
1、键码
2、字符编码
var EventUtil = {
//其他代码 getCharCode:function(event){
if(typeof event.charCode == "number"){
return event.charCode;
}else{
return event.keyCode;
}
}, //其他代码
}
3、DOM3级变化
4、textInput事件
var textbox = document.getElementById("myText");
EventUtil.addHandler(textbox,"textInput",function(event){
event = EventUtil.getEvent(event);
alert(event.data);
});
5、设备中的键盘事件
复合事件
变动事件
//检查浏览器是否支持变动事件
var isSUpported = document.implementation.hasFeature("MutationEvents","2.0");
1、删除节点
<!DOCTYPE html>
<html>
<head>
<title>Node Removal Events Example</title>
</head>
<body>
<ul id="myList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</body>
</html>
2、插入节点
HTML5事件
1、contexmenu事件
2、beforeunload事件
3、DOMContentLoaded事件
4、readystatechange事件
5、pageshow和pagehide事件
6、hashchange事件
设备事件
1、orientationchange事件
2、MozOrientation事件
3、deviceorientation事件
4、devicemotion事件
触摸与手势事件
1、触摸事件
2、手势事件
内存和性能
事件委托
<ul id="myLinks">
<li id="goSomewhere">Go somewhere</li>
<li id="doSomething">Do something</li>
<li id="sayHi">say hi</li>
</ul>
包含3个单击后会执行操作的列表项,按之前的做法,需要每个都添加事件处理程序。若在复杂的web程序中如此做,将会有数不清的代码用于事件处理程序。使用事件委托,只需在DOM树中尽量高的层次添加一个事件处理程序,例:
var list = document.getElementById("myLinks");
EventUtil.addHandler(list,"click",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event); switch(target.id){
case "doSomething":
document.title = "I changed the document's title";
break;
case "goSomewhere":
location.href = "http://www.wrox.com";
break;
case "sayHi":
alert("hi");
break;
}
});
移除事件处理程序
<div id="myDiv">
<input type="button" value="Click Me" id="myBtn">
</div>
<script type="text/javascript">
var btn = document.getElementById("myBtn");
btn.onclick = function(){
//先执行某些操作
btn.onclick = null; //移除事件处理程序 document.getElementById("myDiv").innerHTML = "Processing...";
};
</script>
模拟事件
DOM中的事件模拟
1、模拟鼠标事件
2、模拟键盘事件
3、模拟其他事件
4、自定义DOM事件
IE中的事件模拟
第14章,表单脚本
表单基础知识
var form = document.getElementById("form1");
2、通过document.forms获取所有表单元素,通过数值索引或name值来取得特定表单
var firstForm = document.forms[0]; //取得页面中的第一个表单
var myForm = document.forms["form2"]; //取得页面中name值为“form2“的表单
提交表单
<!-- 通用提交按钮 -->
<input type="submit" value="Submit Form"> <!-- 自定义提交按钮 -->
<button type="submit">Submit Form</button> <!-- 图像按钮 -->
<input type="image" src="graphic.gif">
var form = document.getElementById("myForm"); //提交表单
form.submit();
重置表单
<!-- 通用重置按钮 -->
<input type="reset" value="Reset Form"> <!-- 自定义重置按钮 -->
<button type="reset">Reset Form</button>
重置按钮也可以通过js,例:
var form = document.getElementById("myForm");
//重置表单
form.reset();
表单字段
1、共有的表单字段属性
2、共有的表单字段方法
3、共有的表单字段事件
文本框脚本
选择文本
1、选择(select)事件
var textbox = document.forms[0].elements["textbox1"];
EventUtil.addHandler(textbox,"select",function(event){
var alert("Text selected" + textbox.value);
});
2、取得选择文本
3、选择部分文本
过滤输入
1、屏蔽字符
2、操作剪切板
var EventUtil = {
//其他代码 getCliboardText:function(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
}, setCliboardText:function(event,value){
if(event.clipboardData){
return event.clipboardData.setData("text/plain",value);
}else if(window.clipboardData){
return window.clipboardData.setData("text",value);
}
}, //其他代码
};
自动切换焦点
<input type="text" name="tel1" id="txtTel1" maxlength="3">
<input type="text" name="tel2" id="txtTel2" maxlength="3">
<input type="text" name="tel3" id="txtTel3" maxlength="4">
自动切换焦点功能实现:
(function(){
function tabForward(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event); if(target.value.length == target.maxLength){
var form = target.form; for(var i=0,len=form.elements.length;i < len;i++){
if(form.elements[i] == target){
if(form.elements[i+1]){
form.elements[i+1].focus();
}
return ;
}
}
}
} var textbox1 = document.getElementById("textTel1");
var textbox2 = document.getElementById("textTel2");
var textbox3 = document.getElementById("textTel3"); EventUtil.addHandler(textbox1,"keyup",tabForward);
EventUtil.addHandler(textbox2,"keyup",tabForward);
EventUtil.addHandler(textbox3,"keyup",tabForward); })();
HTML5约束验证API
1、必填字段
<input type="text" name="username" required>
2、其他输入类型
3、数值范围
4、输入模式
5、检测有效性
6、禁用验证
选择框脚本
选择选项
添加选项
移除选项
移动和重排选项
表单序列化
富文本编辑
使用contenteditable属性
操作富文本
富文本选区
JavaScript高级程序设计(第三版)学习笔记13、14章的更多相关文章
- JavaScript高级程序设计第三版学习笔记(一)之数据类型区分详谈
null.NaN.undefined三者的区别是什么? 在初次接触到JavaScript的时候,傻傻的分不清null.NaN.undefined三者到底区别何在,在实际的项目开发中也因为这个问题而困惑 ...
- JavaScript高级程序设计第三版-读书笔记(1-3章)
这是我第一次用markdown,也是我第一次在网上记录我自己的学习过程. 第一章 JavaScript主要由以下三个不同的部分构成 ECMAScript 提供核心语言功能 DOM 提供访问 ...
- JavaScript高级程序设计第三版.CHM【带实例】
从驱动全球商业.贸易及管理领域不计其数的复杂应用程序的角度来看,说 JavaScript 已经成为当今世界上最流行的编程语言一点儿都不为过. JavaScript 是一种非常松散的面向对象语言,也是 ...
- javascript高级程序设计第三版书摘
在HTML 中使用JavaScript <script>元素 在使用<script>元素嵌入 JavaScript 代码时,只须为<script>指定 type 属 ...
- 21.1 XMLHttpRequest 对象【JavaScript高级程序设计第三版】
IE5 是第一款引入XHR 对象的浏览器.在IE5 中,XHR 对象是通过MSXML 库中的一个ActiveX对象实现的.因此,在IE 中可能会遇到三种不同版本的XHR 对象,即MSXML2.XMLH ...
- DOM 操作技术【JavaScript高级程序设计第三版】
很多时候,DOM 操作都比较简明,因此用JavaScript 生成那些通常原本是用HTML 代码生成的内容并不麻烦.不过,也有一些时候,操作DOM 并不像表面上看起来那么简单.由于浏览器中充斥着隐藏的 ...
- 模拟事件【JavaScript高级程序设计第三版】
事件,就是网页中某个特别值得关注的瞬间.事件经常由用户操作或通过其他浏览器功能来触发.但很少有人知道,也可以使用JavaScript 在任意时刻来触发特定的事件,而此时的事件就如同浏览器创建的事件一样 ...
- Javascript高级程序设计第三版-笔记
1.JS数值最大值最小值: >Number.MIN_VALUE <5e-324 >Number.MAX_VALUE <1.7976931348623157e+308 判断数值是 ...
- 22.1 高级函数【JavaScript高级程序设计第三版】
函数是JavaScript 中最有趣的部分之一.它们本质上是十分简单和过程化的,但也可以是非常复杂和动态的.一些额外的功能可以通过使用闭包来实现.此外,由于所有的函数都是对象,所以使用函数指针非常简单 ...
- 2.1 <script>元素【JavaScript高级程序设计第三版】
向 HTML 页面中插入 JavaScript 的主要方法,就是使用<script>元素.这个元素由 Netscape 创造并在 Netscape Navigator 2 中首先实现.后来 ...
随机推荐
- 2015北京网络赛B题 Mission Impossible 6
借用大牛的一张图片:模拟 #include<cstdio> #include<cmath> #include<cstring> #include<algori ...
- 如何理解Stay hungry,stay foolish?
People know about this words because of Steve Jobs.Me too. Hungry,对知识我们一般不会用hungry,我们会用curious,什么时候我 ...
- 题目1043:Day of Week(输入日期与当前日起天数差%7,在做相关星期调整)
题目描述: We now use the Gregorian style of dating in Russia. The leap years are years with number divis ...
- C++ 顺序表
C++ 顺序表 /***1顺序表1.必做题 编写程序建立一个数续表,并逐个输出顺序表中所有数据元素的值.编写主函数测试结果. 编写顺序表定位操作子函数,在顺序表中查找是否存在数据元素x. 如果存在,返 ...
- 50道经典的JAVA编程题(36-40)
50道经典的JAVA编程题(36-40),今天晚上心情压抑,不爽,继续做题,管它明天考试,我继续我的java,一个周末都在看微机原理看得的很头疼啊~明天该挂科就挂吧,不在乎了~~~ [程序36] Ar ...
- 50道经典的JAVA编程题 (16-20)
50道经典的JAVA编程题 (16-20),用了快一个下午来做这10道题了,整理博客的时间貌似大于编程的时间啊..哈哈 [程序16]Nine.java 题目:输出9*9口诀. 1.程序分析:分行与列考 ...
- Redhat常见问题
1.现象:hadoop用户启动startx时失败,报如下提示 Fatal server error: PAM authentication failed, cannot start X server. ...
- 【转载】c++中的 extern "C"(讲的更好一些)
[说明]本文章转载自 东边日出西边雨 的文章http://songpengfei.iteye.com/blog/1100239 ------------------------------------ ...
- 2016多校第六场题解(hdu5793&hdu5794&hdu5795&hdu5800&hdu5802)
这场就做出一道题,怎么会有窝这么辣鸡的人呢? 1001 A Boring Question(hdu 5793) 很复杂的公式,打表找的规律,最后是m^0+m^1+...+m^n,题解直接是(m^(n+ ...
- android事件分发笔记
1.SimpleOnGestureListener 遇到的问题: 自己定义一个按钮继承自Button,一开始改变按钮颜色的操作放在onTouchEvent的ATION_DOWN里触发. 这时问题来了, ...