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 中首先实现.后来 ...
随机推荐
- uva 2572 Viva Confetti
思路: 小圆面是由小圆弧围成.那么找出每条小圆弧,如果小圆弧,在小圆弧中点上下左右进行微小位移的所得的点一定在一个小圆面内. 找到最后覆盖这个小点的圆一定是可见的. 圆上的点按照相邻依次排序的关键量为 ...
- HDU-4704 Sum 大数幂取模
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4704 题意:求a^n%m的结果,其中n为大数. S(1)+S(2)+...+S(N)等于2^(n-1) ...
- 50个Java多线程面试题
不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java 语言一个重要的特点就是内置了对并发的支持,让 Java 大受企业和程序员的欢迎.大多数待遇丰厚的 Java 开发职位都要求开发者 ...
- Android 如何添加一种锁屏方式
前言 欢迎大家我分享和推荐好用的代码段~~ 声明 欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net ...
- 【翻译自mos文章】DBA_JOBS 和 DBA_JOBS_RUNNING 不同的结果的解释
DBA_JOBS 和 DBA_JOBS_RUNNING 不同的结果 參考原文: Different Results from DBA_JOBS and DBA_JOBS_RUNNING (Doc ID ...
- Java路径操作具体解释
1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或文件夹在硬盘上真正的路径.(URL和物理路径)比如: C:\xyz\test.txt 代表了test.txt文件的绝对路径.http://w ...
- Android开发环境中的概念和工具介绍
最近学习Android开发,以前使用C/C++多一些,现在再补点Java知识,不管是哪种语言,都不过是一种工具而已,真的学起来,大同小异,无谓优劣.学习Android编程肯定是要先从环境搭建开始,无论 ...
- zendserver 安装 ZendDebugger
网上都找不到支持PHP5.3及以上的Zend Debugger,然后下载了ZendStudio 10.1,发现它内置的PHP 5.3 和 5.4都支持Debugger, 这Debugger就是Zend ...
- android124 zhihuibeijing 新闻中心-新闻 -北京页签 下拉刷新
缓存工具类:以url为key,json数据为value, package com.itheima.zhbj52.utils; import com.itheima.zhbj52.global.Glob ...
- Mysql shell 控制台---mysqlsh
原创 2016-07-12 杜亦舒 性能与架构 以前登录Mysql的控制台后,使用SQL语言来操作数据库,如 mysql> select * from tablename; Mysql 5.7. ...