事件与表单脚本总结
事件
JS与html之间的
交互
是通过事件
来实现的,可以用侦听器(或处理程序)来预定事件
事件流(从页面中接收事件的顺序)
- 事件冒泡(IE的事件流)
从嵌套层次最深的节点开始然后逐级向上到不具体的节点(文档):
沿DOM树往上
+ 一个例子
<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling Example</title>
</head>
<body>
<div id="myDiv">Click Me</div>
</body>
</html>
+ 如果单击了div元素,那么这个事件会按照(div->body->html->document)顺序传播
- 事件捕获(与事件冒泡相反:
沿DOM树往下
,一直传播到事件的实际目标) - DOM事件流
- 三个阶段:事件捕获阶段(
捕获
) - 处于目标阶段(
接收
) - 事件冒泡阶段(
做出响应)
- 三个阶段:事件捕获阶段(
事件处理程序(事件侦听器):响应某个事件的函数
事件处理程序的名字以on开头
- HTML事件处理程序
某个元素支持的每种事件,都可以使用一个与相应事件处理程序
同名的 HTML 特性来指定
+ 可以通过event变量直接访问事件对象
+ 扩展作用域的方式:
+ 1、用with扩展作用域
>拓展: with: 一般的,“由于with语句块中作用域的‘变量对象’是只读的,`所以在他本层定义的标识符,不能存储到本层,而是存储到它的上一层作用域”`。
function(){
with(document){
with(this){
//元素属性值
}
}
}
//就能更好访问自己的属性
<input type="button" value="Click Me" onclick="alert(value)">
- 2、如果是一个表单输入元素,则作用域中还会包含表单元素(父元素)的入口
<form method="post">
<input type="text" name="username" value="">
<input type="button" value="Echo Username" onclick="alert(username.value)">
</form>
- 在HTML中指定事件处理程序的缺点:
- 1、时差问题(当时的事件处理程序有可能尚不具备执行条件)
- 2、扩展事件处理程序的作用域链在不同浏览器中会导致不同结果。
- 3、 HTML 与 JavaScript 代码耦合太紧密
- DOM0级事件处理程序(将一个函数赋值给一个事件处理程序属性)=>被认为是元素的方法(在元素的作用域中运行)
var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert("Clicked");
};
- 也可以
删除
,直接将事件处理程序的属性设置为null
btn.onclick = null; //删除事件处理程序
- DOM2级事件处理程序
- 定义了两个方法:
- 1、addEventListener(要处理的事件名,事件处理程序的函数,布尔值)
- 2、removeEventListener(也是三个参数,同上)
所有DOM节点都包含这两种方法,三个参数的最后一个参数布尔值表示:
- true:
捕获阶段调用
- false:
冒泡阶段调用
- 定义了两个方法:
- 使用DOM2级方法的好处是:可以添加多个事件处理程序,如下:
var btn = document.getElementById("myBtn");
btn.addEventListener("click", function(){
alert(this.id);
}, false);
btn.addEventListener("click", function(){
alert("Hello world!");
}, false);
以上两个语段会按照顺序执行
要注意的点是:
- 1、
通过 addEventListener() 添加的事件处理程序只能使用 removeEventListener() 来移除
(匿名函数则无法移除)- 2、大多数情况下,都是将事件处理程序添加到
事件流的冒泡阶段
,这样可以最大限度地兼容各种浏览
器。
- 跨浏览器的事件处理程序
- addHandler 方法,可以参考https://www.cnblogs.com/n2meetu/p/7121701.html
####事件对象(触发DOM上的某个事件时会产生一个event的事件对象)
- addHandler 方法,可以参考https://www.cnblogs.com/n2meetu/p/7121701.html
- DOM中的事件对象
无论指定事件处理程序时使用什么方法
(DOM0 级或 DOM2 级)
,都会传入event
对象,event 对象包含与创建它的特定事件有关的属性和方法
-
this 、 currentTarget 和 target
- 在事件处理程序内部,对象
this 始终等于 currentTarget 的值
,而target
则只包含事件的实
际目标。如果直接将事件处理程序指定给了目标元素
,则 this 、 currentTarget 和 target 包含相同的值
- 在事件处理程序内部,对象
-
例子
var btn = document.getElementById("myBtn");
btn.onclick = function(event){
alert(event.currentTarget === this); //true
alert(event.target === this); //true
};
事件类型(参考https://www.cnblogs.com/smileke/p/9944043.html)
- UI事件
- 焦点事件
- 鼠标与滚轮事件
- 键盘与文本事件
- 复合事件
- 变动事件
- 设备事件
- 触摸与手势事件
内存和性能
在 JavaScript 中,添加到页面上的
事件处理程序数量将直接关系
到页面的整体运行性能
- 事件委托(“事件处理程序过多”问题的解决方案)
建立在
事件冒泡机制
之上的事件委托技术,可以有效地减少事件处理程序的数量
- 一个例子
- 先是html代码:
<ul id="myLinks">
<li id="goSomewhere">Go somewhere</li>
<li id="doSomething">Do something</li>
<li id="sayHi">Say hi</li>
</ul>
- 添加事件的js代码
var item1 = document.getElementById("goSomewhere");
var item2 = document.getElementById("doSomething");
var item3 = document.getElementById("sayHi");
EventUtil.addHandler(item1, "click", function(event){
location.href = "http://www.wrox.com";
});
EventUtil.addHandler(item2, "click", function(event){
document.title = "I changed the document's title";
});
EventUtil.addHandler(item3, "click", function(event){
alert("hi");
});
1、上面这段js代码可以看到如果对单击元素都是用这种方式那么要写
许多的添加事件处理程序的代码
2、因袭为了解决就用事件委托来解决:(在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;
}
});
1、如上,理解:为id为mylinks的ul元素添加一个事件,而其他列表项都是他的
子节点
,而且他们的事件会冒泡
,即由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发事件目标是被单击的列表项
,故而可以通过检测 id 属性来决定采取适当的操作
2、但是它与上面那段代码相比结果一样,事前消耗却更低,因为只取得了一个DOM元素,这样占用内存也更少
- 移除事件处理程序
建议在
浏览器卸载页面之前移除
页面中的所有事件处理程序
表单脚本
在 HTML 中,表单是由 元素来表示的,而在 JS中,表单对应的则是 HTMLForm-,其属性和方法如下图:
Element 类型
表单的基础知识
- 提交
- 1、 使用
<input>
和<button>
将type设为submit就可以提交
- 1、 使用
<!-- 通用提交按钮 -->
<input type="submit" value="Submit Form">
<!-- 自定义提交按钮 -->
<button type="submit">Submit Form</button>
这种提交方式浏览器会在将请求
发送给服务器之前触发 submit 事件
所以有机会验证表单数据
- 2、使用submit()方法
var form = document.getElementById("myForm");
// 提交表单
form.submit();
这种方式不会触发 submit 事件,因此要记得
在调用此方法之前先验证表单数据
。
- 重置
- 也是
两种方式
,和提交一样,第一种方式是type值设为reset,第二种是reset()方法,第二种方式不同在于会触发reset事件
- 也是
- 表单字段
每个表单都有elements属性=>表单中所有表单元素的集合
- 可以按照位置和 name 特性来访问
var form = document.getElementById("form1");
//取得表单中的第一个字段
var field1 = form.elements[0];
//取得名为"textbox1"的字段
var field2 = form.elements["textbox1"];
如果有多个表单控件都在使用一个 name (如单选按钮),那么就会
返回以该 name 命名的一个
NodeList (一个列表)
- 共有的表单字段方法( focus() 和 blur() )
1、焦点的理解:当你用鼠标点击一下页面时,会相应的产生一个焦点,比如说,你点击了一个文本输入框,光标将移动到那里,此时,那个文本框就获得了一个焦点,当你在别的地方再点击时,光标消失,那个文本框就失去了焦点。
2、在默认情况下,只有表单字段可以获得焦点
。对于其他元素而言,如果先将其
tabIndex 属性设置为-1,然后再调用 focus() 方法
,也可以让这些元素获得焦点
- focus()方法:将浏览器的焦点设置到表单字段
- blur()方法:从元素中移走焦点:用法document.forms[0].elements[0].blur();