jQuery 事件
一、绑定事件
.on() 方法能实现绑定任何事件,内部由 addEventLister() 来实现的,
只不过 .on() 除了能绑定系统事件 click, mouseenter…,这种浏览器能通过线程监测到的事件,
还可以绑定非系统的的自定义事件,自定义事件通过 .trigger() 来触发
1、.on() 方法的四个参数
.on( 'type', 'selector', 'data', 'handle' )
1. type 事件类型(必填)
2. selector 选择器,可以筛选具体绑定哪些标签,利用事件委托的时候才会用(可以不填)
3. data 函数执行的参数(可以不填)
4. handle 事件处理函数(必填)
第一个参数,type 事件类型
同一个事件类型,可以绑定多个事件处理函数,点击一次弹出两次 alert
<div class="demo" style="width:100px;height:100px;background-color:chocolate"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('.demo').on('click', function(){ alert('第一次哦'); }); $('.demo').on('click', function(){ alert('第二次呦'); }); </script>
同一个事件类型,多次绑定同一个事件处理函数,也会弹出两次提示框
function demo(){ alert('弹出窗口'); } $('.demo').on('click', demo); $('.demo').on('click', demo);
平时基本不会这样做,真想执行两次弹窗,一个函数里写两次 alert() 不好吗
第三个参数
第三个参数 data 的类型可以是对象,字符串,布尔值,传什么都可以,但是要注意一个小问题
1. 如果第三个参数传的是"字符串",并且没有传第二个参数 $('.demo').on('type', 'selector', 'data', 'handle)
1. 按照参数的顺序,data 会理解成选择器 selector,不会有任何效果
2. 什么都打印不出来,其实连事件都没绑定上,因为是给 $('.demo') 下面的 cc 值绑定事件,但是没有符合条件的
$('.demo').on('click', 'cc', function(e){ console.log(e.data); });
第三个参数参数传一个对象 { name: 'Glee' } ,可以在事件对象 e.data 属性里面取
$('.demo').on('click', {name:'Glee'}, function(e){ console.log(e.data); // {name: 'Glee'} });
第三个参数也可以填 true
$('.demo').on('click', true, function(e){ console.log(e.data); // true });
如果第三个参数就想传"字符串",可以传一个占位第二参数,比如传一个空字符串,或者不传加一个逗号
$('.demo').on('click', '', '这是第三个参数', function(e){ console.log(e.data); // 这是第三个参数 });
第二个参数 selector
第二个参数 selector 作用蛮大的,不仅起到过滤的作用,而且事件委托的时候经常会使用到
给所有的 $('li') 绑定事件,效率肯定是不高的,我们利用事件委托给 li 绑定事件
1. 当点击 li 时候 e.target 是 li,因为点击 li,事件会冒泡到 ul
2. 事件函数执行,e.target 判断事件源是谁?
3. 事件源是 li,最后弹出 li 里的文本
<style> ul{width:600px;padding:10px;list-style:none;background-color: antiquewhite;} li{height:20px;padding:20px;margin-bottom:10px; background-color: burlywood;color:#fff;} </style> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('ul').on('click', function(e){ alert($(e.target).text()); // e.target是事件源对象,也就是说事件发生在谁的身上 }); </script>
需求是给 li 绑定事件,结果点击 ul 时也有反映,可以传第二个参数 li
1. 事件还是给 $('ul') 绑定,只不过 jQuery 在内部冒泡的时候会判断一下,事件源是不是 li ?
2. 如果事件源是 li,才去执行事件处理函数,否则就不会执行,点击 ul 就不弹出了
$('ul').on('click', 'li', function(e){ alert($(e.target).text()); });
怎么知道 jQuery 内部是给 ul 绑定的事件呢?
1. 创建一个新的 li,然后插入到 ul 里面,也就是在绑定事件之后新增了li
2. 如果是给 li 绑定的事件,新添加的 li 现在没有被绑定事件,点击不会有反应
3. 如果是给 ul 绑定的事件,事件委托追加任何一个li都会冒泡到 ul,点击 li 是可以弹出
$('<li>新增7</li>').appendTo($('ul')); $('ul').on('click', 'li', function(e){ alert($(e.target).text()); });
总结第二个参数的目的
1. 进一步进行筛选,让谁起到作用
2. 起到事件委托的作用,只能谁去触发
2、.one() 方法只执行一次
A 标签绑定一个 one() 事件
第一次点击,先跳转到淘宝,然后取消 A 标签自己跳转百度的默认事件
第二次点击,one() 方法没有用了,就打开 a 标签自己默认的 href,跳转的百度
<a href="https://baidu.com" target="_black">点击</a> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('a').one('click',function(e){ window.open('http://www.taobao.com'); // 跳转到淘宝 return false; // 阻止a标签跳转百度的默认事件 }); </script>
取消默认事件 jQuery 里非常简单,
1. 直接 return false 就可以是兼容,而且还阻止了冒泡
2. 也可以 e.preventDefault() 阻止默认事件也是兼容的
一次性事件一般的适用场景做广告,配合延迟器来做
3、一个标签同时绑定多种事件类型
.on() 一次绑 定click、mouseenter、mousetleave,三个事件类型
1. 可以这样 .on().on().on() 绑定,
2. 也可以一次 .on 来绑
.on() 传一个对象,属性对应属性值的方式,jQuery 内部 for in 来解析
<div class="demo" style="width:100px;height:100px;background-color:chocolate"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('.demo').on({ click: function(){ console.log('click'); }, mouseenter: function(){ console.log('mouseenter'); }, mouseleave: function(){ console.log('mouseleave'); } }); </script>
二、解绑事件
为了解绑事件呈现出一个更好的对比
1. 给 demo 绑定两种事件类型 click、mouseenter
2. 每种事件类型,绑定两种不同的事件处理函数
<div class="demo" style="width:100px;height:100px;background-color:chocolate"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('.demo').on('click', clickOne); $('.demo').on('click', clickTwo); $('.demo').on('mouseenter', enterOne); $('.demo').on('mouseenter', enterTwo); // 两个命名的click事件处理函数 function clickOne(){ console.log('clickOne'); } function clickTwo(){ console.log('clickTwo'); } // 两个命名的mouseenter事件处理函数 function enterOne(){ console.log('enterOne'); } function enterTwo(){ console.log('enterTwo'); } </script>
什么参数都不填,所有事件全部解绑,无论系统的还是自定义的
$('.demo').off();
如果传一个参数,
一定要传事件类型,对应 click 点击类型全部取消了,鼠标移入还是有反应的
$('.demo').off('click');
填两个参数,
第一个填事件类型,第二个填事件处理函数,点击只剩下一个事件函数 clickOne
$('.demo').off('click', clickTwo);
on() 用的第二个参数,官方推荐怎么绑定,off() 也怎么来解绑
<style> ul{width:600px;padding:10px;list-style:none;background-color:antiquewhite;} li{height:20px;padding:20px;margin-bottom:10px;background-color:burlywood;color:#fff;} </style> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> <script> function clickOne(e){ alert($(e.target).text()); } $('ul').on('click', 'li', clickOne); // 绑定绑定 $('ul').off('click', 'li', clickOne); // 就怎么解绑 </script>
绑定的是 li 这样解绑偶数位 li 是不行的
$('ul').off('click', 'li:even', clickOne)
三、主动触发事件trigger()
trigger() 作用帮我们主动的去触发一列事件
1. 无论是系统事件还是自定义事件,
2. 自定义事件只能用 trigger()
如果用户点击操作,
浏览器有线程监控 click 点击事件,系统帮我们去触发,
trigger() 是从代码层面上去触发事件
<div class="demo" style="width:100px;height:100px;background-color:chocolate"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('.demo').on('click', function(){ console.log('click') }); $('.demo').trigger('click'); </script>
第一个参数事件类型,
第二个参数是一个数组,数组里面的值会成为事件函数执行时候的参数
<div class="demo" style="width:100px;height:100px;background-color:chocolate"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('.demo').on('click', function(e, a, b, c, d){ // 事件函数的第一个参数e是事件对象,后面的a,b,c,d对应数组里面的[10,20,30,40] console.log(a, b, c, d); }); $('.demo').trigger('click', [10, 20, 30, 40]); // 10 20 30 40 </script>
.trigger() 主动触发某一个事件函数的时候,
实参,需要参数用数组的形式传进去 ( 'click', [10, 20, 30, 40] )
形参,必须在事件对象 e 之后,必须把 e 先写出来 function( e, a, b, c, d )
trigger() 的应用场景
比如广告层右上角有一个 x 关闭的,广告层播放广告会数秒,用户不点击 x 关闭,数秒 5~6 秒后广告播放完也会自动消失,
用户可以点击执行关闭方法,
用户不点击时间到了 trigger() 自动触发,还执行关闭方法,
trigger() 对系统已有的事件触发还是非常有意义的,在编程里非常常见,
自定义事件这块 trigger() 还能大展身手
四、体现编程实力的时候到了"自定义事件"
on() 方法可以绑定自定义 pageLoad 事件, pageLoad 是我们自己定义的,使用 trigger('pageLoad') 触发
<div class="demo" style="width:100px;height:100px;background-color:chocolate"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('.demo').on('pageLoad', function(){ console.log('触发了'); }); $('.demo').trigger('pageLoad'); // 参数变成了自定义事件类型pageLoad </script>
自定义事件往往能体现出我们的编程实力,
比如 fullpage 插件,全屏滚动切换没有系统事件去监控到,但是我们的需要給每个页面都绑定自定义事件(pageLoad),叫页面加载成功事件
pageLoad 事件,我们需要按照一定的逻辑,到达某个点了必须要使用 trigger() 去触发了
自定义事件的传参的形式是一样
<div class="demo" style="width:100px;height:100px;background-color:chocolate"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('.demo').on('pageLoad', function(e,a,b,c,d){ console.log('pageLoad',a,b,c,d) }); $('.demo').trigger('pageLoad', [10,20,30,40]); </script>
五、hover() 事件
如果不用 hover 事件也可以,通过两个 on 的方式绑定了mouseenter 和 mouseleave
<div class="demo" style="width:100px;height:100px;background-color:chocolate"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('.demo').on('mouseenter', function(){ $(this).css({backgroundColor: 'orange'}); }).on('mouseleave', function(){ $(this).css({backgroundColor: 'yellow'}); }); </script>
hover() 事件很方便
$('.demo').hover(function(){ $(this).css({backgroundColor: 'orange'}); }, function(){ $(this).css({backgroundColor: 'yellow'}); });
六、直接使用事件
键盘事件
<input type="text"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $('input').keydown(function(){ console.log($(this).val()); }); </script>
思考题,
鼠标滑轮事件 mousewheel
附,
事件对象
已经做好兼容了,名字和原生的也没有很大变化
e.pageX 点击位置
e.clienX 点击位置
e.which 鼠标是那个键
e.button 鼠标左右键
e.preventDefault() 阻止默认事件
e.stopPropagation() 阻止冒泡
return false; 兼容阻止事件冒泡和默认事件