jQuery之事件和批量操作、事件委托示例
一、常用事件
click(function(){...}) // 点击时触发
focus(function(){...}) // 获得焦点触发
blur(function(){...}) // 失去焦点触发
change(function(){...}) // 内容改变后触发
keyup(function(){...}) // 键盘按下后触发
keydown(function(){...}) // 键盘放开后触发
hover(function(){...},function(){...}) // 鼠标移上去触发第一个函数,移开时触发第二个函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> // 按键被按下 $(window).keydown(function (event) { // 每个按键都有一个属于自己的代码编号,打印下哪个按键被按下 console.log(event.keyCode); if (event.keyCode === 16){ console.log('shift被按下了'); } }); // 按键被放开的事件 $(window).keyup(function (event) { console.log(event.keyCode); if (event.keyCode === 16){ console.log('shift被放开了'); } }) </script> </body> </html>
二、事件绑定
1、 jQuery绑定事件的方式
1.on( events [, selector ],function(){})
events: 事件
selector: 选择器(可选的)
function: 事件处理函数
例如:
$('div').on('click', function(){})
$('div').on('click','.c1',function(){})
2. events(function(){})
events: 事件
function: 事件处理函数
例如:
$('div').click(function(){})
方式一:在标签中写属性的方式绑定 <div id="d1" onclick="changeColor(this);">点我改变背景颜色</div> <script> function changeColor(ths) { ths.style.backgroundColor="green"; } </script> 注意: this是实参,表示触发事件的当前元素。 函数定义过程中的ths为形参。 方式二:通过JS代码绑定 <div id="d2">点我有惊喜</div> <script> var divEle = document.getElementById("d2"); divEle.onclick=function () { alert("惊不惊喜,刺不刺激!"); } </script>
2、示例
1.hover事件示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>hover示例</title> <style> * { margin: 0; padding: 0; } .nav { height: 40px; width: 100%; background-color: #3d3d3d; position: fixed; top: 0; } .nav ul { list-style-type: none; line-height: 40px; } .nav li { float: left; padding: 0 10px; color: #999999; position: relative; } .nav li:hover { background-color: #0f0f0f; color: white; } .clearfix:after { content: ""; display: block; clear: both; } .son { position: absolute; top: 40px; right: 0; height: 50px; width: 100px; background-color: #00a9ff; } .hide { display: none; } </style> </head> <body> <div class="nav"> <ul class="clearfix"> <li>登录</li> <li>注册</li> <li>购物车 <p class="son hide"> 空空如也... </p> </li> </ul> </div> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> $(".nav li").hover( function () { $(this).find(".son").removeClass("hide"); }, function () { $(this).find(".son").addClass("hide"); } ); </script> </body> </html>
2.实时监听input输入值变化示例
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>input事件</title> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> </head> <body> <input type="text" id="i1"> <script> /* * oninput是HTML5的标准事件 * 能够检测textarea,input:text,input:password和input:search这几个元素的内容变化, * 在内容修改后立即被触发,不像onchange事件需要失去焦点才触发 * oninput事件在IE9以下版本不支持,需要使用IE特有的onpropertychange事件替代 * 使用jQuery库的话直接使用on同时绑定这两个事件即可。 * */ $("#i1").on("input propertychange", function () { console.log($(this).val()); }) </script> </body> </html>
三、移除事件
.off( events [, selector ][,function(){}])
.off() 方法移除用 .on()绑定的事件处理程序。
events: 事件
selector: 选择器(可选的)
function: 事件处理函数
四、阻止后续事件执行
1、return false;
2、e.preventDefault();
3、阻止的是有关联的事件,比如阻止表单提交,阻止冒泡事件等
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>阻止后续事件发生</title> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> </head> <body> <form action=""> <input type="text" name="name" id="t"> <input type="submit" value="提交" id="sub"> </form> <script> /*表单的submit会把表单内容提交到action指向的连接 *如果没有设置action的值,则会刷新本页面,即你现在点击提交,会刷新你现在的页面 *也就是说submit是自带了一个事件的,用于表单的提交, *现在我再给submit绑定一个点击事件,判断表单是否为空,如果为空,则阻止提交(阻止submit自带的事件), *即值为空的时候页面不会刷新 * */ $("#sub").on('click', function (e) { var value = $("#t").val().trim(); if (!value) { // 阻止表单的提交 // 阻止后面的事件执行 // e.preventDefault(); return false; } }) </script> </body> </html>
五、冒泡事件
事件冒泡:当一个元素接收到事件的时候 会把他接收到的事件传给自己的父级,一直到window 。
注意这里传递的仅仅是事件,并不传递所绑定的事件函数。所以如果父级没有绑定事件函数,就算传递了事件也不会有什么表现,但事件确实传递了。
很难理解吗?那看看例子吧
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>阻止事件冒泡</title> </head> <body> <div> <p> <button id="b1">点我</button> </p> </div> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> $('div').click(function () { alert('我是div标签'); console.log(this); }); $('p').click(function () { alert('我是一个p标签'); console.log(this); }); $('#b1').click(function () { alert('我是那个按钮!'); console.log(this); }); </script> </body> </html>
解释:此时会弹出三个警告框,因为点击按钮的时候,会把点击事件也传给它的父标签,
一直传到window,而此时父标签p和div也绑定了点击事件,因此也会触发。
那么要想阻止冒泡事件,有两种方式:
1、使用return false,阻止后续事件发生、
2、使用事件的event.stopPropagation()方法,阻止事件冒泡
即在按钮那个事件里面设置:
$('#b1').click(function (e) {
// e在此处是一个形参,表示事件本身,也可以写成eve或者even等
alert('我是那个按钮!');
console.log(this);
e.stopPropagation();
// 阻止后续事件发生也可以达到相同的效果
// return false;
});
六、页面载入
如果你的JS代码写在head标签中,因为浏览器是从上到下执行的,那么你的JS代码就不会生效了,
因为你的JS代码是操作你body里面的标签的,而浏览器读到head的时候已经把JS代码读取了,
但是此时HTML代码还没读取,也就是说,此时你JS代码操作的标签根本就不存在,因此JS代码不会生效。
但是如果我就想把JS代码写在head呢,可以,有两种方式:
1、DOM方法
1.语法
window.onload = function(){你的JS代码}
2. 存在的问题
会等到页面上的文档、图片、视频等所有资源都加载完才会触发
存在覆盖声明的问题
2、jQuery帮我们封装的一个事件
1. 语法
1. $(document).ready(function(){你的JS代码})
2. $(function(){绑定事件的操作...})
2. 优势:
1. 只要文档加载完就会触发
2. 不存在覆盖声明的问题
七、事件委托
事件委托是通过事件冒泡的原理,利用父标签去捕获子标签的事件。
语法:
$("table").on("click", "button", function () {
// JS代码
})
解释:给table绑定一个点击事件,但是是通过button触发的。
注意事项1:
像click、keydown等DOM中定义的事件,我们都可以使用`.on()`方法来绑定事件,但是`hover`这种jQuery中定义的事件就不能用`.on()`方法来绑定了,
也就是说hover()方法不能直接使用事件委托,想使用事件委托的方式绑定hover事件处理函数,可以参照如下代码分两步绑定事件:
$('ul').on('mouseenter', 'li', function() {//绑定鼠标进入事件
$(this).addClass('hover');
});
$('ul').on('mouseleave', 'li', function() {//绑定鼠标划出事件
$(this).removeClass('hover');
});
注意事项2
关于this:谁触发这个事件,this就指向谁。
例如:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> </head> <body> <div id="div"> <p id="p"> <input type="button" value="点我" id="btn"> </p> </div> <script type="text/javascript"> $("#div").click(function () { //点击按钮,经过事件冒泡,触发这个事件 //此时this是代表div的,虽然点击的是那个按钮 //但是实际上是经过冒泡后,div自己触发的这个事件,所有this是div console.log(this); }); //任意注释一个script标签测试另一个标签 $("#div").on("click", "#btn", function () { //事件委托,给div绑定了一个事件,点击按钮触发这个事件 //此时this是代表按钮btn的,虽然绑定的事件是div //但是触发这个事件的是btn,所以this是btn console.log(this); }) </script> </body> </html>
八、动画效果
// 基本
s是毫秒
show([s,[e],[fn]])
hide([s,[e],[fn]])
toggle([s],[e],[fn])
// 滑动
slideDown([s],[e],[fn])
slideUp([s,[e],[fn]])
slideToggle([s],[e],[fn])
// 淡入淡出
fadeIn([s],[e],[fn])
fadeOut([s],[e],[fn])
fadeTo([[s],o,[e],[fn]])
fadeToggle([s,[e],[fn]])
// 自定义(了解即可)
animate(p,[s],[e],[fn])
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>点赞动画示例</title> <style> div { position: relative; display: inline-block; cursor: pointer; } div > i { display: inline-block; color: red; position: absolute; right: -16px; top: -5px; opacity: 1; } </style> </head> <body> <div id="d1">点赞</div> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> $("#d1").on("click", function () { var newI = document.createElement("i"); newI.innerText = "+1"; $(this).append(newI); $(this).children("i").animate({ // 在1秒内透明度变成0 opacity: 0 }, 1000) }) </script> </body> </html>
九、拓展 1、each 方式一:循环可迭代对象 jQuery.each(collection, callback(indexInArray, valueOfElement)) jQuery.each(可迭代对象, 函数(索引, 值)) -->类似于python内置函数sorted那种类型 描述:一个通用的迭代函数,它可以用来无缝迭代对象和数组。 数组和类似数组的对象通过一个长度属性(如一个函数的参数对象)来迭代数字索引,从0到length - 1。其他对象通过其属性名进行迭代。 例如: li =["a","b","c","d"] $.each(li,function(i, v){ console.log(i, v);//i是索引,v是每次循环的具体元素。 }) 输出: 0"a" 1"b" 2"c" 3"d" li =["a","b","c","d"] $.each(li,function(i, v){ if (i === 2){ return false; // 相当于break } console.log(i, v); }) 输出: 0"a" 1"b" li =["a","b","c","d"] $.each(li,function(i, v){ if (i === 2){ return; // 相当于continue } console.log(i, v); }) 输出: 0"a" 1"b" 3"d" d = {"name": "ming", "age": 18}
$.each(d,function(k,v){
console.log(k,v) // k是对象的键,v是对象的值
})
"name" "ming"
"age" 18 方式二:循环节点 somenode.each(function(index, Element)) 描述:遍历一个jQuery对象,为每个匹配元素执行一个函数。 .each() 方法用来迭代jQuery对象中的每一个DOM元素。每次回调函数执行时,会传递当前循环次数作为参数(从0开始计数)。 由于回调函数是在当前DOM元素为上下文的语境中触发的,所以关键字 this 总是指向这个元素。 例如: // 为每一个li标签添加一个样式 $("li").each(function(){ $(this).addClass("c1"); }); 注意: jQuery的方法返回一个jQuery对象,遍历jQuery集合中的元素 - 被称为隐式迭代的过程。当这种情况发生时,它通常不需要显式地循环的 .each()方法 也就是说,上面的例子没有必要使用each()方法,直接像下面这样写就可以了: $("li").addClass("c1"); // 对所有标签做统一操作 2、data
data详情 在匹配的元素集合中的所有元素上存储任意相关数据或返回匹配的元素集合中的第一个元素的给定名称的数据存储的值。 1.设置数据(可以存储任意的值,包括对象) somenode.data(key, value): 描述:在匹配的元素上存储任意相关数据。 $("div").data("age",100); //给所有div标签都保存一个数据,名为age,值为100,即:data-age=100 2.取值 somenode.data(key) 描述: 返回匹配的元素集合中的第一个元素的给定名称的数据存储的值 $("div").data("k"); //返回第一个div标签中保存的"k"的值 $("div").data(); //返回div标签中保存的所有的值 3.删除值 somenode.removeData(key): 描述:移除存放在元素上的数据,不加key参数表示移除所有保存的数据。 $("div").removeData("k"); //移除元素上存放k对应的数据 3、插件 语法:jQuery.extend(object) 给jQuery添加自定义的方法(扩展后jQuery就拥有了此方法): $.extend({ nb:function(){ console.log("RNG牛逼!") } }); $.nb(); 给jQuery对象添加自定义的方法(扩展后所有对象都能用此方法): $.fn.extend({ znb:function(){ console.log("RNG真牛逼!") } }); $("div").znb(); 十、示例 1、表格的新增和删除(事件委托)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .cover { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0, 0, 0, 0.3); z-index: 99; } .modal { width: 300px; height: 200px; background-color: white; position: absolute; top: 50%; left: 50%; margin-top: -100px; margin-left: -150px; z-index: 1000; } .hide { display: none; } </style> </head> <body> <button id="add">新增</button> <table border="1"> <thead> <tr> <th>#</th> <th>姓名</th> <th>爱好</th> <th>操作</th> </tr> </thead> <tbody> <tr> <td><input type="checkbox"></td> <td>小明</td> <td>开车</td> <td> <button class="fire">开除</button> </td> </tr> <tr> <td><input type="checkbox"></td> <td>小红</td> <td>化妆</td> <td> <button class="fire">开除</button> </td> </tr> <tr> <td><input type="checkbox"></td> <td>小东</td> <td>吃吃吃</td> <td> <button class="fire">开除</button> </td> </tr> </tbody> </table> <div class="cover hide"></div> <div class="modal hide"> <div> <label>姓名: <input type="text" id="name"> </label> </div> <div> <label>爱好: <input type="text" id="hobby"> </label> </div> <button id="cancel" type="button">取消</button> <button id="submit" type="button">提交</button> </div> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> // 定义一个清空输入框并且隐藏模态框的方法 function hideModal(){ // 1. 清空input的值 $("#name,#hobby").val(''); // 2. 隐藏起来 $(".cover,.modal").addClass('hide'); } // 开除按钮的功能(事件委托) $("table").on('click', '.fire', function () { // 点击开除按钮要做的事儿 // 把当前行移除掉 //this --> 触发当前点击事件的DOM对象 $(this).parent().parent().remove(); // 链式操作 }); // 新增按钮的功能 $("#add").click(function () { // 点击新增按钮要做的事儿 // 1. 移除cover和modal的hide样式 $(".cover,.modal").removeClass('hide'); }); // 点击modal中的cancel按钮 $("#cancel").click(function () { hideModal(); }); // 点击modal中的submit按钮 $("#submit").click(function () { // 1. 获取用户输入的值 var name = $("#name").val(); var hobby = $("#hobby").val(); // 2. 隐藏模态框,清空输入框 hideModal(); // 3. 创建一个tr标签,把数据添加进去 var trEle = document.createElement("tr"); // 直接append HTML内容 $(trEle).append('<td><input type="checkbox"></td>'); $(trEle).append('<td>' + name + '</td>'); // 创建td标签 var tdTmp = document.createElement('td'); // 设置td标签的文本内容 tdTmp.innerText = hobby; // 把创建的td标签追加到tr里面 $(trEle).append(tdTmp); // 直接append HTML内容 $(trEle).append('<td><button class="fire">开除</button></td>') // 4. 把上一步的tr追加到表格的tbody后面 $('tbody').append(trEle); }); </script> </body> </html>
2、批量操作示例
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>批量操作</title> </head> <body> <table border="1"> <thead> <tr> <th>#</th> <th>姓名</th> <th>操作</th> </tr> </thead> <tbody> <tr> <td><input type="checkbox"></td> <td>小明</td> <td> <select> <option value="1">上线</option> <option value="2">下线</option> <option value="3">隐身</option> </select> </td> </tr> <tr> <td><input type="checkbox"></td> <td>小红</td> <td> <select> <option value="1">上线</option> <option value="2">下线</option> <option value="3">隐身</option> </select> </td> </tr> <tr> <td><input type="checkbox"></td> <td>小白</td> <td> <select> <option value="1">上线</option> <option value="2">下线</option> <option value="3">隐身</option> </select> </td> </tr> <tr> <td><input type="checkbox"></td> <td>小花</td> <td> <select> <option value="1">上线</option> <option value="2">下线</option> <option value="3">隐身</option> </select> </td> </tr> <tr> <td><input type="checkbox"></td> <td>小狗</td> <td> <select> <option value="1">上线</option> <option value="2">下线</option> <option value="3">隐身</option> </select> </td> </tr> </tbody> </table> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> var flag = false; // shift被按下,就将全局的flag置为true $(window).keydown(function (e) { // shift键的代码编号是16 if (e.keyCode === 16){ flag = true; } }); // shift键被放开的时候,就将全局的flag置为false $(window).keyup(function (e) { if (e.keyCode === 16){ flag = false; } }); // 按下shift键,进入批量编辑模式,且操作的是被选中的项 // 给select标签绑定change事件 $('td>select').change(function () { // 判断是否进入批量编辑模式 // 判断checkbox的状态 var isChecked = $(this).parent().prev().prev().find(':checkbox').prop('checked'); // flag为true且checkbox是被选中的状态 if ( flag && isChecked){ // 1. 取到当前select选中的值 var checkedValue = $(this).val(); // 2. 找到所有被选中的行 // 3. 把选中行的select置为一样的值 $('tr:has(input:checked)').find('select').val(checkedValue); } }) </script> </body> </html>