jQuery介绍(二)
一. 事件:
1,鼠标事件
(1). DOM中:
a. mouseover, mouseout
鼠标进入 鼠标移出
b. 问题:即使反复进出子元素,也会反复触发父元素上的鼠标进入和离开事件。和现实情况不符!
c. 解决: mouseenter和mouseleave代替mouseover和mouseout
鼠标 进入 鼠标 离开
d. 好处: 即使反复进出子元素,也不会反复触发父元素上的事件处理函数了。和现实情况相符了!
(2). jq中额外提供了一种新的简写:
a. 前提: 如果确实同时绑定了mouseenter和mouseleave,才能简写为
b. 简写: $元素.hover( //=mouseenter+mouseleave
function(){ ... }, //给mouseenter
function(){ ... }, //给mouseleave
)
c. 示例: 使用mouseenter、mouseleave、hover实现鼠标进入和离开操作
1 <!DOCTYPE HTML> 2 <html> 3 4 <head> 5 <title>事件处理</title> 6 <meta charset="utf-8" /> 7 <style> 8 #d1 #d2 #d3 { 9 cursor: pointer 10 } 11 12 #d1 { 13 background-color: green; 14 position: relative; 15 width: 150px; 16 height: 150px; 17 text-align: center; 18 cursor: pointer; 19 } 20 21 #d2 { 22 background-color: blue; 23 position: absolute; 24 top: 25px; 25 left: 25px; 26 width: 100px; 27 height: 100px; 28 } 29 30 #d3 { 31 background-color: red; 32 position: absolute; 33 top: 25px; 34 left: 25px; 35 width: 50px; 36 height: 50px; 37 line-height: 50px; 38 } 39 </style> 40 41 </head> 42 43 <body> 44 <div id="d1"> 45 <div id="d2"> 46 <div id="d3"> 47 </div> 48 </div> 49 </div> 50 <script src="js/jquery-1.11.3.js"></script> 51 <script> 52 $("#d1") 53 // // .mouseover(function(){ 54 // .mouseenter(function(){ 55 // console.log(`进入d1`) 56 // }) 57 // // .mouseout(function(){ 58 // .mouseleave(function(){ 59 // console.log(`离开d1`) 60 // }) 61 .hover( 62 function(){ 63 console.log(`进入d1`) 64 }, 65 function(){ 66 console.log(`离开d1`) 67 } 68 ) 69 </script> 70 </body> 71 72 </html>
d. 更简化: 如果条件允许,把hover中两个函数改造成完全相同的函数。则只需要写一个函数即可绑定两个事件.
$元素.hover(
function(){ ... } //既给mouseenter,又给mouseleave
)
e. 示例: 使用最佳化hover实现功能
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title> new document </title> 5 <meta charset="utf-8"> 6 <style> 7 #target { 8 border: 1px solid #eee; 9 border-radius: 6px; 10 padding: 10px; 11 transition: all .5s linear; 12 } 13 #target.hover { 14 border: 1px solid #aaa; 15 box-shadow: 0 0 6px #aaa; 16 background-color:red; 17 color:#fff; 18 } 19 </style> 20 </head> 21 <body> 22 <h1>使用hover(fn,fn)</h1> 23 24 <h3>鼠标悬停在div上方,则突出显示;移出则取消突出显示</h3> 25 <div id="target"> 26 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi neque quae voluptatum ducimus culpa itaque maxime distinctio soluta cum cupiditate esse tenetur deserunt fuga perferendis sed veritatis asperiores. Numquam officia.</p> 27 </div> 28 <script src="js/jquery-1.11.3.js"></script> 29 <script> 30 $("#target").hover( 31 function(){ 32 // $(this).addClass("hover") 33 $(this).toggleClass("hover") 34 }//, 35 // function(){ 36 // // $(this).removeClass("hover") 37 // $(this).toggleClass("hover") 38 // } 39 ) 40 </script> 41 </body> 42 </html>
2. 模拟触发:
(1). 什么是: 明明没有点到按钮,也能执行和点按钮相同的操作!(用键盘按键模拟触发(如百度一下按enter触发搜索))
(2). 如何:
a. 标准: $元素.trigger("事件名")
触发
b. 意为: 找到带有事件的元素,并触发这个元素上的指定事件。
c. 简写: 如果要触发的事件属于常用事件列表中,则可以简写为:
$元素.事件名()
(3). 示例: 按回车和点按钮都能执行搜索操作:
1 <!DOCTYPE html> 2 <html> 3 4 <head lang="en"> 5 <meta charset="UTF-8"> 6 <title></title> 7 <style> 8 </style> 9 </head> 10 11 <body> 12 <input><button>百度一下</button> 13 <script src="js/jquery-1.11.3.js"></script> 14 <script> 15 //当单击按钮时可以搜索 16 $("button").click(function(){ 17 //获得文本框中用户输入的关键字 18 // 当前按钮 前一个兄弟的值 19 var value=$(this).prev().val(); 20 console.log(`搜索${value}相关的内容...`) 21 }); 22 //当在文本框按回车时也能执行和点击按钮一样的搜索 23 //用户按回车键->键盘发送数字->存入event中 24 // ↓ 25 $("input").keyup(function( e ){ 26 //只有用户点的是回车键(13号),才能执行搜索操作 27 if(e.keyCode==13){ 28 // $("button").trigger("click"); 29 $("button").click(); 30 } 31 }) 32 </script> 33 </body> 34 35 </html>
二. 动画: 2种:
1. 简单动画: 固定写死的三种动画效果
(1). 显示隐藏:
a. $元素.show() 让一个隐藏的元素显示出来
相当于.style.display="block"
b. $元素.hide() 让一个显示的元素隐藏
相当于.style.display="none"
c. $元素.toggle() 让一个元素在显示和隐藏之前切换
d. 问题: 默认以上三个函数,没有过渡效果!而是瞬间显示隐藏
e. 解决: 只要给三个函数添加"动画持续时间ms"实参值即可有过渡效果。
(2). 上滑下滑: .slideUp() .slideDown() .slideToggle()
(3). 淡入淡出: .fadeIn() .fadeOut() .fadeToggle()
括号中可以添加时间毫秒数如$元素.hide(2000)将用时2000ms完成动画
(4). 问题: 2大致命问题:
a. 动画效果都是在js函数库中写死的!几乎不可维护的!
b. 底层其实是用js的DOM操作+定时器模拟实现的动画效果(可以在Element中看到动画的变化过程)——效率比css动画差的远!
(5). 结论: 如果一个动画效果,将来既能用css实现,又能用js实现,应该首选css!
(6). 示例: 使用简单动画函数实现动画效果:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title> new document </title> 5 <meta charset="utf-8"> 6 <style> 7 *{margin:0; padding:0;} 8 #target{ 9 border-radius:10px; 10 background:#eee; 11 } 12 .fade{/*动画起始状态*/ 13 height:104px; width:970px; opacity:1; 14 padding: 10px; overflow:hidden; 15 border: 1px solid #aaa; 16 17 } 18 .out{/*动画结束状态*/ 19 20 } 21 </style> 22 </head> 23 <body> 24 <h1>jQuery动画函数——显示隐藏动画</h1> 25 <button id="btn1">显示/隐藏div</button> 26 <div id="target"> 27 <p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore debitis animi sint iste sequi sunt ad excepturi error labore molestiae est expedita eos nisi placeat provident dolorem quos facilis! Sapiente!</span><span>Accusamus neque id reprehenderit! Voluptatem in deleniti laboriosam commodi facere magnam impedit minima corrupti distinctio culpa amet optio natus esse. Inventore incidunt ab id perspiciatis atque minus magnam tempore harum.</span></p> 28 </div> 29 <script src="js/jquery-1.11.3.js"></script> 30 <script> 31 $("#btn1").click(function(){ 32 $("#target") 33 // .toggle(2000); 34 // .slideToggle(2000); 35 .fadeToggle(2000); 36 }); 37 </script> 38 </body> 39 </html>
(7). 特例: .show(), hide(),和toggle()在没有实参值ms的情况下,只是display=none和display=block的简写!不存在可维护性和效率的考虑。因此,这三个函数,在不需要动画效果的显示隐藏时,还是非常简化的!
(8). 示例: 隐藏显示部分品牌
1 <!DOCTYPE html> 2 <html> 3 4 <head lang="en"> 5 <meta charset="UTF-8"> 6 <title></title> 7 <style> 8 body { 9 text-align: center; 10 } 11 12 ul { 13 list-style: none; 14 } 15 16 li { 17 margin: 0; 18 padding: 0; 19 display: inline-block; 20 width: 30%; 21 } 22 </style> 23 </head> 24 25 <body> 26 <ul id="list"> 27 <li>0尼康(234)</li> 28 <li>1佳能(22)</li> 29 <li>2索尼(932)</li> 30 <li>3宾得(11)</li> 31 <li>4爱国者(3234)</li> 32 <li>5欧巴(32)</li> 33 <li>6海鸥(2334)</li> 34 <li>7卡西欧(334)</li> 35 <li>8三星(834)</li> 36 <li>9松下(234)</li> 37 <li>10其它品牌(2343)</li> 38 </ul> 39 40 <button data-toggle="brandlist">精简显示品牌</button> 41 42 <script src="js/jquery-1.11.3.js"></script> 43 <script> 44 //DOM 4步 45 //1. 查找触发事件的元素 46 //本例中: 点按钮触发事件 47 $("button") 48 //2. 绑定事件处理函数 49 .click(function(){ 50 //3. 查找要修改的元素 51 //本例中: 点按钮,要修改2套元素 52 //3.1 要修改当前按钮本身 53 var $this=$(this); 54 //3.2 要修改ul下>4位置的且不是最后一个的li元素 55 var $lis=$("ul>li:gt(4):not(:last-child)"); 56 //4. 修改元素 57 //3.1 当前按钮的文字要改 58 if($this.html()=="精简显示品牌"){ 59 $this.html("显示所有品牌") 60 }else{ 61 $this.html("精简显示品牌") 62 } 63 //3.2 多个li要切换显示隐藏 64 $lis.toggle(); 65 }) 66 </script> 67 </body> 68 69 </html>
2. 万能动画: 能够对多种css属性随意应用动画效果
(1). $元素.animate({
css属性: 目标值,
... : ...
}, 动画持续时间ms)
(2). 意为: 让元素的指定的css属性值在规定的动画持续时间内从当前值过渡到目标值。
(3). 强调:
a. animate()中的css属性只需要提供目标值即可!animate()函数会自动用目标值-当前值,获得差值,并自动规划动画变化过程。
b. animate()只支持单个数值的css属性。且不支持颜色动画和css3变换。——animate()远不如css的transition!
(4). 问题: 底层依然是DOM+定时器。效率也远不如css的transition和animation。
(5). 示例: 测试animate都支持哪些属性,不支持哪些属性:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title> new document </title> 5 <meta charset="utf-8"> 6 <style> 7 #d1{ 8 border:1px solid #aaa; 9 border-radius:6px; 10 background:#eee; 11 width:50px; height:50px; 12 position:absolute; top:120px; left:0; 13 } 14 </style> 15 </head> 16 <body> 17 <h1>animate</h1> 18 <button id="btn1">启动动画</button> 19 <div id="d1">abcd</div> 20 <script src="js/jquery-1.11.3.js"></script> 21 <script> 22 $("button").click(function(){ 23 $("#d1").animate({ 24 width:400, //heigth 25 // left:400, //top bottom right 26 // padding:30, //margin 27 // fontSize:64 28 29 // backgroundColor:"red" 30 // transform:"rotate(90deg)" 31 },2000); 32 }) 33 </script> 34 </body> 35 </html>
(6). 排队和并发:
a. 并发: 多个css属性同时变化
$元素.animate({
//放在一个animate中的多个css属性,是并发变化
css属性1: 值1,
css属性2: 值2
})
b. 排队: 多个css属性先后依次变化
$元素
//对同一个元素先后调用多个animate,就是排队变化。
.animate({
css属性1:值1
})
.animate({
css属性2:值2
})
c. 原理:
1). 在jq中,每个元素身上都有一个动画队列。
2). 调用animate()函数,其实不是立刻执行动画的意思,而是将动画加入到元素的动画队列中暂存
3). 如果当前元素的动画队列中之前还有未执行完的动画,则新加入队列的动画就要等待
4). 如果当前元素的动画队列中之前没有未执行完的动画,则新加入队列的动画就可立刻执行!
(7). 停止动画:
a. $元素.stop();
b. 注意: 如果一个元素的动画队列中有多个动画在等待,则stop()默认只能停止其中一个动画!队列中后续动画依然继续执行!
c. 解决: $元素.stop(true) //停止当前动画,并清空动画队列。
(8). 判断一个元素是否正在播放动画(jq中独有的):
:animated 选择器
(9). 动画播放后自动执行: 为animate()函数添加第三个回调函数参数
$元素.animate(
{
css属性: 目标值,
... : ...
},
动画持续时间ms,
function(){ //回调函数
//放在这里的代码注定只能在动画结束后被自动调用执行!
}
)
(10). 示例:点小星星,播放动画,再点小星星,停止动画
1 <!DOCTYPE html> 2 <html> 3 4 <head lang="en"> 5 <meta charset="UTF-8"> 6 <title></title> 7 <style> 8 img { 9 position: relative; 10 } 11 </style> 12 </head> 13 14 <body> 15 //图片为小星星图片 16 <img id="s1" src="img/star.png"><br /> 17 <img id="s2" src="img/star.png"><br /> 18 <img id="s3" src="img/star.png"><br /> 19 <img id="s4" src="img/star.png"><br /> 20 21 <script src="js/jquery-1.11.3.js"></script> 22 <script> 23 /* 24 s1在屏幕左上角的小星星, 点击后从左移动到屏幕右边 25 s2在屏幕左上角的小星星,点击后从左移动到屏幕右边,再移动到下边——走直角 26 s3在屏幕左上角的小星星,点击后从左上角移动到屏幕右下边,走斜线 27 s4点击小星星,变大、变淡.... 直至消失 28 */ 29 $("#s1").click(function(){ 30 var $this=$(this); 31 //如果当前星星正在执行动画, 32 if($this.is(":animated")){ 33 //则停止当前动画 34 $this.stop(); 35 }else{//否则如果当前星星没有执行动画 36 //才启动动画 37 $this.animate({ 38 left:400 39 },3000) 40 } 41 }) 42 $("#s2").click(function(){ 43 var $this=$(this); 44 //如果当前星星正在执行动画, 45 if($this.is(":animated")){ 46 //则停止当前动画 47 $this.stop(true); 48 }else{//否则如果当前星星没有执行动画 49 //才启动动画 50 $this 51 .animate({ 52 left:400 53 },2000) 54 .animate({ 55 top:200 56 },1000) 57 } 58 }) 59 $("#s3").click(function(){ 60 var $this=$(this); 61 //如果当前星星正在执行动画, 62 if($this.is(":animated")){ 63 //则停止当前动画 64 $this.stop(); 65 }else{//否则如果当前星星没有执行动画 66 //才启动动画 67 $this 68 .animate({ 69 left:400, 70 top:200 71 },3000) 72 } 73 }) 74 $("#s4").click(function(){ 75 alert("疼!"); 76 var $this=$(this); 77 $this 78 .animate(//DOM+定时器 //异步 79 { 80 width:256, 81 opacity:0 82 }, 83 3000, 84 function(){//回调函数,3000后自动调用 85 $this.hide(); 86 } 87 ); 88 //错误: 89 // .hide();//后续操作,不会等动画执行完才执行。而是几乎和动画同时执行! 90 }) 91 </script> 92 </body> 93 94 </html>
三. 类数组对象操作:
1. 遍历:
(1). JS中数组类型中:
a. arr.forEach(function(元素, 下标, 当前数组){ ... })
b. 专门代替for循环遍历数组中每个元素值
(2). jq中:
a. $查找结果.each(function(下标, 当前元素对象){ ... })
b. 专门遍历jq查找结果中每个DOM元素对象,每遍历查找结果中一个DOM元素对象,就自动调用一次回调函数。
c. 强调: 因为jQuery查找结果中保存的其实是原生的DOM元素对象,所以each()函数,每次从jQuery查找结果对象中取出的也是DOM元素对象。如果希望继续调用简化版函数,必须先$(DOM元素)。
(3). 示例: 检查每个li的内容,根据内容不同,执行不同的操作
1 <!DOCTYPE html> 2 <html> 3 4 <head lang="en"> 5 <meta charset="UTF-8"> 6 <title></title> 7 <style> 8 </style> 9 </head> 10 11 <body> 12 13 <ul id="list"> 14 <li>98</li> 15 <li>85</li> 16 <li>33</li> 17 <li>99</li> 18 <li>52</li> 19 </ul> 20 21 <script src="js/jquery-1.11.3.js"></script> 22 <script> 23 //回顾数组forEach 24 var arr = ["亮亮", "然然", "东东"]; 25 arr.forEach(function (value) { 26 console.log(`${value} - 到!`) 27 }) 28 29 //请给每个不足60分的成绩+10分,并将超过90分的成绩用绿色背景标识出来 30 $("ul>li").each(function (i, li) { 31 console.log(li);//DOM元素对象 32 var $li = $(li);//转为jq对象 33 //先获得当前li元素对象的内容,转为整数 34 var n = parseInt($li.html()); 35 if (n < 60) { 36 $li.html(n + 10) 37 } else if (n >= 90) { 38 $li.css("background-color", "green") 39 } 40 }) 41 </script> 42 </body> 43 44 </html>
2. 查找:
(1). JS高级数组类型中:
a. var 下标=arr.indexOf(元素值)
b. 在数组arr中查找一个指定的元素值出现的下标位置
c. 返回值:
1). 如果在数组arr中找到了指定的元素值,就返回这个元素值的下标位置.
2). 如果在数组arr中没有找到指定的元素值,则返回-1
(2). jq中:
a. var 下标=$查找结果.index(DOM元素或jq对象)
b. 意为: 在jq查找结果中查找一个指定的DOM元素出现的位置。
c. 返回值:
1). 如果在jq查找结果中找到了指定的DOM元素,就返回这个DOM元素的下标位置.
2). 如果在jq查找结果中没有找到指定的元素值,则返回-1
(3). 示例: 五星评价:
1 <!DOCTYPE html> 2 <html> 3 4 <head lang="en"> 5 <meta charset="UTF-8"> 6 <title></title> 7 <style> 8 .score { 9 list-style: none; 10 margin: 0; 11 padding: 0; 12 } 13 14 .score li { 15 display: inline-block; 16 width: 50px; 17 height: 50px; 18 border: 1px solid #f00; 19 border-radius: 50%; 20 cursor: pointer; 21 } 22 </style> 23 </head> 24 25 <body> 26 27 <h3>请打分</h3> 28 <ul class="score"> 29 <li></li> 30 <li></li> 31 <li></li> 32 <li></li> 33 <li></li> 34 </ul> 35 36 <script src="js/jquery-1.11.3.js"></script> 37 <script> 38 //回顾数组indexOf 39 var arr = ["亮亮", "然然", "东东"]; 40 // 0 1 2 41 //想查找然然的位置: 42 var i = arr.indexOf("然然"); 43 console.log(`然然在${i}位置`); 44 //想查找小玥玥的位置: 45 var i = arr.indexOf("小玥玥"); 46 console.log(i); //-1 47 48 //获得当前单击的li在所有li中的位置i,i及其执行的都变为红色,i之后的都变为白色 49 //DOM 4步 50 //1. 查找触发事件的元素 51 //本例中: 因为ul下所有li都能点击,所以应该用事件委托优化,事件应该绑定在ul上一份即可 52 $("ul") 53 //2. 绑定事件处理函数 54 .click(function(e){ 55 //e.target代替this 56 var $tar=$(e.target); 57 //只有点在li上才能触发事件 58 if($tar.is("li")){ 59 //3. 查找要修改的元素 60 //4. 修改元素 61 //先获得当前点击的li在ul下所有li中的下标位置: 62 var i=$("ul>li").index($tar); 63 //<i+1位置的所有li都变黄 64 $(`ul>li:lt(${i+1})`) 65 .css("background-color","yellow") 66 //>i位置的所有li都变白 67 $(`ul>li:gt(${i})`) 68 .css("background-color","#fff") 69 } 70 }) 71 72 </script> 73 </body> 74 75 </html>
四. 添加自定义函数:
1. 问题: 如果在项目中经常用到一个功能,但是jq中没有提供对应的简化版函数。
2. 解决: 可以自定义一个函数,放入jq的原型对象中,将来,jq所有子对象就都可以调用我们自定义的函数了
3. 如何:
(1). 向jq原型对象中添加自定义函数
jQuery.prototype.自定义函数=function(){
... this ...
}
(2). 将来: $查找结果.自定义函数()
4. 强调:
(1). 如果自定义函数中,需要访问将来调用这个自定义函数的.前的jq对象,则必须使用this关键字。
(2). 但是,因为this已经指向将来.前的$()jq对象了,所以不用给this加$(),就能直接用this访问简化版函数。
(3). 但是,如果遍历this中每个DOM元素,取出的依然是原生的DOM元素对象。如果DOM元素想使用简化版函数,必须先$(DOM元素)。否则,DOM元素就只能使用原生DOM的属性和方法
5. 示例: 为jq添加自定义求和函数
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <ul> 9 <li>85</li> 10 <li>91</li> 11 <li>73</li> 12 <li>59</li> 13 </ul> 14 <script src="js/jquery-3.2.1.js"></script> 15 <script> 16 //假设在我的项目中经常需要对找到的所有元素内容求和 17 jQuery.prototype.sum=function(){ 18 //对数组或集合求和的固定套路: 19 //先定义变量保存临时的和,开局值为0 20 var result=0; 21 //遍历数组或集合中每个元素 22 //只有this,才能自动获得将来.前的查找结果对象 23 //因为将来.前已经是$()jq对象了,所以,无需给this重复加$(),就已经指向将来的jq对象了 24 console.log(this); 25 //但是,of从将来jq对象中遍历出来的每一项依然是jq找到的原生的DOM元素对象 26 //所以,of前的变量,接到的DOM元素对象,如果想继续调用简化版函数,必须$(元素) 27 //否则,of前的变量就只能用原生的属性和方法。 28 for(var DOM元素 of this){ 29 console.log(DOM元素); 30 //每遍历一个元素,就将元素的内容转为数字,累加到临时变量中 31 result+=parseFloat(DOM元素.innerHTML) 32 } 33 //返回临时变量中保存的最终求和结果。 34 return result; 35 } 36 37 //将来: 38 console.log($("ul>li").sum()); 39 // sum()函数 40 // 是要求.前的查找结果中 41 // 每个元素内容的和 42 // 所以遍历的应该是将来.前的jq查找结果对象 43 </script> 44 </body> 45 </html>
五. 封装自定义插件
1. 什么是插件/组件: 页面中拥有专属的HTML+CSS+JS的可重用的独立的功能区域。
2. 为什么: 重用!提高开发效率!
3. 何时: 今后,只要页面中有个功能,经常被反复使用!都需要定义在组件中,然后反复使用组件。
4. jq官方提供了一套js组件库: jquery ui
(1). 下载: jqueryui.com
(2). 放入项目文件夹中:如图

(3). 在页面中引入:(注意顺序)
<link rel="stylesheet" href="css/jquery-ui.css">
<script src="js/jquery-1.11.3.js"> //先引jq
<script src="js/jquery-ui.js"> //再引jqui
(4). 在页面中使用jqueryui的插件: 2步:
a. 按插件的要求,手工编写HTML结构和内容
不用加任何class!只需要在父元素上指定一个id名,好找即可!
b. 在自定义的<script>中,用jq查找插件的父元素,调用插件函数!
$(插件父元素).插件函数();
(5). 问题: 2个致命的问题
a. 因为jq ui将功能和样式封装的死死的,几乎不可维护!
b. 只有PC端,没有移动端,也不支持响应式!
(6). 所以,jq ui今后几乎不会使用。被bootstrap、element ui等代替了!
(7). 示例: 使用jquery ui实现手风琴效果:
1 //这里看不出效果网页中没有真实引入js等 只是代码 2 <!DOCTYPE html> 3 <html> 4 5 <head> 6 <title> new document </title> 7 <meta charset="utf-8"> 8 <link rel="stylesheet" href="css/jquery-ui.css"> 9 <script src="js/jquery-1.11.3.js"></script> 10 <script src="js/jquery-ui.js"></script> 11 </head> 12 13 <body> 14 <h1>jQueryUI:Widgets —— Accordion</h1> 15 <div id="my-accordion"> 16 <div>《西游记》简介</div> 17 <div>一个和尚和四个动物的故事: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Similique nulla voluptas velit minus esse voluptatem illum quis magni nihil sint facilis cupiditate nobis quia ab neque. Modi veniam omnis nisi? </div> 18 <div>《水浒传》简介</div> 19 <div>105个男人和三个女人的故事: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis provident sapiente aperiam reprehenderit repellat rem magnam vel odio quia harum hic impedit dolorem similique ea est consequatur adipisci at nemo!</div> 20 <div>《红楼梦》简介</div> 21 <div>一个男人和一群女人的故事: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus minima quidem aspernatur eligendi optio cupiditate minus nam expedita? Aliquid veritatis doloribus maxime vel dicta illo unde iusto qui quasi doloremque.</div> 22 </div> 23 <script> 24 $("#my-accordion").accordion(); 25 </script> 26 </body> 27 28 </html>
5. 封装一个自定义的jquery ui风格的组件:
(1). 何时: 如果我只想封装一个组件,给我自己使用!jq ui这种方式,还是很简单的!
(2). 如何封装:
a. 前提: 封装插件,其实不是从0开始开发的过程。而是,已经用HTML+CSS+JS写好了插件的功能,只不过功能的代码和页面中其它代码混在一起,不便于常用而已!其实,封装插件,就是一个提取代码的过程!
b. 第一步: 将原网页中插件相关的所有css代码,剪切到一个独立的css文件中保存。
c. 第二步: 在独立的js文件中,向jq原型对象中添加一个新的自定义插件函数:
1). 自动为各级元素添加class
示意图:

(2). 自动为指定元素添加事件绑定:
因为在原页面中已经实现了插件的功能,所以,我们无需重新编写插件的事件处理函数。只要回到原页面中找到原事件处理函数,剪切到插件函数中即可!
(3). 如何使用: 和使用jquery ui完全一样!
a. 引入我们自定义的插件的css和js
<link rel="stylesheet" href="zidingyi/test.css">
<script src="js/jquery-1.11.3.js">
<script src="zidingyi/test.js">
b. 按插件要求,编写HTML结构和内容
不用加任何class,只在父元素加一个id,好找即可
c. 在自定义<script>中,查找插件父元素,调用我们自己定义的插件函数即可!
(4). 示例: 封装自定义的手风琴插件:
如下例:
完整的css+js+jQuery 代码:
<!DOCTYPE html> <html> <head> <title> new document </title> <meta charset="utf-8"> <style> /* css样式 */ .accordion{width:80%; margin:0 auto;} .accordion>.title{ background:#eee; border:1px soild #aaa; padding:6px; font-size:1.5em; font-weight:bold; cursor:pointer; } .accordion>.content{ border-left:1px solid #eee; border-right:1px solid #eee; } .accordion>:last-child{ border-bottom:1px solid #eee; } .fade{ height:0; opacity:0; overflow:hidden; transition:all .5s linear; } .in{ height:84px; opacity:1; } </style> </head> <body> <!-- HTML代码 --> <h1>使用“高度动画”实现“手风琴”组件</h1> <div class="accordion"> <div class="title">《西游记》简介</div> <div class="content fade in">一个和尚和四个动物的故事: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Similique nulla voluptas velit minus esse voluptatem illum quis magni nihil sint facilis cupiditate nobis quia ab neque. Modi veniam omnis nisi? </div> <div class="title">《水浒传》简介</div> <div class="content fade">105个男人和三个女人的故事: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis provident sapiente aperiam reprehenderit repellat rem magnam vel odio quia harum hic impedit dolorem similique ea est consequatur adipisci at nemo!</div> <div class="title">《红楼梦》简介</div> <div class="content fade">一个男人和一群女人的故事: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus minima quidem aspernatur eligendi optio cupiditate minus nam expedita? Aliquid veritatis doloribus maxime vel dicta illo unde iusto qui quasi doloremque.</div> </div> <script src="js/jquery-1.11.3.js"></script> <script> // jQuery代码 $(".accordion").on("click",".title",e=> $(e.target).next(".content").toggleClass("in") .siblings(".content").removeClass("in") ); </script> </body> </html>
将其差分为:
第一步: 将原网页中插件相关的所有css代码,剪切到一个独立的css文件中保存。保存在一个zidingyi文件夹中test.css
1 .accordion{width:80%; margin:0 auto;} 2 .accordion>.title{ 3 background:#eee; border:1px soild #aaa; 4 padding:6px; font-size:1.5em; 5 font-weight:bold; cursor:pointer; 6 } 7 .accordion>.content{ 8 border-left:1px solid #eee; 9 border-right:1px solid #eee; 10 } 11 .accordion>:last-child{ 12 border-bottom:1px solid #eee; 13 } 14 .fade{ 15 height:0; 16 opacity:0; 17 overflow:hidden; 18 transition:all .5s linear; 19 } 20 .in{ 21 height:84px; 22 opacity:1;
第二步: 在独立的js文件中,向jq原型对象中添加一个新的自定义插件函数: 同样保存在zidingyi问价夹中 test.js
1 jQuery.prototype.myAccordion=function(){ 2 //1. 自动为当前插件元素各级元素添加规定的class 3 //1.1 为当前插件的父元素,添加class accordion 4 //因为将来别人用插件时,都是先用$()找到插件的父元素 5 //所以,这里还是用this来获得将来.前的插件父元素 6 //又因为.前已经是$(父元素)了,已经是jq对象了,所以不用加$(this)。this就可直接调用简化版函数 7 this //父元素 8 .addClass("accordion") //return 父元素 9 //1.2 为父元素下所有奇数位置的子元素添加class title 10 .children(":nth-child(odd)")//return 所有奇数位置 11 .addClass("title")//return 所有奇数位置 12 //1.3 为所有奇数位置的div的下一个兄弟元素加class content fade 13 .next()//return 所有偶数位置的元素 14 .addClass("content fade")//return 所有偶数位置 15 //1.4 为所有偶数位置的div中第一个div加class in 16 .first() //获得任意jq查找结果中第一个元素对象(内置) 17 .addClass("in"); 18 //2. 自动为指定元素绑定事件处理函数 19 $(".accordion").on("click",".title",e=> 20 $(e.target).next(".content").toggleClass("in") 21 .siblings(".content").removeClass("in") 22 ); 23 } 24 //希望,将来别人: 25 //$(父元素).myAccordion() 26 //他的元素就能自动变成手风琴效果。
第三步:最后在html中引入
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title> new document </title> 5 <meta charset="utf-8"> 6 <link rel="stylesheet" href="zidingyi/test.css"> 7 <script src="js/jquery-1.11.3.js"></script> 8 <script src="zidingyi/test.js"></script> 9 </head> 10 <body> 11 <h1>使用“高度动画”实现“手风琴”组件</h1> 12 <div id="my-accordion"> 13 <div>《西游记》简介</div> 14 <div>一个和尚和四个动物的故事: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Similique nulla voluptas velit minus esse voluptatem illum quis magni nihil sint facilis cupiditate nobis quia ab neque. Modi veniam omnis nisi? </div> 15 <div>《水浒传》简介</div> 16 <div>105个男人和三个女人的故事: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis provident sapiente aperiam reprehenderit repellat rem magnam vel odio quia harum hic impedit dolorem similique ea est consequatur adipisci at nemo!</div> 17 <div>《红楼梦》简介</div> 18 <div>一个男人和一群女人的故事: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus minima quidem aspernatur eligendi optio cupiditate minus nam expedita? Aliquid veritatis doloribus maxime vel dicta illo unde iusto qui quasi doloremque.</div> 19 </div> 20 <script> 21 $("#my-accordion").myAccordion() 22 </script> 23 </body> 24 </html>
六.用jQuery 发送ajax请求
1. 问题: 程序中,只要前端的网页想要显示数据,都要向服务器端发送ajax请求!因为前端页面需要大量的数据,所以将来前端会发送大量的ajax请求。但是,通过xhr发送ajax请求的步骤极其繁琐!
2. 解决:任何框架或函数库,发送ajax请求都只需要一句话即可!只不过,不同的框架或函数库,这句话的写法有不同而已!
3. jq中: (固定写法)
$.ajax({
url:"服务器端接口地址",
type:"get或post",
//如果需要携带参数值到服务器端,如果不需要携带参数到服务器端,可省略
data:{ 参数名: 参数值, ... : ... , ... },
//如果服务器端返回的结果是json格式的字符串,则必须
dataType:"json",//如果服务器端返回的不是json,则可省略
//代替以前的onreadystatechange,只在响应成功后自动触发执行
success:function(result){
//形参result,会自动收到服务器端返回的结果。
//因为前边写了dataType:"json",所以会自动调用JSON.parse()将json字符串转为内存中的对象或数组。无需手工调用JSON.parse()。
//result得到的就是直接可用的对象或数组!
//因为ajax是异步请求,所以,程序中,只要希望ajax请求成功后,才能执行的操作,都必须放在success回调函数内!
}
})
4. 示例: 使用jq ajax向创建的新浪云服务器发送ajax请求
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <script src="js/jquery-1.11.3.js"></script> 9 </head> 10 <body> 11 <script> 12 //向东哥新浪云服务器发送请求 13 //1. 请求首页6个商品对象 14 $.ajax({ 15 url:"http://xzserver.applinzi.com/index", 16 type:"get", 17 dataType:"json", 18 success:function(result){ 19 console.log(result); 20 } 21 }) 22 //2. 查询5号商品的详细信息 23 $.ajax({ 24 url:"http://xzserver.applinzi.com/details", 25 type:"get", 26 data:{ lid:5 }, 27 dataType:"json", 28 success:function(result){ 29 console.log(result) 30 } 31 }) 32 //3. 登录验证 33 $.ajax({ 34 url:"http://xzserver.applinzi.com/users/signin", 35 type:"post", 36 data:{ uname:"dingding", upwd:"123456" }, 37 dataType:"json", 38 success:function(result){ 39 console.log(result); 40 } 41 }) 42 </script> 43 </body> 44 </html>
七跨域
1. 什么是: 一个网站下的网页,去使用另一个网站下的资源。
2. 包括:
(1). 域名不同:
http://www.a.com下的网页 请求 http://www.b.com的资源
(2). 子级域名不同:
http://oa.tedu.com下的网页 请求 http://hr.tedu.com的资源
(3). 端口号不同:
http://127.0.0.1:5500下的网页 请求 http://127.0.0.1:3000的资源
(4). 协议不同:
http://12306.cn下的网页 请求 https://12306.cn的资源
(5). 即使同一台机器,同一个网站下,IP地址与主机名之间互访:
http://127.0.0.1:3000下的网页 请求 http://localhost:3000的资源
3. 大多数元素,都可以随意跨域:
<link rel="stylesheet" href="其它网站的css">
<script src="其它网站的js">
<img src="其它网站的图片">
<a href="其它网站的页面">
<iframe src="其它网站的网页片段">
... ...
4. 问题: 浏览器禁止ajax xhr发送任何跨域请求!只要发送就会报经典错误:
Access to XMLHttpRequest at 'http://127.0.0.1:3000/' from origin 'http://127.0.0.1:5500'
从源头http://127.0.0.1:5500向http://127.0.0.1:3000发送的xhr请求
has been blocked by CORS policy:
被CORS策略阻止了!
No 'Access-Control-Allow-Origin' header is present on the requested resource.
因为在请求回来的资源上没有包含'Access-Control-Allow-Origin'响应头设置!
5. 原理: 什么是CORS策略:
(1). CORS策略: 简称同源策略,cross orgin resoures shareing
跨 不同源头 资源 共享
(2). 原理:
a. 浏览器虽然允许网页中的内容或程序中的xhr向任意地址发送请求
b. 但是,浏览器会对xhr发送的ajax请求响应回来的数据进行检查:
c. 浏览器会检查响应结果头部的Access-Control-Allow-Origin属性:
1). 如果这个属性的值与当前网页所在的域名地址和端口号一致,浏览器才允许程序使用响应回来的数据
2). 如果这个属性的值与当前网页所在的域名地址和端口号不一致,浏览器就不允许程序使用响应回来的数据,且会报跨域错误!

6. 解决: 3种:
(1). 纯服务器端跨域: CORS方式:
a. 原理: 请服务器端篡改寄件人地址(Access-Control-Allow-Origin)和客户端保持一致!骗过CORS策略检查
b. 如何: 只服务器端做即可
在返回响应之前:
res.writeHead(200, {
//其它配置
... : ...,
//篡改寄件人地址:
"Access-Control-Allow-Origin": "客户端地址和端口号"
})

服务器代码
1 //你不用会写!看不懂也没关系! 2 const http=require("http"); 3 http.createServer(function(req,res){ 4 var weather="北京 多云 6~-3"; 5 res.writeHead(200,{ 6 //解决乱码 7 "Content-Type":"text/plain;charset=utf-8", 8 //篡改寄件人地址: 9 "Access-Control-Allow-Origin":"http://127.0.0.1:5500" 10 }) 11 res.write(weather); 12 res.end(); 13 }).listen(3000); 14 //运行: 15 //右键点击2_server.js 16 //选择在集成终端中打开 17 //在打开的终端窗口中输入node 2_server.js 18 //打开浏览器,地址栏: http://127.0.0.1:3000 19 //如果看到北京天气预报,说明服务器端运行正常
客户端浏览器访问代码
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <script src="js/jquery-1.11.3.js"></script> 9 </head> 10 <body> 11 <script> 12 $.ajax({ 13 url:"http://127.0.0.1:3000", 14 success:function(result){ 15 document.write(`今日天气: ${result}`); 16 } 17 }) 18 </script> 19 </body> 20 </html>
(2). 服务器端+客户端一起跨域: JSONP方式 麻烦,用的越来越少(了解)
(3). VUE框架可以解决(后期博客会介绍)
总结: $()共有4种:
1. $("选择器") 查找DOM元素,并包装进jQuery对象中
2. $(DOM元素对象) 不用查找,直接将DOM元素包装进jQuery对象中
3. $(`HTML片段`) 创建新元素
4. $(function(){ ... }) 绑定DOMContentLoaded事件处理函数,在DOM内容加载后就自动提前执行!
总结: this 7种:
一定不要看定义在哪儿,只看在哪里调用,如何调用
1. obj.fun() this->obj
2. new Fun() this->new正在创建的子对象
3. 类型名.prototype.共有方法=function(){ ... }
this->将来调用这个共有方法的.前的子对象
4. fun() 和 (function(){ })() 和回调函数中的this->window
5. 访问器属性中的this,指访问器属性所在的当前对象。
6. DOM和jQuery事件处理函数中的this->当前正在触发事件的这个DOM元素对象
7. jQuery.prototype.自定义函数=function(){
… this指将来调用这个自定义函数的点前的一个jq子对象 …
}

浙公网安备 33010602011771号