javascript与HTML之间的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
事件三要素:
1)事件目标(eventtarget)发生的事件与之相关联或与之相关的对象
2)事件处理程序(eventhandler)处理或相应事件的函数
3)事件对象(eventobject)与特定事件相关且包含有关该事件详细信息的对象
事件流
描述的是从页面中接受事件的顺序
1)事件捕获(从外向内解析函数)
2)事件冒泡(从内向外执行函数)
默认情况下先进行事件捕获,然后进行事件冒泡
事件的绑定与解绑
dom 0级事件:
绑定:dom.onType=function(){}
解绑:dom.onType=null;
优点:兼容性好
缺点: 不能同时对同一dom元素绑定同一类型的多个事件,做多个事件设置相当于是做了事件重写
dom 2级事件:
绑定:dom.addEventListener(事件类型,事件处理,执行阶段)
解绑:dom.removeEventListener("click",程序,执行阶段)
执行阶段 布尔值:true在捕获阶段调用事件处理程序;false在冒泡阶段调用,默认执行阶段是冒泡阶段 false
缺点:兼容性较差
IE8以下 attachEvent() detachEvent()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div#outer{
height: 300px;
width: 300px;
border: 1px solid red;
margin: 0 auto;
}
div#center{
height: 200px;
width: 200px;
border: 1px solid red;
margin: 0 auto;
}
div#inner{
height: 100px;
width: 100px;
border: 1px solid red;
margin: 0 auto;
}
</style>
<script type="text/javascript">
window.onload=function(){
//1.获取事件目标
var outer=document.getElementById('outer');
//2.绑定一个事件
outer.onclick=function(evet){
//console.log(evet);
alert(this.id);//this-->outer
}
/*outer.onclick=function(){
alert("outer222---");
} 不能对同一dom元素绑定同一类型的多个事件*/
//解绑outer
//outer.onclick=null;//函数名相同即为重写
center.onclick=function(evet){
alert(this.id);
}
inner.onclick=function(evet){
alert(this.id);
}
//inner-->center-->outer
/*dom 2级事件
outer.addEventListener("click",function(){
alert("outer");
},true);
function say(){
alert("outer222");
};//设置一个引用地址,在2级事件移除时使用
outer.addEventListener("click",say,true);同一元素设定了不同事件
移除:
outer.removeEventListener("click",say,true);
center.addEventListener("click",function(){
alert("center");
},true);
inner.addEventListener("click",function(){
alert("inner");
},true);*/
}
</script>
</head>
<body>
<div id="outer">
<div id="center">
<div id="inner"></div>
</div>
</div>
</body>
</html>

事件对象
当声明好一个函数之后,将函数绑定给一个dom元素,这个函数中会多出一个event实参,触发事件后会进行传参

属性:
1)target:事件目标
始终指向触发事件的元素
2)currentTarget:事件目标
指向当前正在执行函数的元素
3)this:事件目标 和currentTarget一致
4)type:返回事件类型
方法:
5)stopPropagation() Function取消事件的进一步捕获或者冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
div{
margin:0 auto;
border:1px solid red;
}
div#outer{
width: 300px;
height: 300px;
}
div#center{
width: 200px;
height: 200px;
}
div#inner{
width: 100px;
height: 100px;
}
</style>
<script type="text/javascript">
window.onload=function(){
var outer=document.getElementById('outer');
var center=document.getElementById('center');
var inner=document.getElementById('inner');
outer.onclick=function(event){
// // console.log(event.target)始终指向触发事件的元素,点击outer控制台输出三个outer
// console.log(event.currentTarget)//指向当前正在执行函数的元素
// console.log(event.type)//返回事件类型--》click
// console.log(event.this)//指向当前正在执行函数的元素
event.stopPropagation();
console.log(this)//取消事件的进一步捕获或者冒泡,只进行一次
}
center.onclick=function(event){
// // console.log(event.target)
// console.log(event.currentTarget)
event.stopPropagation();
console.log(this)
}
inner.onclick=function(event){
// // console.log(event.target)
// console.log(event.currentTarget)
event.stopPropagation();
console.log(this)
}
}
</script>
</head>
<body>
<div id="outer">
<div id="center">
<div id="inner"></div>
</div>
</div>
</body>
</html>
6)preventDefault() Function取消事件的默认行为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload=function(){
var input=document.getElementsByTagName("input")[0];
var form=document.forms[0];
form.onsubmit=function(event){//onsubmit 表单提交事件
var p1=/^\d{8}$/;//利用正则表达式验证表单 以数字开头^\d 输入8个数字 匹配结尾也是数字$
if(p1.test(input.value)){//input.value 拿到input的值 test()-->true/false
alert("提交成功!!");
}else{
alert("数据类型有误,请重新输入!");
event.preventDefault();//验证失败,阻止事件提交
}
}
}
</script>
</head>
<body>
<form action="1.html">
<h3>请输入学号:</h3>
<input type="text" name="number">
<button>提交</button>
</form>
</body>
</html>

UI事件
1)load 当页面完全加载后在window上触发,当所有框架加载完时在框架集上触发,当图像加载完毕时在img元素上触发,当嵌入的内容加载完时在<object>触发
2)unload 当页面完全卸载后在window上触发,当所有框架都卸载后在框架集上触发,当嵌入的内容卸载完毕后再<object>上触发,(firefox不支持)
3)select 当用户选择文本框(<input>,<textarea>)中的一个或多个字符时
4)change 在select的下拉列表的选中的选项更改的时候触发
5)resize 当浏览器窗口被调整到一个新的高度或者宽度时,会触发
6)scroll 当用户滚动带滚动条的元素中的内容时,在该元素上触发,resize,scroll 会在变化期间重复被激发,尽量保持代码简单
焦点事件
1)blur 元素失去焦点的时候触发
2)focus 元素获得焦点的时候触发,不支持冒泡//IE支持
3)focusin 与focus等价,支持冒泡
4)focusout 与blur等价,支持冒泡
鼠标与滚轮事件
1)click 点击主鼠标按钮或者按下回车按键的时候触发。只有在一个元素上相继发生mousedown,mouseup事件,才会触发click事件【支持子元素】
2)dblclick 双击主鼠标按钮时触发.只有在一个元素上相继触发两次click时间才会触发dbclick事件
3)mousedown 任意鼠标按钮按下时触发
4)mouseup 释放鼠标按钮触发
5)mousemove 鼠标在元素内部移动的时候重发触发
6)mousewheel 滚轮事件
7)mouseenter鼠标光标从元素外部首次移动到元素范围内激发,不冒泡。【不支持子元素】
8)mouseleave 在位于元素上方的鼠标光标移动到元素范围之外时触发,不冒泡【不支持子元素】
9)mouseover 鼠标位于元素外部,将其首次移入另一个元素边界之内时触发【支持子元素】
10)mouseout 在位于元素上方的鼠标光标移入到另外一个元素中。【支持子元素】在被选元素上与mouseleave效果相同
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>支持子元素和不支持子元素事件</title>
<style>
div{
margin:0 auto;
border:1px solid red;
}
div#outer{
width: 300px;
height: 300px;
}
div#center{
width: 200px;
height: 200px;
}
div#inner{
width: 100px;
height: 100px;
}
</style>
<script type="text/javascript">
window.onload=function(){
var outer=document.getElementById('outer');
outer.onmouseenter=function(event){
console.log(event.target);//支持子元素,event.target会发生改变层层嵌套,触发哪个元素显示哪个元素
}
}
</script>
</head>
<body>
<div id="outer">
<div id="center">
<div id="inner"></div>
</div>
</div>
</body>
</html>
键盘与文本事件
1)keydown 按下键盘任意键时触发,如果按住不放会重复触发此事件
2)keypress 按下键盘字符键时触发,如果按住不放会重复触发此事件
3)keyup 释放键盘上键时触发
当键盘事件发生时,event对象的keyCode属性中会包含一个代码与键盘上的特定键对应,对数字字母键,keyCode属性的值与ASCII码中对应的小写字母和数字编码相同
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
window.onload=function(){
var input=document.getElementsByTagName('input')[0];
input.onkeydown=function(event){
/*alert(event.keyCode);*/
if(event.keyCode==13){
alert("你按下回车了--");
}
}
}
</script>
</head>
<body>
<input type="text">
</body>
</html>
事件代理
解决了:添加的一行没有事件绑定
解决方法:将本应该绑定给子元素的事件,绑定给直接父元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
table{
border-collapse: collapse;
margin:20px auto;
}
table th,table td{
width: 100px;
height: 30px;
border:1px solid black;
text-align: center;
}
div{
width: 200px;
margin:50px auto;
}
section{
width: 400px;
margin:30px auto;
}
.current{
background-color: pink;
}
</style>
<script type="text/javascript">
window.onload=function(){
var btns=document.getElementsByTagName('button');
var tbody=document.getElementsByTagName("table")[0].children[0];
//1.添加一行
btns[0].onclick=function(){
var tr=document.createElement("tr");
for(var i=0;i<4;i++){//tr中有4个td
var td=document.createElement("td");
tr.appendChild(td);//td-->append-->tr
}
tbody.appendChild(tr);//tr-->append-->tbody
}
//2.鼠标移入添加当前行背景色
tbody.onmouseover=function(event){
if(event.target.nodeName=="TD"){
event.target.parentNode.style.backgroundColor='lightblue';
}
}
tbody.onmouseout=function(event){
if(event.target.nodeName=="TD"){
event.target.parentNode.style.backgroundColor='';
}
}
/*console.log(tbody);
var trs=tbody.children;
Array.prototype.slice.call(trs).forEach(function(item,index){
item.onmouseover=function(event){*/
//给当前行绑定样式
//1.通过styl属性设置样式
//event.currentTarget.style.backgroundColor="pink";
//2.通过class属性设置
//event.currentTarget.className
/*event.currentTarget.setAttribute("class","current");
}
});*/
//3.鼠标移出删除当前行背景色
/* Array.prototype.slice.call(trs).forEach(function(item,index){
item.onmouseout=function(event){*/
//1.通过styl属性设置样式
//event.currentTarget.style.backgroundColor="";
//2.通过class属性设置
/* event.currentTarget.removeAttribute("class");
}
});*/
}
</script>
</head>
<body>
<section>
<input type="text" placeholder="请输入添加行数"><input type="button" value="确定">
<br>
<input type="text" placeholder="请输入关键字"><input type="button" value="搜索">
</section>
<table>
<tr>
<th>姓名</th>
<th>学号</th>
<th>年龄</th>
<th>班级</th>
</tr>
<tr>
<td>章三</td>
<td>1209810017</td>
<td>28</td>
<td>web2001</td>
</tr>
<tr>
<td>李三</td>
<td>1209810016</td>
<td>23</td>
<td>web2001</td>
</tr>
<tr>
<td>王五</td>
<td>1209810019</td>
<td>22</td>
<td>web2002</td>
</tr>
<tr>
<td>赵六</td>
<td>1209810020</td>
<td>29</td>
<td>web2002</td>
</tr>
</table>
<div>
<button>添加</button>
<button>删除</button>
</div>
</body>
</html>

闭包
特点:
1.函数内部的函数
2.函数内部可以引用函数外部的变量
3.闭包使用的变量和参数不会被垃圾回收机制销毁
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
window.onload=function(){
//0.基础问题
function outer(){
var a=10;
return function(){
a++;
return a
}
}
var inner=outer();
//console.log(inner());-->11
//1.经典问题
function say(){
var num=10;
return function(){
var n=0;
console.log(++num);
console.log(++n);
}
}
var result=say();
//result();先打印++num,再打印++n 11;1
//result();12;1 n被重新赋值,num并没有被销毁
//2.弹出问题
var btns=document.getElementsByTagName('button');
for(var i=0;i<btns.length;i++){
btns[i].onclick=(function(num){
return function(){
alert(num);
}
})(i)//匿名函数立即执行,把i传入
}
}
</script>
</head>
<body>
<button>btn1</button>
<button>btn2</button>
<button>btn3</button>
<button>btn4</button>
<button>btn5</button>
</body>
</html>
