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>
View Code

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>
View Code

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>
View Code

二. 动画: 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>
View Code

(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>
View Code

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>
View Code

(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>
View Code

三. 类数组对象操作:

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>
View Code

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>
View Code

四. 添加自定义函数:

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>
View Code

五. 封装自定义插件

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>
View Code

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>
View Code

将其差分为:

第一步: 将原网页中插件相关的所有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;
View Code

 第二步: 在独立的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 //他的元素就能自动变成手风琴效果。
View Code

第三步:最后在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>
View Code

六.用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>
View Code

七跨域

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 //如果看到北京天气预报,说明服务器端运行正常
View Code

客户端浏览器访问代码

 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>
View Code

 (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子对象 …

    }

 

posted @ 2021-02-24 18:28  ComeIntoBud  阅读(108)  评论(0)    收藏  举报