一、注册事件
1.传统方式
2.方法监听注册方式
addEventListener里面的事件类型是是字符串,必须加引号,而且不带on,function函数叫做监听器(function里面的东西就叫监听器),这个可以给同一个元素添加多个处理函数,比如下面这两段代码页面先警示11,再22
btn.addEventListener('click', function () {
alert('11');
})
btn.addEventListener('click', function () {
alert('22');
})
二、删除事件
按钮点了之后可以禁用,如果是div 的话,我想让div点了一次再点就不会弹对话框了,但是div又没有办法禁用,咋办呢
可以点一次就删除这个事件。
1.传统注册方式
this.onclick = null;
var div=document.querySelectorAll('div');
div[0].onclick=function(){
alert('hh');
this.onclick=null;
}
2.方法监听注册方式
this.removeEventListener(‘click’, fn);
<script>
var div=document.querySelectorAll('div');
div[0].addEventListener('click',fun)
function fun(){
alert('hh');
this.removeEventListener('click',fun);
}
</script>
这里的function就不能写在里面了,注册事件的时候写在里面当匿名函数,但是删除事件的时候remove需要写函数名,不能直接写function
三、dom事件流
三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段
注意:1.js代码只能执行捕获或冒泡中的一个阶段
2.onclick或attachEvent只能得到冒泡阶段
3.addEventListener中的第三个参数如果是true,表示在捕获阶段处理程序,是false(什么都不写),表示在冒泡阶段处理程序
var father = document.querySelector('.father');
var son = document.querySelector('.son');
//给父亲添加点击事件,true表示事件捕获
father.addEventListener('click', function () {
alert('father');
}, true);
//点击son,结果弹出来father,再弹出来son
son.addEventListener('click', function () {
alert('son');
}, true);
true是捕获阶段,我点击了son之后,先弹出father再son,从上往下
father.addEventListener('click', function () {
alert('father');
}, );
son.addEventListener('click', function () {
alert('son');
}, );
现在什么都没写,表示冒泡阶段,先弹出son再father,从下往上
四、事件对象
1.事件对象
最后打印出来鼠标点击事件,包括xy坐标和作用的对象(兼容版:window.e)
2.事件对象常用的属性和方法
(1)event.target返回触发事件的对象(元素)
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function (event) {
console.log(this); //返回ul
console.log(event.target); // 返回li
console.log(event.type); //返回click
})
</script>
event.target返回的是触发事件的对象(元素),而this返回的是绑定事件的对象(元素)
this就是你前面的啥.addEventListener是啥this就是什么
event.target是看什么触发的事件,我点了li才触发,那返回的就是li
(2)event.preventDefault() 阻止默认行为
比如点击链接(这种默认行为)但是阻止链接跳转
//阻止默认事件event.preventDeafult();
var a = document.querySelector('a');
a.addEventListener('click', fn);
function fn(e) {
e.preventDefault();
}
(3)event.stopPropagation() 阻止事件冒泡
冒泡事件中,我点击了son,father也会执行,添加e.stopPropagation()之后就只执行son,father不会动
var father = document.querySelector('.father');
var son = document.querySelector('.son');
//给父亲添加点击事件,true表示事件捕获,false或者不写表示事件冒泡
father.addEventListener('click', function () {
alert('father');
}, false);
//点击son,结果弹出来son,再弹出来father
son.addEventListener('click', function () {
alert('son');
e.stopPropagation(); //阻止事件冒泡
}, false);
只会弹出son,father不弹
五、事件委托!!!
原理:不在每个子节点单独设置事件监听器(函数),而是在其父节点上设置事件监听器,然后利用事件冒泡来通过子节点影响父节点
就比如ul中有五个li,以前要是想对li做点啥是不是还得循环对五个li依次获取太麻烦了,直接对父节点添加事件监听器,然后用target来找到li,因为点击li之后会冒泡到ul上
var ul = document.querySelector('ul');
ul.addEventListener('click', function (event) {
//console.log(this); //返回ul
//console.log(event.target); // 返回li
event.target.style.backgroundColor='pink';
六、常用的键盘鼠标事件
1、鼠标事件
(1)常用的鼠标事件
(2)鼠标事件对象
可视区是浏览器除了控制台区域,所以就算有滚动条,你在滚动条最后一页点击左上角也是x30 y30px(举例个大概数)
案例:小天使图片跟着鼠标动
注意:图片是来回移动在页面最上方的,所以用定位,每次鼠标移动的时候我们都能得到一个x、y坐标,把这个作为图片的top和left就行
img{
position: absolute;
}
</style>
<body>
<img src="angel.gif" alt="">
<script>
//body=document.querySelector('body');
img=document.querySelector('img');
document.addEventListener('mousemove',fn)
function fn(e){
img.style.left= e.clientX+'px';
img.style.top= e.clientY+'px';
}
</script>
</body>
我写的时候给再body里面的mousemove,但是检查能看到body里面没有内容就没被撑开,很小一条,总的应该是document才对
2、键盘事件对象
(1)常用的键盘事件
<script>
document.addEventListener('keyup',function(){
console.log('hh');
})
document.addEventListener('keydown',function(){
console.log('aa');
})
</script>
三个事件的执行顺序:keydown→keypress→keyup
(2)键盘事件对象
.key
document.addEventListener('keyup',function(e){
console.log(e.key);
})
(3)案例:按下s键就定位到文本框焦点
核心:用.key判断是否输入了s,输入的话就focus
var input=document.querySelector('input');
document.addEventListener('keyup',function(e){
if(e.key=='s'||'S'){
input.focus();
}
})
我本来用的是keydown,这样的话确实是有光标了,但是s也跟着进搜索栏了,因为按下去就有光标,获取光标之后还按着s可不就输入就去了吗(按着的时间没办法控制)
(4)案例:京东快递单号查询
.search{
position: relative;
margin: 100px;
}
input{
width: 200px;
height: 20px;
}
.con{
width: 150px;
height: 30px;
border: 1px solid rgb(139, 135, 135);
display: none;
font-size: 15px;
top: -35px;
position: absolute;
}
.con::before{
content: '';
width: 0;
height: 0;
position: absolute;
border: 8px solid #000;
top: 28px;
left: 18px;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
<body>
<div class="search">
<div class="con"></div>
<input type="text" placeholder="请输入您的快递单号">
</div>
<script>
var input=document.querySelector('input');
var con=document.querySelector('.con');
input.addEventListener('keyup',function(e){
con.style.display='block';
//输入完了再来检测内容,所以用up更合适
con.innerHTML=this.value;
//=e.key的话每次框里只有当下输入的一个字母
//表单里的值用value表示!!!
if(!this.value)
{
con.style.display='none';
}
})
input.addEventListener('blur',function(e){
con.style.display='none';
})
input.addEventListener('focus',function(e){
if(this.value!=='')
{
con.style.display='block';
}
})
</script>
用keydown的话每次输入之后框里显示的比输入的少一个字母,因为keydown和keypress触发的时候,文字还没有落入文本框中
下去还得再练习巩固一下,到了后面学起来确实没有前面省劲了