在前面一章我们已经点到过,很多的情况我们都是通过JQuery来对标签进行操作的,在这一章我们就来好好讲一讲这个JQuery。
JQuery初识
先看看JQuery的使用
JQuery的特点:
- 可以用及其简练的语言来做JS做的事情(write less,do more)
- JQuery就是一个JS文件,相当于一个Python的第三方模块,直接拿过来用就可以了(但是需要按照要求的规则)。但是原生的JS DOM是基础,其实还是通过这些基础来实现所有的操作。
- 我们要学习的,JQuery最常用的方向,也就是改变标签的属性、样式和事件相关的一系列操作。
JQuery的基础语法
JQuery的语法还是比较简单的,只有一句必须要掌握的
$(selector).action()
前面的selector就相当于一个标签选择器,后面的action就是相对应的操作
标签选择器
id选择器
$("#id")
标签选择器
$("tagName")
class选择器
$(".className")
所有元素选择器
$("*")
选择器的配合使用
$("tagName.className") //两个条件一定不能加空格,要紧挨着,加了空格就有层级的效果,下面会讲到
组合选择器
同时符合多个条件
$("condition1,condition2...")
练习题
结合上面的各种基本组合器看看下面的方法应该怎么实现
找到本页面中id是i1的标签 找到本页面中所有的h2标签 找到本页面中所有的input标签 找到本页面所有样式类中有c1的标签 找到本页面所有样式类中有btn-default的标签 找到本页面所有样式类中有c1的标签和所有h2标签 找到本页面所有样式类中有c1的标签和id是p3的标签 找到本页面所有样式类中有c1的标签和所有样式类中有btn的标签
$("#i1") $("h2") $("input") $(".c1") $(".btn-default") $(".c1,h2") $(".c1,#p3") $(".c1,.btn")
结论
注意上面的结论里的逗号,是没有空格分割的。
层级选择器:
下面的x和y可以是任意一种选择器
$("x y"); //x内所有的后代y $("x > y"); //x的所有直系y $("x + y"); //所有紧挨着x后面的y $("x ~ y"); //x之后所有的兄弟级y
再看看案例
找到本页面中form标签中的所有input标签 找到本页面中被包裹在label标签内的input标签 找到本页面中紧挨在label标签后面的input标签 找到本页面中id为p2的标签后面所有和它同级的li标签
$("form input") $("label > input") $("label + input") $("#p2 ~ li")
基本筛选器
我们还可以对找到的标签进行再一次的筛选,筛选器的方法如下
:first //第一个 :last //最后一个 :eq(index) //索引等于index的元素 :even //匹配所有索引值为偶数的元素 :odd //匹配所有索引值为奇数的元素 :gt(index) //匹配所有索引值大于index的元素 :lt(index) //匹配所有索引值小于index的元素 :not(选择器) //匹配所有满足not条件的标签 :has(选择器) //匹配所有包含一个或多个标签在其内的标签(从后代里找)
要注意一个用法,eq(index)里的值是可以是负数的,负数就是从最后一个开始算的,和列表切片一样。
奇偶数索引最常见的一个使用方面就是那种有颜色差的表格标签
属性选择器
[attribute] [attribute = value] //属性等于 [attribute != value] // 属性不等于
属性选择器主要是对有属性的标签进行筛选,看看下面的例子
//找到#d3内有value属性的标签 $("#d3 input[value]") //找到id为d3内所有checkbox标签 $("#d3 input[type=‘checkbox‘]") //找到value值为1的input标签 $("input[value = ‘1‘]") //找到value值不为2的标签 $("input[value != ‘2‘]")
表单选择器
可以找到下面各种input类型或表单相关按钮的标签
:text :password :file :radio :checkbox :submit :reset :button
所以,也可以通过上面的方法直接找到相应的标签
//找到id为d3内所有checkbox标签 $("#d3 :checkbox")
表单对象属性
:enabled :disabled :checked :selected
结合上面各种筛选器看一看下面的案例
找到id值为f1的标签内部的第一个input标签 找到id值为my-checkbox的标签内部最后一个input标签 找到id值为my-checkbox的标签内部没有被选中的那个input标签 找到所有含有input标签的label标签
$("#f1 input:first") $("#my-checkbox input:last") $("#my-checkbox input:not(:checked)") $("label:has(input)")
JQuery对象和DOM对象
我们在前面一章里讲了DOM对象的用法,这一章将了JQuery对象的用法,他们两个是可以直接互相转换的
var i1ELe = document.getElementById("i1"); //DOM对象 var $i1Ele = $("#i1") //JQuery对象(数组) var i1Ele2 = $i1Ele[0] //数组索引就是DOM对象 var $ieEle2 = $(i1ELe) //DOM对象转换为jQuery对象
这就导致了一个问题(其实也不是问题):在一个页面里一个变量可能是DOM对象,也有可能是JQuery对象,为了直观,我们一般把JQuery的变量用$符号作为前缀。
JQuery对象的方法
找到某个元素后面某个(或多个)元素
$("#id").next() //id元素后下一个元素 $("#id").nextAll() //id元素后所有的元素(不包括id) $("#id").nextUntil("#id2") //id值id2之间所有元素
注意最后一个until的方法是不包括id和id2两个元素的。
找到某个元素前面某个(或多个)元素
$("#id").prev() //id元素前一个元素 $("#id").prevAll() //id元素之前所有的元素(不包括id) $("#id").prevUntil("#id2") //id值id2之间所有元素
找父级标签
$("#id").parent() //支持链式操作 $("#id").parent().parent().parent() $("#id").parents() //找到当前元素所有的父辈元素 $("#id").parentsUntil() //找到当前元素的所有父辈元素直至匹配到某个元素
子级元素和兄弟元素
$("#id").children() //子级所有元素 $("#id").siblings() //兄弟级所有元素
直接查找元素
这个方法是找出正在处理的元素的后代元素的好方法,
$("#id").find()
有些类似前面筛选器的用法,但是有些时候JQuery对象是别人传过来的,这时候在操作就要靠这个方法了。比如我们要找一个div下的class为c1的对象,可以直接找
$("div.c1")
但是有些情况下第一步查找div的过程不是我们自己做的或者是从别的变量里传过来的,那么就只能用这个方法了
$(‘div‘).find(‘.c1‘)
所以两个方法效果是一样的,但是使用环境不太一样。
补充方法
还有几个补充的方法,效果和前面的基本筛选器差不多,也是使用环境有些许的差别,只看名字就知道用途了,不再具体说明。
$("#id‘).first() $("#id‘).last() $("#id‘).not() $("#id‘).has()
标签操作
class操作
$(‘#id‘).addClass(‘classname‘) $(‘#id‘).removeClass(‘classname‘) $(‘#id‘).toggleClass(‘classname‘)
CSS样式操作
$(‘.c1‘).css(‘background-color‘,‘blue‘)
回顾一下原生的DOM里是怎么写的?可别忘记了!
.style.color=‘green‘
如果是多个CSS修改,是可以用键值对的方式来进行操作的,所以下面两个方式的效果是一样的
$(this).css(‘color‘,‘green‘) $(this).css(‘font-size‘,‘20px‘) (this).css({"color":"green","font-size":"20px"})
位置操作
offset() //获取匹配元素在当前窗口的相对偏移或设置元素的位置 position() //获取匹配元素相对父元素的偏移 scrollTop()//获取匹配元素相对滚动条顶部的偏移 scrollLeft()//获取匹配元素相对滚动条左侧的偏移
其中,offset()方法允许我们检索一个元素相对于文档document的当前位置,和position()的差别在于后者是相对于父级元素的位移。
offset()的返回值是个object对象
{top: 0, left: 0}
$(window).scrollTop()可以返回一个值,是右侧滚动条滚动的值,并且赋值0可以使滚动条返回顶部。
$(window).scrollTop(0)
我们还可以通过给函数赋值来实现移动控件的效果
$(‘.c1‘).offset({top:500,left:100})
放个案例,一个按钮一个红色的div,每点一次按钮div的方块向左下移动50
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>坐标系</title> <style> .c1{height: 100px; width: 200px; background-color: red; } * { margin: 0; padding:0; } </style> </head> <body> <div class="c1" >div1</div> <input type="button" onclick="fun();" value="点击!!!"> <script src="jquery-3.2.1.min.js"></script> <script> function fun(){ console.log(123); $div1Ele = $(‘.c1‘); pos = $div1Ele.offset(); var newLeft = pos[‘left‘]+50; var newTop = pos[‘top‘]+50; $div1Ele.offset({top:newLeft,left:newLeft}); } </script> </body> </html>
案例
还有一个案例:经常会看到页面底部有个按钮,每次点击的时候可以返回页面顶部
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>返回顶部示例</title> <style> .c1{height: 100px;} .hide{ display: none; } .fixBtn{ position: fixed; bottom: 50px; right: 50px; width: 200px; height: 100px; background-color: brown; } </style> </head> <body> <input type="button" name="" id="b1" class="fixBtn hide" value="返回顶部"> <div> <div class="c1">1</div> <div class="c1">2</div> <div class="c1">3</div> <div class="c1">4</div> <div class="c1">5</div> <div class="c1">6</div> <div class="c1">7</div> <div class="c1">8</div> <div class="c1">9</div> <div class="c1">10</div> <div class="c1">11</div> <div class="c1">12</div> <div class="c1">13</div> <div class="c1">14</div> <div class="c1">15</div> <div class="c1">16</div> <div class="c1">17</div> <div class="c1">18</div> <div class="c1">19</div> <div class="c1">20</div> <div class="c1">21</div> <div class="c1">22</div> <div class="c1">23</div> <div class="c1">24</div> <div class="c1">25</div> <div class="c1">26</div> <div class="c1">27</div> <div class="c1">28</div> <div class="c1">29</div> <div class="c1">30</div> <div class="c1">31</div> <div class="c1">32</div> <div class="c1">33</div> <div class="c1">34</div> <div class="c1">35</div> <div class="c1">36</div> <div class="c1">37</div> <div class="c1">38</div> <div class="c1">39</div> <div class="c1">40</div> <div class="c1">41</div> <div class="c1">42</div> <div class="c1">43</div> <div class="c1">44</div> <div class="c1">45</div> <div class="c1">46</div> <div class="c1">47</div> <div class="c1">48</div> <div class="c1">49</div> <div class="c1">50</div> <div class="c1">51</div> <div class="c1">52</div> <div class="c1">53</div> <div class="c1">54</div> <div class="c1">55</div> <div class="c1">56</div> <div class="c1">57</div> <div class="c1">58</div> <div class="c1">59</div> <div class="c1">60</div> <div class="c1">61</div> <div class="c1">62</div> <div class="c1">63</div> <div class="c1">64</div> <div class="c1">65</div> <div class="c1">66</div> <div class="c1">67</div> <div class="c1">68</div> <div class="c1">69</div> <div class="c1">70</div> <div class="c1">71</div> <div class="c1">72</div> <div class="c1">73</div> <div class="c1">74</div> <div class="c1">75</div> <div class="c1">76</div> <div class="c1">77</div> <div class="c1">78</div> <div class="c1">79</div> <div class="c1">80</div> <div class="c1">81</div> <div class="c1">82</div> <div class="c1">83</div> <div class="c1">84</div> <div class="c1">85</div> <div class="c1">86</div> <div class="c1">87</div> <div class="c1">88</div> <div class="c1">89</div> <div class="c1">90</div> <div class="c1">91</div> <div class="c1">92</div> <div class="c1">93</div> <div class="c1">94</div> <div class="c1">95</div> <div class="c1">96</div> <div class="c1">97</div> <div class="c1">98</div> <div class="c1">99</div> <div class="c1">100</div> </div> <script src="jquery-3.2.1.min.js"></script> <script> $(window).scroll(function(){ if($(window).scrollTop()>100){ $(‘#b1‘).removeClass(‘hide‘) } }) $(‘#b1‘).click(function(){ if($(window).scrollTop()>100){ $(window).scrollTop(0); $(‘#b1‘).addClass(‘hide‘) } }) </script> </body> </html>
返回顶部按钮
尺寸使用
下面的方法是对标签尺寸进行设置的
height() //内容区的高度 width() //内容区的宽度 innerHeight() //内容区加padding的高度 innerWidth() //内容区加padding的宽度 outerHeight() //内容区加padding加border的高度 outerWidth() //内容区加padding加border的宽度
文本操作
html代码
html() html(‘str‘)
html()方法是获取JQuery对象第一个元素的html标签里夹着的字符,注意是第一个元素,也就是说下面的方法效果一样
$(‘div‘)[0].innerText $(‘div‘).html
但是上面的第一个方法是原生的DOM方法,而下面的用法是JQuery的方法。
而带参数的html()方法是可以直接传个标签的html字符串的。和DOM原生的innerHTML一样。
$(‘div‘).html("<a href=‘http://www.baidu.com‘>搜索</a>")
文本值
text() //获取所有匹配元素的内容 text(val)//设置所有匹配元素的内容
值
val() //获得第一个匹配元素的当前值 val(val)//设置所有匹配元素的值 val([val1,val2)//设置多选的checkbox,select的值
我们还结合以前那个注册界面的案例来试一下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=s, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>文档操作</title> </head> <body> <script src="jquery-3.2.1.min.js"></script> <form action=""> <p> <label for="">用户名: <input type="text" id="userID"> </label> </p> <p> <label for="">密码: <input type="password" id="pwd"> </label> </p> <p>爱好 <input type="checkbox" name=‘hobby‘ value="football">足球 <input type="checkbox" name="hobby" value="basketball">篮球 <input type="checkbox" name="hobby" value="pingpang">乒乓球 </p> <p>性别: <label for="">男 <input type="radio" name="gender" value="1"> </label> <label for="">女 <input type="radio" name="gender" value="0"> </label> </p> <p> <label for="">籍贯 <select name="from" id="s1"> <option value="010">北京</option> <option value="021">上海</option> <option value="020">广州</option> </select> </label> </p> <p> <label for="t1">其他</label> <textarea name="memo" id="t1" cols="30" rows="10"></textarea> </p> <p> <input type="submit" value="确认"> <input type="button" value="取消"> </p> </form> </body> </html>
注册界面
如果我们用val()方法的话
$(‘:checkbox:checked‘).val()
这里用了伪装态checked,来取选中的多选框
但是返回的只有第一个被选中的对象的文本:football,所以这里索取值的方法索取的都是对象组里的第一个对象对应的值。如果想索引出所有的值,就要用for循环一次索引
var $checkedEles = $(‘:checkbox:checked‘) for (var i=0;i<$checkedEles.length;i++){console.log($($checkedEles[i]).val())}
注意第二行代码里用$($checkedEles[i]),因为我们对JQuery对象进行索引后就成了DOM对象,调用val()方法的时候必须是JQuery对象,所以要用$符进行转换。
而select标签在多选的情况下用val()的返回值是一个列表,如果我们把上面的#s1对象对应的代码改成下面这样
<select name="from" id="s2" multiple=‘multiple‘> <option value="010">北京</option> <option value="021">上海</option> <option value="020">广州</option> <option value="0755">深圳</option> </select>
然后就可以用下面的方法来索引值了(这里是不用加checked这个状态来表明选中的!)
$(‘#s1‘).val() //返回值"010" $(‘#s2‘).val() //返回值["010", "021", "0755"]
当然我们也可以通过对方法赋值来改变页面的选择状态
$(‘#s1‘).val(‘020‘) $(‘#s2‘).val([‘020‘,‘0755‘])
这里放个案例,登录框的校验:如果用户名或密码为空就在相对应的框旁边弹出提示:密码或用户名不能为空
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=s, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>文档操作</title> <style> .error{ color:red } </style> </head> <body> <script src="jquery-3.2.1.min.js"></script> <form action=""> <p> <label for="">用户名: <input type="text" id="userID" class="notnone"> <span class="error"></span> </label> </p> <p> <label for="">密码: <input type="password" id="pwd" class="notnone"> <span class="error"></span> </label> </p> <p>爱好 <input type="checkbox" name=‘hobby‘ value="football">足球 <input type="checkbox" name="hobby" value="basketball">篮球 <input type="checkbox" name="hobby" value="pingpang">乒乓球 </p> <p>性别: <label for="">男 <input type="radio" name="gender" value="1"> </label> <label for="">女 <input type="radio" name="gender" value="0"> </label> </p> <p> <label for="">籍贯 <select name="from" id="s1"> <option value="010">北京</option> <option value="021">上海</option> <option value="020">广州</option> </select> </label> </p> <p> <label for="t1">其他</label> <textarea name="memo" id="t1" cols="30" rows="10"></textarea> </p> <p> <input type="submit" value="确认" id="logbtn"> <input type="button" value="取消"> </p> </form> <script> $(‘#logbtn‘).click(function(){ var $notNoneElem = $(‘.notnone‘); for(var i=0;i<$notNoneElem.length;i++){ if ($($notNoneElem[i]).val().trim().length === 0) { var labelName = $($notNoneElem[i]).parent().text().trim().slice(0,-1); console.log(labelName) $($notNoneElem[i]).next().text(labelName+‘不能为空!‘) } } return false; }) </script> </body> </html>
登录框校验
这里只用了输入框为空的校验,其实真实情况下还是有很多种的。
要注意的几点:
1.用的登录按钮是submit,本身是带有事件的,在函数内添加了返回值false,就是如果符合判定情况(文本框为空)就直接截断不进行后面的提交事件。这个在后面讲事件的时候会讲到。
2.用到了JQuery对象的父级搜索、下一个对象的选取等方法。
属性操作
用ID等或自定义属性
attr(attrName) //返回第一个匹配元素的属性值 attr(attrName,attrValue) //为所有匹配的元素设置一个属性值 attr(k1:v1,k2,v2) //为匹配元素设置多个属性值 removeAttr() //从匹配每一个的元素中删除一个属性
比方我们有个id为id1的input,类型为text,我们可以用下面的方法来实现属性的获取和更换
$(‘#id1‘).attr(‘type‘) $(‘#id1‘).attr(‘type‘,‘password‘)
用于checkbox和radio的属性
我们还可用下面的方法来返回一个布尔量的值
prop() //获取属性 removeProp() //返回属性
比方我们有个checkbox,id为ckb1,可以用下面的方法来判定其是否被选中
$(‘#ckb1‘).prop(‘checked‘)
还可以将其赋值个布尔量来改变选中状态
$(‘#ckb1‘).prop(‘checked‘,false)
有个要注意的点:在1.x和2.x版本的JQuery中使用attr对checkbox进行赋值时会出现bug,在JQuery3.x版本就没有这个问题了。为了兼容性,我们在处理checkbox和radio的时候尽量使用特定的prop(),而不要使用attr(‘checked‘,‘checked‘)
案例
用三个按钮来几个checkbox进行全选,取消和反选的功能实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <table border="1px"> <thead> <tr> <th>#</th> <th>姓名</th> <th>年龄</th> </tr> </thead> <tbody> <tr> <td><input type="checkbox" name="" id="c1"></td> <td>张三</td> <td>10</td> </tr> <tbody> <tr> <td><input type="checkbox" name="" id=""></td> <td>李四</td> <td>10</td> </tr> <tr> <td><input type="checkbox" name="" id=""></td> <td>王五</td> <td>10</td> </tr> </tbody> </table> <input type="button" id="b1" value="全选"> <input type="button" id="b2" value="取消"> <input type="button" id="b3" value="反选"> <script src="jquery-3.2.1.min.js"></script> <script> var $chkelems = $(‘input:checkbox‘); console.log($chkelems); $(‘#b1‘).click(function(){ for(var i=0;i<$chkelems.length;i++){ $($chkelems[i]).prop(‘checked‘,true); } }) $(‘#b2‘).click(function(){ for(var i=0;i<$chkelems.length;i++){ $($chkelems[i]).prop(‘checked‘,false); } }) $(‘#b3‘).click(function(){ for (var i=0;i<$chkelems.length;i++) { if (($($chkelems[i])).prop(‘checked‘)) { $($chkelems[i]).prop(‘checked‘,false); } else { $($chkelems[i]).prop(‘checked‘,true); } } }) </script> </body> </html>
全选、反选和取消
文档处理
内部添加
追加到指定元素内部的后面
$(A).append(B) //把B追加给A $(A).appendTo(B)//把A追加到B
添加到指定元素内部的前面
$(A).prepend(B) //把B前置到A内 $(A).prependTo(B) //把A前置到B内
举个例子,一个ul,id为u1列表里有1-5一共5个li标签
然后要新建一个li标签变量,并把内部值赋值为0
var liELe = document.createElement(‘li‘) liELe.innerText = ‘0‘
下面的几段代码就有不同的结论
$(‘#u1‘).append(liEle) //1 $(‘#u1‘).prepend(liEle) //2 $(liEle).appendTo(‘#u1‘) //3 $(liEle).prependTo(‘#u1‘) //4
外部添加
添加到指定元素外部的后面
$(A).after(B) //把B放在A的后面 $(a).insertAfter(B) //把A放在B的后面
添加到指定元素外部的前面
$(A).before(B) //把B放在A的前面 $(a).insertBefore(B) //把A放在B的前面
用法和效果和上面的内部添加一样,就不再演示了。
移除和清空
remove() //从DOM中删除所有匹配的元素 empty() //删除所有匹配的元素集合中的所有子节点
两个还是有些区别的,就以前面的ui标签为例子,
$(‘#u1‘).remove()
是把u1和里面的li全部删除了
$(‘#u1‘).empty()
是只删除u1里面所有的li,而保留u1。
案例
需求:一个表格标签,下面放一个按钮,每点一次按钮添加一组数据。表格最后一列每行有个按钮,点击该按钮删除改行数据(有bug版,在下一小节会解决)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <table border="1"> <thead> <th>编号</th> <th>姓名</th> <th>爱好</th> <th>操作</th> </thead> <tbody> <tr> <td>1</td> <td>张三</td> <td>足球</td> <td><button class="delLine">删除</button></button> </tr> <tr> <td>2</td> <td>李四</td> <td>篮球</td> <td><button class="delLine">删除</button></button> </tr> <tr> <td>3</td> <td>张三</td> <td>看书</td> <td><button class="delLine">删除</button></button> </tr> </tbody> </table> <button id="btn1">添加数据</button> <script src="jquery-3.2.1.min.js"></script> <script> $(‘#btn1‘).click(function(){ var trEle=document.createElement(‘tr‘); // $(trEle).html( // ‘<td>4</td><td>王五</td><td>阅片</td>‘ // ); trEle.innerHTML = ‘<td>4</td><td>王五</td><td>阅片</td>‘+ ‘<td><button class="delLine">删除</button></button>‘ $(‘tbody‘).append(trEle); }) $(‘.delLine‘).click(function(){ $(this).parent().parent().remove() }) </script> </body> </html>
按钮对表格进行增删操作
替换操作
$(A).replaceWith(B) //用B替换符合A的所有元素 replaceAll()
克隆操作
$(A).clone() //复制标签本身 $(A).clone(true)//复制标签(包括原标签的事件)
事件操作
常用事件
先看看JQuery里定义的几种常用事件
click //点击 hover //鼠标指向 focus //获取焦点 blur //失去焦点 change//发生变化 keyup//键盘弹起
绑定事件
目前为止我们已经了解了下面几种绑定事件的方式:
- 在标签里写事件和对应的函数:onclick=fun(this)
- 在原生的DOM里用过JS绑定:DOM对象.onclick=function(){}
- jQuery版的绑定事件:JQuery对象.click(function(){})
以后我们要下面的这种JQuery的绑定事件的方式
JQuery对象.on("click",function(){})
JQuery对象.on("click","选择器",function(){})
用这个方法最大的效果(也可以说是不同的地方)是可以对未来生成的元素(页面生成的时候还没有的标签)也绑定事件,也就是事件委托。
我们拐回去看一看前面那个按钮对表格进行增删操作的例子,会发现有个bug:对新增的行内的按钮进行点击操作是没有事件发生的。因为前面说的几种事件的绑定方式未能对未来式生成的元素进行事件绑定。而这里还有个知识点:事件冒泡和事件捕获
如果有一个事件为发生后没有绑定相关操作,该事件就会被父级元素捕获,如果父级元素也未对其响应,就会被传递给父级的父级元素,以此类推,这几时事件冒泡。所以就要对上面的例子加以修改(这里只放出来按钮绑定事件的部分)
$(‘tbody‘).on(‘click‘,‘.delLine‘,function(){ $(this).parent().parent().remove() })
因为tbody元素是从页面刷新就存在的,所以我们就给他绑定事件。但是也不能直接用html标签来绑,因为那样太宽泛,程序的响应会慢得多。
注意注意!
像click、keydown等DOM中定义的事件,我们都可以使用on的方法来绑定,但是‘hover’这种JQuery中定制的事件就不能用on方法来绑定,因为hover是鼠标移标移除两个事件组成的,我们要参照下面的方式操作
$(‘ul‘).on(‘mouseenter‘,‘li‘,function(){//绑定鼠标进入事件 $(this).addClass(‘hover‘); }); $(‘ul‘).on(‘mouseleave‘,‘li‘,function(){//绑定鼠标移出事件 $(‘this‘).addClass(‘hover‘); });
移除事件
对于上面用on方法绑定的事件可以用下面的方式来移除
$(selector).off(event,selector,function(eventObj),map)
这个方法用的比较少,我们知道就可以了。
阻止后续事件执行
有些时候我们需要函数中加上一个类似中断的效果,就像前面登录校验的例子,阻止submit按钮提交表单,就要在要中断的地方加一个返回值
return false;
程序走到这一步就会阻止后续事件的执行。
所以这里就需要对上面那个登录校验的代码修改一下,因为上面那个方法是没有办法提供submit方法的,直接就通过false阻止了后面的submit事件,最简单的方法就是加个标志位flag,对flag进行赋值然后返回
$(‘#logbtn‘).click(function(){ var $notNoneElem = $(‘.notnone‘); var returnFlag = true for(var i=0;i<$notNoneElem.length;i++){ if ($($notNoneElem[i]).val().trim().length === 0) { var labelName = $($notNoneElem[i]).parent().text().trim().slice(0,-1); console.log(labelName) $($notNoneElem[i]).next().text(labelName+‘不能为空!‘) returnFlag = false; break; } } return returnFlag;
用上面的方法就行了。
例子
需求:用shift键实现批量效果
把前面的那个表格修改一下,把最后一列的按钮改成下拉列表
如果前面的复选框被选中,那么按下ctrl键时可以批量修改状态。也可以独立修改每行的下拉列表内容。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <table border="1"> <thead> <th>#</th> <th>姓名</th> <th>爱好</th> <th>操作</th> </thead> <tbody> <tr> <td><input type="checkbox" name="" id=""></td> <td>张三</td> <td>足球</td> <td> <select name="" id=""> <option value="0">在线</option> <option value="1">隐身</option> <option value="2">下线</option> </select> </td> </tr> <tr> <td><input type="checkbox" name="" id=""></td> <td>李四</td> <td>篮球</td> <td> <select name="" id=""> <option value="0">在线</option> <option value="1">隐身</option> <option value="2">下线</option> </select> </td> </tr> <tr> <td><input type="checkbox" name="" id=""></td> <td>张三</td> <td>看书</td> <td> <select name="" id=""> <option value="0">在线</option> <option value="1">隐身</option> <option value="2">下线</option> </select> </td> </tr> <tr> <td><input type="checkbox" name="" id=""></td> <td>张三</td> <td>看书</td> <td> <select name="" id=""> <option value="0">在线</option> <option value="1">隐身</option> <option value="2">下线</option> </select> </td> </tr><tr> <td><input type="checkbox" name="" id=""></td> <td>张三</td> <td>看书</td> <td> <select name="" id=""> <option value="0">在线</option> <option value="1">隐身</option> <option value="2">下线</option> </select> </td> </tr><tr> <td><input type="checkbox" name="" id=""></td> <td>张三</td> <td>看书</td> <td> <select name="" id=""> <option value="0">在线</option> <option value="1">隐身</option> <option value="2">下线</option> </select> </td> </tr> </tbody> </table> <button id="btn1">添加数据</button> <script src="jquery-3.2.1.min.js"></script> <script> var mode = false; //全局变量mode,ctrl键按下时为true var $bodyELe = $(‘body‘) //绑定ctrl键按下时的事件 $bodyELe.on(‘keydown‘,function(evt) { console.log(evt.keyCode); if(evt.keyCode===17) //ctrl键键码为17 {mode = true;} }); //绑定ctrl键松开时的事件 $bodyELe.on(‘keyup‘,function(evt) { if(evt.keyCode === 17) {mode = false;} }); $bodyELe.on(‘change‘,‘select‘,function(){ var getvalue = $(this).val(); //获取下拉列表改变后的值 //获取变化下拉框对应checkbox var $getckb = $(this).parent().siblings().first().find(":checkbox"); //进入真正的批量操作模式 if($getckb.prop(‘checked‘) && mode){ var $checkedEles = $("input[type=‘checkbox‘]:checked"); // $("input[type=‘checkbox‘]:checked") console.log($checkedEles) for(var i=0;i<$checkedEles.length;i++) { $($checkedEles[i]).parent().siblings().last().find(‘select‘).val(getvalue); } } } ) </script> </body> </html>
键盘事件——批量操作下拉列表
JQuery补充
页面载入之前执行JQuery方法
我们在前面所有的例子都是把script标签写在body内部最后面的,因为html代码是从上到下依次刷出来的。如果我们把Script写在head里会怎么样呢?
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="jquery-3.2.1.min.js"></script> <script> console.log($(‘#d1‘).text()) </script> </head> <body> <div id="d1">12345</div> </body> </html>
在界面里检查一下,会发现什么也没打印出来。
所以我们需要用下面打方法定义好,让DOM树生成以后在绑事件。
$(document).ready(function(){})
但是还有一种比较不直观的方法
$(function(){}{... })
上面两种方法是一样的,但是第二种不是特别直观。不建议使用,了解即可。
简单的动画效果
下面是一些简单常见打动画效果,类似早期ppt里的飞入,淡入淡出啥的
基本款
show() //显示 hide() //隐藏 toggle() //切换
滑动效果
slideDown() slideUP() slideToggle()
淡入淡出
fadeIn() fadeOut() fadeTo() fadeToggle()
上面的fadeTo()可以赋值个不透明度来达到在一定时间内淡到不透明度的效果。
$(‘img‘).fadeTo(3000,0.5) //0.5秒内透明度降低到0.5
自定义
animate(p,[s],[e],[fn]) //位置,效果等
案例:
有些时候我们在一些论坛上面有个点赞的按钮,点击以后旁边会有个动态的+1的效果,我们看一看是怎么实现的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>+1效果</title> </head> <body> <style> div>i{display: inline-block; position: absolute; color: red; } </style> <div id="d1">点赞</div> <script src="jquery-3.2.1.min.js"></script> <script> $(‘div‘).on(‘click‘,function(){ var newIele =document.createElement(‘i‘) newIele.innerText=‘+1‘ $(this).append(newIele) $(this).children(‘i‘).animate({ opacity:0},1000) }) </script> </body> </html>
点赞案例
补充
each方法
each是一个通用的迭代函数,可以用来无缝迭代对象和数组。数组和类似数组的对象通过一个长度属性(如一个函数的参数对象)来迭代数字索引,从0到length-1,其他对象通过起属性名进行迭代
jQuery.each(collection,callback(indexInArray,valueOfElement))
下面看看他是怎么用的,比方我们有5个div,里面的内容从111到555
<div>111</div> <div>222</div> <div>333</div> <div>444</div> <div>555</div>
如果我们想要取出来div里面的text,那么现在的方法是这样的
var $divEles = $(‘div‘) for (var i=0;i<$divEles.length;i++){ console.log($divEles[i].innerText)}
就是直接用for循环进行遍历。但是jQuery提供了一种新的方法:each,用起来要简单的多,先看看他的用法
$divEles.each(function(){console.log(this)})
打印出的对象可以看出来是个DOM对象,我们可以直接用innerText属性
$divEles.each(function(){console.log(this.innerText)})
所以,使用each方法是更简单的,但是还是要注意each里的this指向的是谁!
除了上面的用法,我们还可以用$.each的方法来对可迭代的对象进行遍历
var a=[11,22,33,44,55] $.each(a,function(k,v){console.log(k+‘:‘+v)})
一定要记住的一点:
each方法是不支持break,如果想跳出循环是不能用break的,会报错。要想中断的话要加上return false就可以,比方如果我们只想打印到33这个数
$.each(a,function(k,v){console.log(k+‘:‘+v); if(v===33){return false}})
那如果我们只是想跳过当前这次循环,也是加个return就可以
$.each(a,function(k,v){ if(v===33){return;} console.log(k+‘:‘+v)})
data方法
在匹配的元素合集中的所有元素上存储任曦相关数据或者返回匹配的元素集合中的第一个元素的给定名称的存储的值,这个值可以是个jQuery对象,也可以是个一般的变量。具体的使用方法在最后面的案例 中会用到。
综合案例
结合上面的jQuery的各种方法来一个使用案例:
界面效果如下
1点击添加按钮可以弹出模态框,输入相应内容后可以添加新数据。
要点:新添加的元素的事件绑定——事件委托
2点击编辑按钮可以在弹出的模态框内实现相应内容的编辑,点击确认后对替换改行原有数据
要点:点击确认后要判断是编辑状态还是添加状态,编辑状态就用到了上面的data方法。
3点击删除按钮可以删除该行数据(注意第一列的编号也要有相应变化,比如删掉第二行,原有数据第三行以后的编号全部变化。)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="数据修改.css"> </head> <body> <button id="add">添加</button> <table border="1"> <thead> <tr> <th>#</th> <th>姓名</th> <th>爱好</th> <th>操作</th> </tr> </thead> <tbody> <tr> <td class="id">1</td> <td>张三</td> <td>吃</td> <td> <button class="edit">编辑</button> <button class="delete">删除</button> </td> </tr> <tr> <td class="id">2</tdclass="id"> <td>李四</td> <td>吃</td> <td> <button class="edit">编辑</button> <button class="delete">删除</button> </td> </tr> <tr> <td class="id">3</td> <td>王五</td> <td>吃</td> <td> <button class="edit">编辑</button> <button class="delete">删除</button> </td> </tr> </tbody> </table> <div id="cover" class="hide"> <div id="model"> <p> <label for="">姓名: <input type="text" id="name"> </label> </p> <p> <label for="">爱好: <input type="text" name="" id="hobby"> </label> </p> <p> <button id="submit">提交</button> <button id="cancel">退出</button> </p> </div> </div> <script src="jquery-3.2.1.min.js"></script> <script> var $editEle = undefined //定义弹出模态框的方法和关闭模态框的方法 function showCover() { $(‘#cover‘).removeClass(‘hide‘) } function closeCover() { $(‘#cover‘).addClass(‘hide‘) } //编辑按钮被按下 //注意这里要使用事件委托,防止新添加的按钮没有事件绑定 $(‘tbody‘).on(‘click‘,‘.edit‘,function(){ //把点击的当前行JQuery对象保存起来 var $currentTrEle = $(this).parent().parent(); $(‘#model‘).data(‘currentTr‘,$currentTrEle); showCover() //获取 var name = $(this).parent().parent().children()[1].innerText var hobby = $(this).parent().parent().children()[2].innerText $(‘#name‘).val(name) $(‘#hobby‘).val(hobby) }) //删除按钮被按下,同样要用事件委托 $(‘tbody‘).on(‘click‘,‘.delete‘,function(){ var $currentTrEle = $(this).parent().parent(); //修改id号,用each的方法对操作行后面的行依次更新 $currentTrEle.nextAll().each(function(){ var oldNum = $(this).children().first().text(); $(this).children().first().text(oldNum-1); }); $currentTrEle.remove(); }) //添加按钮被按下 $(‘#add‘).on(‘click‘, function () { //弹出模态框 showCover() //清空input $(‘#cover input‘).val(‘‘) //不专业的写法 $(‘#cover‘).find(‘input‘).val("") //只在cover里找input标签,效率略高 }) $(‘#cancel‘).on(‘click‘, function () { //清空模态框里input的内容 //隐藏模态框 closeCover() }) $(‘#submit‘).on(‘click‘, function () { //取到input里的值 //根据是添加状态还是编辑状态做出不同的操作 //如果是添加就生成新的tr标签加到tbody最后 //如果是编辑就找到点击按钮的行数,进行相对应的操作。 var name = $(‘#name‘).val() var hobby = $(‘#hobby‘).val() console.log(name,hobby) //获取现有行数 var newId = $(‘tr‘).length //创建tr标签 newtr = document.createElement(‘tr‘) $(newtr).html("<td class=‘id‘>"+newId+"</td>"+ "<td>"+name+"</td>"+ "<td>"+hobby+"</td>"+ "<td><button class=‘edit‘>编辑</button> <button class=‘delete‘>删除</button></td>") var $currentTrEle = $(‘#model‘).data(‘currentTr‘) console.log($currentTrEle) //添加状态 if ($currentTrEle===undefined){ $(‘tbody‘).append(newtr) } //修改状态 else{ $currentTrEle.children().eq(1).text(name) $currentTrEle.children().eq(2).text(hobby) } //清楚当前行数据 $(‘#model‘).removeData(‘currentTr‘) closeCover() }) </script> </body> </html>
数据修改——html代码
/* 文件名:数据修改.css */ #cover{ background-color: rgba(0,0,0,0.4); position:absolute; top:0; right: 0; bottom: 0; left: 0; z-index: 998; } #model{ background-color: white; height: 200px; width: 300px; position: absolute; top: 50%; left: 50%; margin-left: -100px; margin-top: -150px; z-index: 1000; } .hide{display: none;}
数据修改css代码
原文地址:https://www.cnblogs.com/yinsedeyinse/p/12117238.html