获取事件
- on : onxxxx
一个对象的一个事件只能绑定一个函数 - dom.addEventListener(时间类型,处理函数,false);
能给一个事件绑定多个处理函数(不能给一个函数绑定多次) - div.addEventListener(‘click’, function(){
console.log(‘a’);
},flase);
-IE 独有
div.attachEvent(‘on’ + 时间类型, 处理函数);
可以一个函数绑定多次
事件处理程序的运行环境
- ele.onxxx = function(event) {}
程序 this 指向是 dom 元素本身 - obj.addEventListener(type, fn, false);
程序 this 指向是 dom 元素本身 - obj.attachEvent(‘on’ + type, fn);
程序this指向window
封装一个方法:给一个 dom 对象添加一个事件处理函数(兼容性很好的)
function() addEvent(elem, type, handle) {
if(elem.addEventListener) {
elem.addEventListener(type, handle, false);
}else if(ele.attachEvent) {
elem.attachEvent('on' + type, function() {
handle.call(elem);
})
}else{
elem['on' + type] = handle;
}
}
解除事件处理程序
- ele.onclick = false/’’/null;
- ele.removerEventListener(type, fn, false);
- ele.detachEvent(‘on’ + type, fn);
- 若绑定匿名函数, 则无法解除。
事件处理模型— 事件冒泡丶捕获
- 事件冒泡 结构上嵌套的元素存在于个冒泡的功能,即同一事件,自子元素冒泡向父元素。(自内向外,自底向上)
举个例子:
效果如下:<style> .box{ width: 300px; height: 300px; background-color: red; } .border{ width: 200px; height: 200px; background-color: green; } .content{ width: 100px; height: 100px; background-color: yellow; } </style> <body> <div class="box"> <div class="border"> <div class="content"></div> </div> </div> <script> var oCent = document.getElementsByClassName('content')[0]; var oBord = document.getElementsByClassName('border')[0]; var oBox = document.getElementsByClassName('box')[0]; oCent.addEventListener('click',function(){ console.log('centent'); },false) oBord.addEventListener('click',function(){ console.log('border'); },false) oBox.addEventListener('click',function(){ console.log('box'); },false) </script> </body>
当点击红色区域时:
当点击绿色区域时:
当点击黄色区域时:
点击处于结构中最内层的div时会触及到他的父级 - 事件捕获 (只有 chrome 有)
把addEventListener括号里面最后面的 flase 改为 true 就是 事件捕获
结构上(非视觉上) 嵌套关系的元素,会存在事件捕获事件,自父元素捕获至子元素(事件源元素)。(自上而底)
出发顺序 先捕获 后冒泡
focus,blur,change,submit,reset,select等事件不冒泡。
取消冒泡和阻止
事件对象(上面有个方法可以阻止冒泡)
取消冒泡
- e.stopPropagation();
用法:div.addEventListener('click',function(e){ div.style.backgroundColor = 'green'; e.stopPropagation(); },false)
- e.cancelBubble = true; (之前是IE独有的,现在谷歌也有了);
封装一个取消冒泡的函数:
function stopBubble(event) {
if(event.stopPropagation) {
event.stopPropagation();
}else{
event.cancelBubble = true;
}
阻止默认事件:
(oncontextmenu:右键点击出菜单事件)
- document.oncontextmenu = function () {
return false;
} - document.oncontextmenu = function (e) {
e.preventDefault();
} - document.oncontextmenu = function (e) {
e.returnValue = false;
} //兼容IE
封装一个取消默认阻止时间的函数:
function cancelHandler(event) {
if(event.preventDefault) {
event.preventDefault();
}else{
event.returnValue = false;
}
}
(a标签的默认事件可以取消)
(也可以这样写<a href="javascript: void(false)> </a>"
)
事件对象
event || window.event 用于 IE
当IE下:
div.onclick = function(e) {
var event = e || window.event;
console.log(event);
}
时 e 出不来
此时要用 window.event
//事件源对象:
- event.target 火狐只有这个
- event.scrElement IE 只有这个
举个例子:
<body>
<div class ="wrapper" style="width:100px;height:100px;background-color:red;"></div>
<div class ="box" style="width:50px;height:50px;background-color:green;"></div>
<script>
var wrapper = document.getEelementsByClassName('wrapper')[0];
wrapper.onclick = function(e) {
var event = e || window.event;
console.log(event);
}
</script>
</body>
效果图如下:
当点击红色区域时它的事件源对象为:
当点击绿色区域时它的原对象为:(是冒泡出来的结果)
可以看出源对象返回的是谁触发的事件。
事件委托
-
利用事件冒泡,和事件源对象进行处理
不需要循环所有的元素一个个绑定事件
当有新的子元素时不需要重新绑定事件
根据事件源对象我们可以简化: (有多个li)点击 li 让每个 li 的内容弹出来:
<body> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> //......此处省去n多个li </ul> <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> </body>
简化的原理:我们通过事件的冒泡和事件的原对象,来选择 li 的父级 ul (而不是用for循环把事件写在每个div上),给 ul 绑定一个点击事件,然后通过找到 li 事件对象的原对象 ,最后再打印出原对象的 innerText ,这样就能实现点击 li 的时候打印 对应的 li 的内容了。
这里实现一个拖拽小方块:
<div style="width:100px;height:100px;background-color:red;position: absolute;left: 0px;top: 0px;"></div>
<script>
//拖拽小方块
var div = document.getElementsByTagName('div')[0];
var disX,
disY;
div.onmousedown = function(e){
disX = e.pageX - parseInt(div.style.left);
disY = e.pageY - parseInt(div.style.top);
document.onmousemove = function(e) {
var event = e || window.event;
div.style.left = event.pageX - disX +'px';
div.style.top = event.pageY -disY+ 'px';
}
}
document.onmouseup = function() {
document.onmousemove = null;
}
</sctipt>
事件捕获额外内容(
div.setCapture(); //将所有的事件强行加在自己身上。
div.releaseCapture();
//只有IE能用;
)
鼠标监听
onmouseenter ----> onmouseover
onmouseleave ----> onmouseout
用 button 测试左右键 (左键0,右键2,中键1)加上mouseup 和 mousedown。onclick不行,只能监听左键。右键不能触发click。
移动端的 touchstar touchmove touchend
键盘事件
onkeydown 能够检测到所有键盘上的键(除了fn)
onkeypress 只能检测到字符类按键(返回ASCII码)
onkeyup
string.fromCharCode(e.charCode) 把ASCII码转换成字符。
-
oninput事件:但凡文本有变化它都会触发(输入一个 和 删除一个字符直接触发)
-
onchange事件:聚焦发生—》改变—》失去焦点(触发)【聚焦和失去焦点时状态呢不一样时触发】
- 实现一个简单的用户登陆框:
<input type="text" value="请输入用户名" style="height: 80px;width: 200px;border: 1px solid;position: absolute;left: 200px;">
<script>
var input = document.getElementsByTagName('input')[0];
input.onfocus = function(){
if(this.value == '请输入用户名'){
input.value = '';
}
}
input.onblur = function() {
if(this.value == ''){
input.value = '请输入用户名';
}
}
</script>
IE6没有fixed
onscroll事件滚轮滚动。
本周力扣算法题: