目录
- 事件
- 如何绑定事件处理函数?
- 封装事件处理函数—解决兼容性问题
- 解除事件处理程序
- 事件处理模型—事件冒泡,事件捕获
- 取消事件冒泡和阻止事件默认事件
- 事件对象
- 事件委托
- 事件分类—鼠标事件
- 事件分类—键盘事件
- 事件分类—窗体操作类
- 事件分类—表单事件
事件
1.何为事件?
HTML 事件是发生在 HTML 元素上的事情。
当在 HTML 页面中使用 JavaScript 时, JavaScript 可以触发这些事件。
简单来说就是JavaScript 与页面进行交互,交互就是触发给出一定的反馈。
2.重要吗?
交互体验的核心功能
演示demo–拖拽和点击
<body>
<div style="width:100px; height:100px; background-color: red;
position: absolute; left: 0px; top:0px;"></div>
<script>
// 绑定事件
function addEvent(dom, type, func) {
if (dom.addEventListener) {
dom.addEventListener(type, func, false);
} else if (dom.attachEvent) {
dom.attachEvent.call('on' + type, function () {
func.call(dom);
});
} else {
dom['on' + type] = func;
}
}
// 解除绑定
function removeEvent(dom,type,func){
if(dom.removeEventListener){
dom.removeEventListener(type,func,false);
}else if(dom.detachEvent){
dom.detachEvent('on'+type,func)
}else{
dom['on'+type]=false;
}
}
// 停止冒泡
function StopBubble(event){
if(event.stopPropagation){
event.stopPropagation();
}else if(event.cancelBubble){
event.cancelBubble=true;
}
}
// 取消默认事件
document.oncontextmenu=function(e){
CancelHandler(e);
}
function CancelHandler(event){
if(event.preventDefault){
event.preventDefault();
}else {
event.returnValue=false;
}
}
var div = document.getElementsByTagName('div')[0];
function test(div) {
var divX,
divY;
addEvent(div,'mousedown',function(e) {
var event = e || window.event;
divX = event.clientX-parseInt(div.style.left);
divY = event.clientY-parseInt(div.style.top);
addEvent(div,'mousemove',mousemove);
addEvent(div,'mouseup',mouseup);
CancelHandler(event);
StopBubble(event);
})
function mousemove(e) {
var event = e || window.event;
div.style.left=e.clientX-divX+'px';
div.style.top=e.clientY-divY+'px';
}
function mouseup(e) {
var event = e || window.event;
removeEvent(div,'mousemove',mousemove);
removeEvent(div,'mouseup',mouseup);
}
}
test(div);
</script>
</body>
如何绑定事件处理函数?
1.ele.onXXX=function(event){}
- 兼容性很好,但是一个元素的同一个事件只能绑定一个处理程序
- 基本等同于写在html行间上
- this指向dom元素本身
<body>
<div style=" width:100px; height:100px; background-color:red;"
onclick=this.style.backgroundColor="pink" ;></div>
<script>
var div=document.getElementsByTagName('div')[0];
div.onclick=function(){
this.style.backgroundColor="yellow";
// this指向dom元素本身
}
div.onclick=function(){
this.style.backgroundColor="blue";
} //触发点击事件,颜色会是blue,一个元素的同一个事件只能绑定一个处理程序
</script>
</body>
2.obj.addEventListener(type,function(){},false);
- IE9以下的版本不兼容,可以为一个事件绑定多个处理程序
- this指向dom元素本身
<body>
<div style=" width:100px; height:100px; background-color:red;"></div>
<script>
var div=document.getElementsByTagName('div')[0];
div.addEventListener("click",function(){
this.style.backgroundColor="blue";
// this指向dom元素本身
console.log("abc");
},false)
div.addEventListener("click",function(){
console.log("edgf");
},false)
// 输出结果是:abc edgf
</script>
</body>
3.obj.attachEvent(‘on’+type,function(){});
- IE独有,一个事件可以绑定多个处理程序
- this指向window
<body>
<div style=" width:100px; height:100px; background-color:red;"></div>
<script>
var div=document.getElementsByTagName('div')[0];
div.attachEvent("onclick",function(){
// this指向window 该方法是IE独有的方法
console.log("abc");
})
// 目前我的IE浏览器和chrome浏览器是报错的一个状态
// Uncaught TypeError: div.attachEvent is not a function
</script>
</body>
封装绑定事件–解决兼容性
<body>
<div style=" width:100px; height:100px; background-color:red;"></div>
<script>
var div = document.getElementsByTagName('div')[0];
function addEvent(dom, type, func) {
if (dom.addEventListener) {
dom.addEventListener(type, func, false);
} else if (dom.attachEvent) {
dom.attachEvent.call('on' + type, function () {
func.call(dom);
});
} else {
dom['on'+type]=func;
}
}
function func() {
this.style.backgroundColor = "pink";
}
addEvent(div,'click',func);
</script>
</body>
解除事件处理程序
- ele.οnclick=false/‘null’;
<body>
<div style=" width:100px; height:100px; background-color:red;"
onclick=this.style.backgroundColor="pink" ;></div>
<script>
var div=document.getElementsByTagName('div')[0];
// div.οnclick=function(){
// this.style.backgroundColor="yellow";
// }
//div.οnclick=false;
div.onclick="null";
</script>
</body>
- ele.removeEventListener(type,func,false);
- ele.detachEvent(‘on’+type,func);
- 使用 removeEventListener() ,detachEvent()方法移除, 通过添加的事件句柄
- 注意:若绑定的是匿名函数无法解除
<body>
<div style=" width:100px; height:100px; background-color:red;"></div>
<script>
var div=document.getElementsByTagName('div')[0];
div.addEventListener("click",function(){
this.style.backgroundColor="blue";
},false);
// function(){
// this.style.backgroundColor="blue";
// } 匿名函数无法找到
// 如果要使用 removeEventListener() 方法移除, 通过 addEventListener() 方法添加的事件句柄
div.addEventListener("click",test,false);
function test(){
console.log("事件句柄");
}
div.removeEventListener("click",test,false);
</script>
</body>
事件处理模型—事件冒泡,事件捕获
- 事件冒泡:结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素(自底向上)
简单来说:就是从自己开始逐层向父元素进行冒泡触发元素对应的事件 - focus,blur,change,submit,reset,select等事件不冒泡
<body>
<div class="parent" style="width: 200px;height: 200px; background-color: red;">父元素
<div class="content"style="width: 100px;height: 100px; background-color: peru;">中间元素
<div class="son"style="width: 50px;height: 50px;background-color: blue;">子元素</div>
</div>
</div>
<script>
var div1=document.getElementsByClassName('parent')[0];
var div2=document.getElementsByClassName('content')[0];
var div3=document.getElementsByClassName('son')[0];
function addEvent(dom, type, func) {
if (dom.addEventListener) {
dom.addEventListener(type, func, false);
} else if (dom.attachEvent) {
dom.attachEvent.call('on' + type, function () {
func.call(dom);
});
} else {
dom['on'+type]=func;
}
}
function func() {
console.log(this);
}
addEvent(div1,'click',func);
addEvent(div2,'click',func);
addEvent(div3,'click',func);
</script>
</body>
- 事件捕获:结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获子元素(事件源元素)(自顶向下)
简单来说:从触发当前元素事件,先找到该元素嵌套最顶端的父元素依次往下触发其他层次父元素事件 - //addEventListener中的false变为true,则开启事件捕获
- 注意:IE没有捕获事件
- 如果同时存在事件冒泡和事件捕获 :触发顺序–先捕获-后冒泡
<body>
<div class="parent" style="width: 200px;height: 200px; background-color: red;">父元素
<div class="content"style="width: 100px;height: 100px; background-color: peru;">中间元素
<div class="son"style="width: 50px;height: 50px;background-color: blue;">子元素</div>
</div>
</div>
<script>
var div1=document.getElementsByClassName('parent')[0];
var div2=document.getElementsByClassName('content')[0];
var div3=document.getElementsByClassName('son')[0];
function addEvent(dom, type, func) {
if (dom.addEventListener) {
dom.addEventListener(type, func, true);//addEventListener中的false变为true,则开启事件捕获
}
}
function func() {
console.log(this);
}
addEvent(div1,'click',func);
addEvent(div2,'click',func);
addEvent(div3,'click',func);
</script>
</body>
取消事件冒泡和阻止事件默认事件
-
取消冒泡:
W3C标准event.stopPropagation(),但不支持IE9以下版本
IE可以使用event.cancelBubble=true; -
封装取消冒泡函数StopBubble(event);
<body>
<div class="parent" style="width: 200px;height: 200px; background-color: red;">父元素
<div class="content"style="width: 100px;height: 100px; background-color: peru;">中间元素
<div class="son"style="width: 50px;height: 50px;background-color: blue;">子元素</div>
</div>
</div>
<script>
var div1=document.getElementsByClassName('parent')[0];
var div2=document.getElementsByClassName('content')[0];
var div3=document.getElementsByClassName('son')[0];
function addEvent(dom, type, func) {
if (dom.addEventListener) {
dom.addEventListener(type, func, false);
} else if (dom.attachEvent) {
dom.attachEvent.call('on' + type, function () {
func.call(dom);
});
} else {
dom['on'+type]=func;
}
}
function func() {
console.log(this);
}
addEvent(div1,'click',func);
addEvent(div2,'click',func);
div3.onclick= function func(e) {
StopBubble(e);
console.log(this);
}
function StopBubble(event){
if(event.stopPropagation){
event.stopPropagation();
}else if(event.cancelBubble){
event.cancelBubble=true;
}
}
</script>
</body>
-
阻止默认事件
默认事件—表单提交,a标签跳转,右键菜单(oncontextmenu)等
1,return false ,以对象属性的方式注册的事件才生效
2,event.preventDefault();W3C标注,IE9以下版本不兼容
3,event.returnValue=false;IE兼容 -
封装阻止默认事件的函数 CancelHandler(event);
<body>
<script>
document.oncontextmenu=function(e){
CancelHandler(e);
}
function CancelHandler(event){
if(event.preventDefault){
event.preventDefault();
}else {
event.returnValue=false;
}
}
</script>
</body>
事件对象
- event||window.event( 用于IE)
- 事件源对象:
1,event.target 火狐只有这个
2,event.srcElement IE只有这个
event.target 和 event.srcElement Chrome都有
兼容所有浏览器获得事件源对象
<body>
<script>
var div=document.createElement('div');
document.body.appendChild(div);
div.style.width="100px";
div.style.height="100px";
div.style.backgroundColor="red";
div.onclick=function(e){
var event= e||window.event;
var target=event.target||event.srcElement;
//console.log(event);
console.log(target);
}
</script>
</body>
事件委托
- 事件委托就是利用事件冒泡和事件源对象进行处理;
优点:
- 提高性能,每个元素不需要循环绑定事件
- 灵活,当有新的子元素时,不需要重新进行绑定
下面这个例子是,假如给ul下面1000个li标签绑定一个事件,后期可以随意添加li标签,同时也绑定了事件
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
</div>
<script>
var ul=document.getElementsByTagName('ul')[0];
ul.onclick=function(e){
var event= e||window.event;
var target=event.target||event.srcElement;
console.log(target.innerText);
}
</script>
事件分类–鼠标事件
- 用button来区分鼠标的按键,0/1/2
- DOM3标准规定:click事件只能监听左键,只能通过mousedown和mouseup来判断鼠标键
事件分类–键盘事件
- keydown可以响应任意键盘按键
- keypress只可以响应字符键盘按键
- keypress返回Ascll码,可以通过String.fromcharcode(e.charcode)转换成相对应字符