zoukankan      html  css  js  c++  java
  • jQuery三——筛选方法、事件

    一、jquery常用筛选方法

      以下为jquery的常用筛选方法:

      代码示例如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>筛选方法</title>
        <style type="text/css">
            li.active {
                font-size: 50px;
            }
        </style>
    </head>
    <body>
    <ul>
        <li class="danger">1</li>
        <li><a href="#">luffy</a></li>
        <li class="danger">3</li>
        <li>4</li>
        <a href="#"> 百度</a>
        <a href="#" id="anchor">百度</a>
    </ul>
    
    </body>
    <script src="jquery-3.3.1.js"></script>
    <script type="text/javascript">
        $(function () {
            console.log($('li'));  // 输出:jQuery.fn.init(4)   类似数组的索引
            
            // jQuery的遍历方法:.each()
            // $('li').each(function (index,ele) {   // 索引,对象
            $('ul').children().each(function (index, ele) {
                console.log(ele);   // <li class="danger">1</li> : js的dom对象
                console.log(index);   // 0  : index
    
                // 判断当前匹配元素里是否有这个类名
                var isDanger = $(this).hasClass('danger');
                if (isDanger) {
                    $(this).css('color','red');
                } else {
                    $(this).css('font-size','20px');
                }
            })
    
            // children()
            console.log($('ul').children());
            console.log($('li'));   // 同上
            console.log($('ul').children('.danger'));
    
            // parent()
            console.log($('li').parent()); // jQuery.fn.init [ul, prevObject:...
    
            // last() 最后一个元素   prev:前一个元素
            console.log($('li').last().prev());  // jQuery.fn.init [li.danger
            console.log($('li').last().prevAll());
    
            // silbings:筛选给定的同胞同类元素(不包括给定元素本身)
            console.log($('li').siblings('li'));
            console.log($('#anchor').siblings('a'));  // jQuery.fn.init [a, prevObject..
    
            // 鼠标指向的li标签变大,移走后变小的选项卡效果
            $('li').hover(function () {
                $(this).addClass('active').siblings('li').removeClass('active');
            })
        })
    </script>
    </html>
    

    二、应用筛选方法实现选项卡

      选项卡这种效果在网页中应用非常多,效果如下图所示:

       

      示例代码如下所示:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>    
            <style type="text/css">
                *{padding: 0;margin: 0;}
                ul{
                    list-style: none;
                }
                /*清除浮动产生的问题
                浮动产生的原因:父级元素没有填充高度以及填充的时候父级撑不开,导致子级元素浮动*/
                #box:after{   /*伪类选择器*/
                    content: "";
                    display: block;
                    clear: both;  /* 盒子左右两边都不浮动 */
                }
                #box{width: 800px;border: 1px solid black;margin: 20px auto;background: blue;}
                #leftBox{width: 200px;float: left;}
                #leftBox li{width: 200px;height: 89px;background: red;margin-bottom: 2px;color: white;font: 50px/89px "黑体";  text-align: center;}
                #rightBox div{display: none;float: left; width: 600px;}
                #rightBox p{width:100%;height: 325px;font: 100px/325px "黑体";text-align: center;background: greenyellow }
                /* font:100px/325px; 代表font-size:100px;line-height:325px;  垂直居中*/
                /*text-align:center; 代表中心对齐*/
    
    
                /*父元素设置display:table使它成为一个块级表格元素
                 * 子元素设置display:table-cell使子元素成为表格单元格,就好比是在表格中一样*/
                #rightBox ul{width: 600px;display: table;}
                #rightBox li{display: table-cell;background: purple;height: 40px;border-right: 2px solid blue;font: 30px/40px "黑体";text-align: center;color: white;}
    
                #leftBox .active{background: yellow;color: black;}
                #rightBox .active{background: white;color: black;}
                
            </style>
        </head>
        <body>
            <div id="box">
                <ul id="leftBox">
                    <li>a</li>
                    <li>b</li>
                    <li>c</li>
                    <li>d</li>
                </ul>
                <div id="rightBox">
                    <div style="display: block">
                        <p>a1</p>
                        <ul>
                            <li class="active">a1</li>
                            <li>a2</li>
                            <li>a3</li>
                            <li>a4</li>
                        </ul>
                    </div>
                    <div>
                        <p>b1</p>
                        <ul>
                            <li class="active">b1</li>
                            <li>b2</li>
                            <li>b3</li>
                            <li>b4</li>
                        </ul>
                    </div>
                    <div>
                        <p>c1</p>
                        <ul>
                            <li class="active">c1</li>
                            <li>c2</li>
                            <li>c3</li>
                            <li>c4</li>
                            <li>c5</li>
                            <li>c6</li>
                        </ul>
                    </div>
                    <div>
                        <p>d1</p>
                        <ul>
                            <li class="active">d1</li>
                            <li>d2</li>
                            <li>d3</li>
                            <li>d4</li>
                        </ul>
                    </div>
                </div>
            </div>
            
        </body>
        <script src="jquery-3.3.1.js"></script>
        <script type="text/javascript">
            $(function(){
                //鼠标移入的时候
                $('#leftBox li').mouseover(function(){
                    //修改自己的样式   siblings:选到本身以外其他兄弟元素,去除active类对应的样式
                    $(this).addClass('active').siblings('li').removeClass('active');
                    
                    //修改右边的div
                    console.log($(this).index()); // 利用$(this).index()取当前对象的索引,输出:0123
                    // eq(index):获取第N个元素的筛选方法  showhide方法控制元素显示隐藏
                    $('#rightBox div').eq($(this).index()).show().siblings('div').hide();
                    
                })
                
                $('#rightBox li').click(function(){
                    $(this).addClass('active').siblings('li').removeClass('active');
                    
                    var liValue  = $(this).html();  // 得到对应<li>标签的值
    
                    // 找到li元素的父元素的前一个元素————<p>  给<p>设置html值
                    $(this).parent().prev().html(liValue);
                })
                
            })
            
        </script>
    </html>
    选项卡代码示例

    1、使用:after伪元素解决经典清除浮动的问题

      浮动产生的原因:父级元素没有填充高度以及填充的时候父级撑不开,导致子级元素浮动

    #box:after{   /*伪类选择器*/
        content: "";
        display: block;
        clear: both;  /* 盒子左右两边都不浮动 */
    }
    

    2、注意font:100px/325px; 这种特殊写法

    #rightBox p{100%;height: 325px;font: 100px/325px "黑体";text-align: center;background: greenyellow }
    /* font:100px/325px;代表  font-size:100px;  line-height:325px;  垂直居中*/
    /*text-align:center; 代表中心对齐*/
    

    3、display: table;  和 display: table-cell;  

    /*父元素设置display:table使它成为一个块级表格元素
     * 子元素设置display:table-cell使子元素成为表格单元格,就好比是在表格中一样*/
    #rightBox ul{ 600px;display: table;}
    #rightBox li{display: table-cell;background: purple;height: 40px;border-right: 2px solid blue;font: 30px/40px "黑体";text-align: center;color: white;}
    

    4、$(this).index()可以得到当前对象的索引。两边的元素可以通过索引和eq()方法进行联动:

    // eq(index):获取第N个元素的筛选方法  showhide方法控制元素显示隐藏
    $('#rightBox div').eq($(this).index()).show().siblings('div').hide();

    5、选项卡实现原理:监听鼠标移入事件,触发事件后选到当前被移入的元素,用addClass添加类以此来添加样式,再用siblings选到其他兄弟元素,去除类以此来去除样式。 

    $(function(){
        //鼠标移入的时候
        $('#leftBox li').mouseover(function(){
            //修改自己的样式   siblings:选到本身以外其他兄弟元素,去除active类对应的样式
            $(this).addClass('active').siblings('li').removeClass('active');
            
            //修改右边的div
            console.log($(this).index()); // 利用$(this).index()取当前对象的索引,输出:0123
            // eq(index):获取第N个元素的筛选方法  showhide方法控制元素显示隐藏
            $('#rightBox div').eq($(this).index()).show().siblings('div').hide();
        })
        
        $('#rightBox li').click(function(){
            $(this).addClass('active').siblings('li').removeClass('active');
            
            var liValue  = $(this).html();  // 得到对应<li>标签的值
            // 找到li元素的父元素的前一个元素————<p>  给<p>设置html值
            $(this).parent().prev().html(liValue);
        })  
    })

    6、类似的点击右下方按钮,切换显示内容。是通过parent()方法找到当前元素的父级元素ul,再通过prev()方法定位到元素p,再通过html()方法赋值,修改显示内容。

    var liValue  = $(this).html();  // 得到对应<li>标签的值
    
    // 找到li元素的父元素的前一个元素————<p>  给<p>设置html值
    $(this).parent().prev().html(liValue);
    

    三、小米官网案例——鼠标移动弹出对应文档介绍  

      小米网介绍弹出效果如下所示:

        

      弹出效果代码示例如下:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                /* 清除默认样式 */
                *{
                    padding: 0;
                    margin: 0;
                }            
                ul{list-style: none;}
    
                .wrap{width: 980px;height: 612px;margin: 20px auto 0px;background: #f4f3f4;border: 1px solid gray;}
            
                ul li{float: left;margin-left: 10px;position: relative;overflow: hidden;/*超出部分隐藏*/width: 233px;height: 300px;}
            
                ul li p{    
                    width: 233px;
                    height: 100px;
                    background: rgba(245,102,51,.7);
                    position: absolute;
                    bottom: -100px;  /*将p标签里的内容盖住了*/
                    text-align: center;
                    color: white;
                    line-height: 100px;
                    
                }
            </style>
        </head>
        <body>
            <div class="wrap">
                <ul>
                    <li><a href="#"><img src="images/xiaomi_01.png"/></a><p>百度一下,你就知道</p></li>
                    <li><a href="#"><img src="images/xiaomi_02.png"/></a><p>百度一下,你就知道</p></li>
                    
                    <li><a href="#"><img src="images/xiaomi_03.png"/></a><p>百度一下,你就知道</p></li>
                    <li><a href="#"><img src="images/xiaomi_04.png"/></a><p>百度一下,你就知道</p></li>
                    <li><a href="#"><img src="images/xiaomi_05.png"/></a><p>百度一下,你就知道</p></li>
                    <li><a href="#"><img src="images/xiaomi_07.png"/></a><p>百度一下,你就知道</p></li>
                    <li><a href="#"><img src="images/xiaomi_08.png"/></a><p>百度一下,你就知道</p></li>
                    <li><a href="#"><img src="images/xiaomi_09.png"/></a><p>百度一下,你就知道</p></span></li>
                </ul>
            </div>
        </body>
        <script src="./jquery-3.3.1.js"></script>
        <script type="text/javascript">
            
            //mouseenter进入调用,mouseleave离开调用————这两个方法实现hover
            $('.wrap li').hover(function(){
                // 第一个回调函数是mouseenter方法的实现
                // stop():在鼠标移入移出的时,在激活动画前,先停止动画,解决快速移动鼠标时,钢琴效果
                $(this).children('p').stop(true).animate({bottom:0},100);
                
            },function(){
                // 第二个回调函数是mouseleave方法的实现
                $(this).children('p').stop(true).animate({bottom:-100},100); // 将p标签内容再次盖住
                
            })
            
        </script>
    </html>
    小米官网介绍弹出代码示例

    1、<div>下有<ul>,<ul>下有<li>,每个<li>中包含一个<a><img/></a>和一个<p>。因此给li设置相对定位,且overflow:hidden;来隐藏超出部分。同时给<p>设置绝对定位,并设置bottom:-100px;超出<li>范围,达到将p标签的内容盖住的效果。

    2、hover() 方法规定当鼠标指针悬停在被选元素上时要运行的两个函数。hover方法触发 mouseenter mouseleave 事件。

    // 语法
    $(selector).hover(inFunction,outFunction)
    
    //mouseenter进入调用,mouseleave离开调用————这两个方法实现hover
    $('.wrap li').hover(function(){
        // 第一个回调函数是mouseenter方法的实现
        $(this).children('p').animate({bottom:0},100);
        
    },function(){
        // 第二个回调函数是mouseleave方法的实现
        $(this).children('p').animate({bottom:-100},100); // 将p标签内容再次盖住
    })
    

    3、上述代码虽然实现了<p>标签弹出的效果,但是快速移动鼠标时,会发现多个标签都处于弹出收回状态,产生波浪效果。

      因此使用stop()方法:在鼠标移入移出时,先停止动画。

    $('.wrap li').hover(function(){
        // 第一个回调函数是mouseenter方法的实现
        // stop():在鼠标移入移出的时,在激活动画前,先停止动画,解决快速移动鼠标时,钢琴效果
        $(this).children('p').stop(true).animate({bottom:0},100);
    
    },function(){
        // 第二个回调函数是mouseleave方法的实现
        $(this).children('p').stop(true).animate({bottom:-100},100); // 将p标签内容再次盖住
    })
    

      

    四、焦点轮播图

       要实现的焦点轮播图效果如下所示:

       

    代码示例如下所示:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                /*清除默认样式*/
                *{padding: 0;margin: 0;}
                ul,ol{list-style: none;}
                
                #wrap{width: 650px;height: 250px;margin: 100px auto 0;background: red;overflow: hidden;position: relative;}
                /*#wrap img{display: block;}*/
                #wrap ul{height: 250px;position: relative;z-index: 1;}
                #wrap ol{height: 30px;position: absolute;z-index: 2;bottom: 0;right: 0;}
                /*通过z-index调整层级关系,显现出1、2、3、4按钮*/
                #wrap>ul>li{  /* 子代选择器,配置的<li>样式区分ul下或ol下 */
                    position: absolute;
                    top:0;
                    left: 0;
                }
                
                #wrap>ol>li{
                    float: left;
                    width: 20px;
                    height: 20px;
                    text-align: center;
                    line-height: 20px;
                    border: 1px solid white;
                    background: gray;
                    margin-right: 5px;
                }
                #wrap>ol>li:hover{
                    /*设置鼠标形状*/
                    cursor: pointer;
                }
                
                #wrap li.active{  /* 切换到对应li显示效果不同(鼠标移动上去,抬起效果) */
                    padding: 2px;
                    color: orange;
                    margin-top: -4px;
                    border: 1px solid orange;
                }            
            </style>
        </head>
        <body>
            <div id="wrap">
                <ul>
                    <!--设置绝对定位之后 脱离标准流 最后一个盒子层级提升了,
                    为了默认显示第一张图而不是最后一张图,给第一个li设置z-index -->
                    <li style="z-index: 1;"><a href="#"><img src="./images/01.jpg"/></a></li>
                    <li><a href="#"><img src="./images/02.jpg"/></a></li>
                    <li><a href="#"><img src="./images/03.jpg"/></a></li>
                    <li><a href="#"><img src="./images/04.jpg"/></a></li>
                    <li><a href="#"><img src="./images/05.jpg"/></a></li>            
                    
                </ul>
                <ol>
                    <li class="active">1</li>
                    <li>2</li>
                    <li>3</li>
                    <li>4</li>
                    <li>5</li>
                </ol>
                
            </div>
        </body>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
        <script type="text/javascript">
            $(function(){
                
                //控制层级关系的索引
                var index  = 0;
    
                $('#wrap>ol>li').mouseenter(function(){
    
                    index++;  // 鼠标移进去时,不管是移动哪一个,都会自增
    
                    //修改下标
                    //当前li对象》添加active类来修改样式》取到每个li同胞》删除active类,取消同胞的样式
                    $(this).addClass('active').siblings('li').removeClass('active');
                    
                    //修改图片
                    //选取到ul下的所有li对象》eq取到当前下标对应的索引》修改样式,设置z-index覆盖其他li 》animate完成动画效果1秒内移动覆盖
                    $('#wrap>ul>li').eq($(this).index()).css({left:650,'z-index':index}).animate({
                        left: 0   // 这里不设置left:0的话,li都位于left:650(图片展示的位置确实是left:0)
                    },1000)
                })
                
                
                
            })
            
        </script>
    </html>
    焦点轮播图代码示例

    分析轮播图实现:

      1、轮播图是由同级的ul和ol组成他们的父级div。div设置了相对定位和overflow:hidden;因此超出div的部分会被隐藏。

    #wrap{ 650px;height: 250px;margin: 100px auto 0;background: red;overflow: hidden;position: relative;}

      2、z-index的设置是实现轮播图的关键要素,其中ul>li设置绝对定位之后 脱离标准流 最后一个盒子层级提升了,为了默认显示第一张图而不是最后一张图,给第一个li设置z-index

    <li style="z-index: 1;"><a href="#"><img src="./images/01.jpg"/></a></li>
    <li><a href="#"><img src="./images/02.jpg"/></a></li>
    <li><a href="#"><img src="./images/03.jpg"/></a></li>
    <li><a href="#"><img src="./images/04.jpg"/></a></li>
    

      3、通过鼠标移入ol>li标签来切换轮播图,这需要mouseenter方法实现。同时被鼠标指向的li标签样式将发生改变。

    //修改下标
    //当前li对象》添加active类来修改样式》取到每个li同胞》删除active类,取消同胞的样式
    $(this).addClass('active').siblings('li').removeClass('active');
    

      4、鼠标指向ol的li标签,li标签的样式更改,但是同时还需要修改到对应的图片。需要用eq($(this).index())来取到对应的索引值。

    //修改图片
    //选取到ul下的所有li对象》eq取到当前下标对应的索引》修改样式,设置z-index覆盖其他li 》animate完成动画效果1秒内移动覆盖
    $('#wrap>ul>li').eq($(this).index()).css({left:650,'z-index':index}).animate({
        left: 0   // 这里不设置left:0的话,li都位于left:650(图片展示的位置确实是left:0)
    },1000)
    

      5、需要设置一个控制层级关系的索引:var index= 0;每次鼠标移入都自增一次,保证从头到尾指向一遍后,再指向前面的li标签,均能够保证z-index的值最大能够正常覆盖。注意$(this).index()和index变量的区别。

    //控制层级关系的索引
    var index  = 0;
    
    $('#wrap>ol>li').mouseenter(function(){
    
        index++;  // 鼠标移进去时,不管是移动哪一个,都会自增
        //修改下标
        //当前li对象》添加active类来修改样式》取到每个li同胞》删除active类,取消同胞的样式
        $(this).addClass('active').siblings('li').removeClass('active');
        
        //修改图片
        //选取到ul下的所有li对象》eq取到当前下标对应的索引》修改样式,设置z-index覆盖其他li 》animate完成动画效果1秒内移动覆盖
        $('#wrap>ul>li').eq($(this).index()).css({left:650,'z-index':index}).animate({
            left: 0   // 这里不设置left:0的话,li都位于left:650(图片展示的位置确实是left:0)
        },1000)
        console.log($(this).index());
        console.log(index);
    })
    

      

    五、动态实现轮播图

      前面焦点轮播图实现了点选的方式实现图片轮播,这种显示效果过于呆板,还需要添加动态轮播功能。显示效果如下所示:

        

      点击轮播按钮,图片开始自动轮播,点击暂停按钮,图片轮播停止,显示停止在当前图片。代码示例如下所示:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                *{padding: 0;margin: 0;}
                ul{list-style: none;}
                
                #box{
                    /*图片的宽高 240px  180px*/
                    width: 240px;
                    height: 180px;
                    position: relative;
                    margin: 50px auto;
                    /*overflow 属性规定当内容溢出元素框时发生的事情
                        hidden:内容会被修剪,并且其余内容是不可见的*/
                    overflow: hidden;
                }
                
                ul{
                    width: 960px;  /* 240*4=960 */
                    position: absolute;
                }
                ul li{
                    /*左浮动之后,所有图片都在一排展示*/
                    float: left;
                }
                p {
                    position: absolute;
                    left: 80px;
                    bottom: 30px;
                }
    
                p  span {
                    color: red;
                    display: inline-block;
                    width: 20px;
                    height: 20px;
                    line-height: 20px;
                    text-align: center;
                    /*cursor 属性规定要显示的光标的类型(形状)
                    pointer:光标呈现为指示链接的指针(一只手)*/
                    cursor: pointer;
    
                }
                 p span.active {
                    color: white;
                     background: green;   /*背景颜色*/
                }
            
                
            </style>
        </head>
        <body>
            <div id="box">
                <ul>
                    <!--显示轮播的图片-->
    
                    
                </ul>
                <p>
                    <!--显示索引-->
                </p>
    
                
            </div>
            <button id="play">轮播吧!</button>
            <button id="stop">暂停!</button>
            
        </body>
        <script src="jquery-3.3.1.js"></script>
        <script type="text/javascript">
            $(function(){
                
                //1.获取本地的图片数据 以后再后面的课程中这些数据会从后端服务器获取
                var imgArr = ['./01.jpg','./02.jpg','./03.jpg','./04.jpg'];
                
                //2.动态的生成图片
                for(var i = 0; i < imgArr.length;i++){
                    // 字符串拼接实现动态添加标签
                    $('ul').append("<li><img src="+imgArr[i]+"></li>")
                }
    
                //3.生产索引
                var str = '';
                // each(function(index,element))为每个匹配的元素规定运行的函数
                $('li').each(function (i,ele) {
                    str += "<span>"+(i+1)+"</span>";
                })
                console.log(str);  // <span>1</span><span>2</span><span>3</span><span>4</span>
                $('p').html(str);
    
                // 4.默认设置索引的一个active
                $('span:first').addClass('active');
    
                var index = 0;  // index定义为全局变量
    
                // 5.点击索引
                $('span').click(function () {
                    $(this).addClass('active').siblings('span').removeClass('active');   // 点选到的按钮修改样式
    
                    // 获取我当前点击的索引
                    index = $(this).index();   // 设为全局变量
                    //方法1:
                    // $('ul').css('left',-240*index);  // 所有图片都在一排,依次排列
                    //方法2:
                    $('ul').animate({
                        left: -240*index
                    },100)
                })
    
    
                // 6.自动轮播
                var timer = null;
    
                $('#play').click(function () {
                    // 开启定时器: 1.索引跟着走;2.图片跟着走。
                    timer = setInterval(next,1000);
                    function next() {
                        // console.log(index++);
    
                        if(index == $('li').length-1) {
                            // 图片结尾了。第四张了
                            index = 0;
                            // 修改span标签的第一个active
                            $('p span').eq(index).addClass('active').siblings('span').removeClass('active');
                            // 修改ul的样式
                            $('ul').css('left',0);
    
                        } else {
                            index++;
                            // 修改后三个span标签的active
                            $('p span').eq(index).addClass('active').siblings('span').removeClass('active');
                            // 修改ul的样式
                            $('ul').css('left',-240*index);
                        }
                    }
    
                })
    
                // 7.暂停轮播
                $('#stop').click(function () {
                    clearInterval(timer);
                })
                
            })
        
        </script>
    </html>
    动态轮播图代码示例

    动态轮播图实现要点:

      1、在html代码中并没有在ul下添加li标签,而是通过字符串拼接动态添加标签。把拼接时需要的图片存放在数组中。ul>li标签css样式都设置了左浮动,因此所有图片在一排展示。overflow 属性规定当内容溢出元素框时发生的事情;hidden:内容会被修剪,并且其余内容是不可见的。

    //1.获取本地的图片数据 以后再后面的课程中这些数据会从后端服务器获取
    var imgArr = ['./01.jpg','./02.jpg','./03.jpg','./04.jpg'];
    
    //2.动态的生成图片
    for(var i = 0; i < imgArr.length;i++){
        // 字符串拼接实现动态添加标签
        $('ul').append("<li><img src="+imgArr[i]+"></li>")
    }
    

      2、html代码中p标签内也是空的,也是利用字符串拼接动态添加span标签,添加图片索引序号。

    //3.生产索引
    var str = '';
    // each(function(index,element))为每个匹配的元素规定运行的函数
    $('li').each(function (i,ele) {
        str += "<span>"+(i+1)+"</span>";
    })
    console.log(str);  // <span>1</span><span>2</span><span>3</span><span>4</span>
    $('p').html(str);
    

      3、同经典轮播图类似,给p>span标签里的这些图片索引,设置active样式,默认给第一个标签添加active类。

    // 4.默认设置索引的一个active
    $('span:first').addClass('active');
    
    p span.active {
         color: white;
         background: green;   /*背景颜色*/
    }
    

      4、使用click()方法来设置点选到<span>标签切换轮播图,由于所有图片都是在一行排列,因此通过 left: -240*index; 这种方法把图片偏移到div显示范围内展示。

    // 5.点击索引
    $('span').click(function () {
        $(this).addClass('active').siblings('span').removeClass('active');   // 点选到的按钮修改样式
    
        // 获取我当前点击的索引
        index = $(this).index();
        //方法1:
        // $('ul').css('left',-240*index);  // 所有图片都在一排,依次排列
        //方法2:
        $('ul').animate({
            left: -240*index
        },100)
    })
    

      5、点击按钮开始轮播,启动定时器setInterval()方法可以按照指定的周期(毫秒计)来调用函数或计算表达式。

      在函数next中,在index的值等于图片索引长度-1时,说明图片结尾了,轮播到第四张图片了,需要设定第一个span标签为active,ul的样式修正为第一张图显示:$('ul').css('left',0);其他情况下,则是为当前index的span添加为active类,给它的其他兄弟删除active,$('ul').css('left',-240*index);修改ul样式,展现当前图片。

    // 6.自动轮播
    var timer = null;
    
    $('#play').click(function () {
        // 开启定时器: 1.索引跟着走;2.图片跟着走。
        timer = setInterval(next,1000);
        function next() {
            // console.log(index++);
    
            if(index == $('li').length-1) {
                // 图片结尾了。第四张了
                index = 0;
                // 修改span标签的第一个active
                $('p span').eq(index).addClass('active').siblings('span').removeClass('active');
                // 修改ul的样式
                $('ul').css('left',0);
    
            } else {
                index++;
                // 修改后三个span标签的active
                $('p span').eq(index).addClass('active').siblings('span').removeClass('active');
                // 修改ul的样式
                $('ul').css('left',-240*index);
            }
        }
    })

      6、setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。因此停止轮播使用clearInterval方法。

    // 7.暂停轮播
    $('#stop').click(function () {
        clearInterval(timer);
    })
    

      

    六、jQuery的事件

    1、事件的概念  

      HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件、页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。

    2、事件流

      事件流描述的是从页面中接收事件的顺序

      “DOM2级事件”规定的事件流包括三个阶段:(1)事件捕获阶段;(2)处于目标阶段;(3)事件冒泡阶段。

    事件流演示代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件流</title>
        <script>
    
        window.onload = function(){
            // 取到DOM元素 js的DOM对象
            var oBtn = document.getElementById('btn');
    
            // addEventListener添加事件侦听器
            // 第一个参数:click事件的名字  第二个参数:回调函数 触发事件发生的事情
            // 第三个参数:true/false  true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序
            oBtn.addEventListener('click',function(){
                console.log('btn处于事件捕获阶段');
            }, true);
            oBtn.addEventListener('click',function(){
                console.log('btn处于事件冒泡阶段');
            }, false);
    
            // 为文档增加事件
            document.addEventListener('click',function(){
                console.log('document处于事件捕获阶段');
            }, true);
            document.addEventListener('click',function(){
                console.log('document处于事件冒泡阶段');
            }, false);
    
    
            // 为文档元素增加事件
            document.documentElement.addEventListener('click',function(){
                console.log('html处于事件捕获阶段');
            }, true);
            document.documentElement.addEventListener('click',function(){
                console.log('html处于事件冒泡阶段');
            }, false);
    
            // 为body增加事件
            document.body.addEventListener('click',function(){
                console.log('body处于事件捕获阶段');
            }, true);
            document.body.addEventListener('click',function(){
                console.log('body处于事件冒泡阶段');
            }, false);
    
        };
    
        </script>
    </head>
    <body>
        <a href="javascript:;" id="btn">按钮</a>
    </body>
    </html>
    

      在浏览器上执行代码,控制台输出如下:

    document处于事件捕获阶段
    html处于事件捕获阶段
    html处于事件冒泡阶段
    document处于事件冒泡阶段
    <!--点击按钮后-->
    document处于事件捕获阶段
    html处于事件捕获阶段
    body处于事件捕获阶段
    btn处于事件捕获阶段
    btn处于事件冒泡阶段
    body处于事件冒泡阶段
    html处于事件冒泡阶段
    document处于事件冒泡阶段

    3、addEventListener

      addEventListener 是DOM2 级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

    4、document、documentElement、document.body三者间的关系

      document代表的是整个html页面

      document.documentElement代表的是<html>标签

      document.body代表的是<body>标签

    5、分析上述事件流示例代码及输出结果

      在标准的“DOM2级事件”中规定,事件流首先是经过事件捕获阶段,接着是处于目标阶段,最后是事件冒泡阶段。示意图如下所示:

      首先在事件捕获过程中,document对象首先接收到click事件,然后事件沿着DOM树依次向下,一直传播到事件的实际目标,就是id为btn的a标签。

      接着在事件冒泡过程中,事件开始时由最具体的元素(a标签)接收,然后逐级向上传播到较为不具体的节点(document)。

      需要注意的点:由于老版本的浏览器不支持事件捕获,因此在实际开发中需要使用事件冒泡,在由特殊需要时再使用事件捕获。

    补充:

      1、IE中的事件流只支持“事件冒泡”,但是版本到了IE9+以后,实现了“DOM2级事件”,也就是说IE9+以后也可以在捕获阶段对元素进行相应的操作。

      2、在DOM事件流中,实际的目标在“捕获阶段”不会接收到事件。而是在“处于目标阶段”被触发,并在事件处理中被看成“冒泡阶段”的一部分。然后,“冒泡阶段”发生,事件又传播回文档。

      3、jquery不支持事件捕获阶段,只支持事件冒泡。

     6、jQuery的事件流程导图

      jQuery的事件流程导图地址:https://www.processon.com/view/link/5ad1c48de4b0b74a6dd65426

     

    七、jQuery的事件对象和事件冒泡

    1、什么是事件冒泡

      在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序或者事件返回true,那么这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活),或者它到达了对象层次的最顶层,即document对象(有些浏览器是window)。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="box">
            <button>点击</button>
        </div>
    </body>
    <script src="jquery-3.3.1.js"></script>
    <script type="text/javascript">
        $('button').click(function () {
            // 冒泡:在页面上仅点击了button。先触发了button的alert,后触发了box的alert。因此冒泡影响了页面效果。
            // 需要阻止冒泡
            alert('button事件触发了');
        })
        $('#box').click(function () {
            alert('22222');
        })
    </script>
    
    </html>
    事件冒泡代码示例

      在上例中,在页面上仅点击了button。先是触发了button的alert,随后又自动触发了box的alert,由此可以看出冒泡激活我们本来不想激活的事件,影响了页面效果。所以必要时,要阻止事件冒泡

    2、事件对象的常见属性

    // ev事件对象
    $('.p1').click(function (ev) {
        // 事件类型、事件属性
        console.log(ev.type);   //获取事件的类型:click
        console.log(ev.target);  //获取事件发生的DOM对象:<p class:'p1'></p
        console.log(ev.pageX);   //获取到光标相对于页面的x的坐标: 50
        console.log(ev.pageY);   //获取到光标相对于页面的y的坐标: 63
        console.log(ev.which);  //鼠标单击事件中获取到鼠标的键,键盘事件中获取键盘的按键: 1
    

    3、事件冒泡的常用事件

    (1)阻止事件冒泡:e.stopPropagation()方法

    (2)阻止默认行为:e.preventDefault()方法

    (3)return false在jQuery中可以阻止事件冒泡和默认事件;jQuery不支持事件捕获。

    $('a').click(function (ev) {
        //方法一:同时阻止默认事件和冒泡事件
        ev.preventDefault();    // 阻止默认事件
        ev.stopPropagation();   // 再阻止冒泡事件
        alert('不再跳转页面');
    
        // 方法二:
        return false;  // 这个可以阻止a标签的默认事件和冒泡事件
    })
    

      jQuery的事件对象和事件冒泡示例代码如下:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                #box{
                    width: 200px;
                    height: 200px;
                    background: gray;
                }
                
                p{
                    width: 100px;
                    height: 100px;
                    background: red;
                }
            </style>
        </head>
        <body>
            <div id="box">
                <p class="p1"></p>
                
                
                <a href="https://www.luffycity.com">luffy</a>
                
            </div>
        </body>
        <script src="jquery-3.3.1.js"></script>
        <script type="text/javascript">
    
            //入口函数事件
            $(function () {
    
                // ev事件对象
                $('.p1').click(function (ev) {
                    // 事件类型、事件属性
                    console.log(ev.type);   //获取事件的类型:click
                    console.log(ev.target);  //获取事件发生的DOM对象:<p class:'p1'></p
                    console.log(ev.pageX);   //获取到光标相对于页面的x的坐标: 50
                    console.log(ev.pageY);   //获取到光标相对于页面的y的坐标: 63
                    console.log(ev.which);  //鼠标单击事件中获取到鼠标的键,键盘事件中获取键盘的按键: 1
    
                    alert('当前按钮事件触发了');
                    // 常用的事件  方法:1.阻止事件冒泡   2.阻止默认事件
    
                    // 1.阻止事件冒泡,不再传到div中
                    ev.stopPropagation();
    
                })
                $('#box').click(function () {
                    alert('#box盒子事件触发了');
                })
    
                $('a').click(function (ev) {
                    // 阻止a标签的默认事件
                    ev.preventDefault();
                    // 再阻止冒泡
                    ev.stopPropagation();
                    alert('不再跳转页面');
    
                    // 方法二:
                    return false;  // 这个可以阻止a标签的默认事件和冒泡事件
                })
            })
            
        </script>
        
    </html>
    事件对象和事件冒泡验证代码示例

    八、事件的绑定和移除

    1、给当前dom添加事件有两种方法

    // 方式一:给当前dom元素添加click事件
    $('#box').click(fn);
    
    // 方式二:给当前的dom元素绑定事件 bind()
    // 语法:jquery对象.bind('事件类型',fn)
    $('#box').bind('click mouseenter', function () {
        alert('事件被绑定了')
    })
    

    2、详解事件和函数绑定到元素——bind()绑定方法

      语法:$(selector).bind(event,data,function)  

      参数:第一个参数是事件类型,常用click,blur,hover等;多个事件类型可以通过将每个空格分隔开来一次绑定。

             可以通过传递事件类型/处理程序对的对象来同时绑定多个事件处理程序

         第二个参数是可选参数,作为envet.data属性值传递给事件对象的额外数据对象

           第三个参数是用来绑定的处理函数

    function add() {
        console.log('click');
    }
    function add2() {
        console.log('mouse-over')
    }
    // 给jquery对象添加不同的事件
    $('#box').bind({
        'click': add,
        'mouseenter':add2
    })
    

      完成上述代码后,点击盒子则执行add函数,移入盒子则执行add2函数。

    3、移除事件——unbind()

      语法:unbind(type,fn)

      第一个参数:事件类型。如果不写参数,移除所有的事件:

    // 如果没有参数表示移除所有事件
    $('#box').unbind();
    

      第二个参数:将要移除的函数

    $( "#foo").unbind( "click" ,function(){})
    

    4、事件代理

      所谓事件就是onclickonmouseoveronmouseout等事件,委托就是让别人来做。这个事件本来是加在某些元素上,却加到别人身上来完成这个事件

      原理:利用冒泡的原理,把事件加到父级上,触发执行效果。

      事件代理(委托)使用情景:

      (1)为DOM中的很多元素绑定相同事件:事件注册在祖先级元素上,代理其子级元素。可以减少事件注册数量,节约内存开销,提高性能。

      (2)为DOM中尚不存在的元素绑定事件:对js动态添加的子元素可自动绑定事件。

      事件代理作用:

      (1)性能比较好;(2)针对新创建的元素,直接可以拥有事件。

      事件源:跟this作用一样(不用看指向问题,谁操作的就是谁),event对象的。

    // 后续添加的事件不能发生在未来==》动态生产的元素不能直接添加对象,里面的事件也不能发生==》事件代理
    $('body').append('<div style=" 200px;height: 300px;background-color: yellow">哈哈哈哈</div>')
    
    //绑定自定义的事件
    $('button').bind('myclick',function (ev,a,b,c) {
        alert(111);
    
        alert(a);  // 1
        alert(b);  // 2
        alert(c);  // 3
    })
    
    // 触发自定义的事件
    $('button').trigger('myclick',[1,2,3])
    

      动态添加元素div,绑定自定义事件后必须运用trigger()方法来触发自定义事件。

    事件绑定和移除的示例代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件绑定和移除</title>
        <style type="text/css">
            #box {
                width: 200px;
                height: 200px;
                background: red;
            }
        </style>
    </head>
    <body>
        <div id="box">
    
        </div>
        <button>按钮</button>
    </body>
    <script src="jquery-3.3.1.js"></script>
    <script type="text/javascript">
        $(function () {
    
            // 给当前dom元素添加click事件:方式一如下
            // $('#box').click(fn);
    
            // 方式二:给当前的dom元素绑定事件 bind()
            // 语法:jquery对象.bind('事件类型',fn)
            // $('#box').bind('click mouseenter', function () {
            //     alert('事件被绑定了')
            // })
    
            function add() {
                console.log('click');
            }
            function add2() {
                console.log('mouse-over')
            }
            // 给jquery对象添加不同的事件
            $('#box').bind({
                'click': add,
                'mouseenter':add2
            })
    
            // 事件移除  unbind()
            setTimeout(function () {
                // 如果没有参数表示移除所有事件
                // $('#box').unbind();
    
                $('#box').unbind('click');
            },3000)
    
            // 后续添加的事件不能发生在未来==》动态生产的元素不能直接添加对象,里面的事件也不能发生==》事件代理
            $('body').append('<div style=" 200px;height: 300px;background-color: yellow">哈哈哈哈</div>')
    
            //绑定自定义的事件
            $('button').bind('myclick',function (ev,a,b,c) {
                alert(111);
    
                alert(a);  // 1
                alert(b);  // 2
                alert(c);  // 3
            })
    
            // 触发自定义的事件
            // $('button').trigger('myclick',[1,2,3])
        })
    </script>
    </html>
    事件的绑定和移除代码示例

    九、事件代理详解(on/delegate/bind)

      事件代理:自己完成不了当前的点击事件,交给父级元素来做这件事情。  

      上一节中用bind函数将click事件绑定到对象上,从而实现了事件代理。还有其他事件代理方法:on和delegate等。

      on方法和delegate方法基本相同,区别仅在于参数:

    on(绑定事件,选择器,回调函数) 
    delegate(绑定的选择器,绑定事件,回调函数)
    

      on方法语法如下:

    父级.on('事件名字','点击当前的标签元素',fn)
    

      .on在选择元素上绑定一个或多个事件:

    //事件代理   自己完成不了当前的点击事件,交给父级元素来做这件事情
    //父级.on('事件名字','点击当前的标签元素',fn)  第二个参数其实是选择器
    // $('ul').on('click','li',function () {
    $('ul').on('click','#namei,.luffy',function () {  // 绑定多个选择器:注意用逗号分隔
        console.log(this);
    })
    

      事件代理示例代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件代理</title>
    </head>
    <body>
    <ul>
        <li class="luffy">路飞</li>
        <li>路飞</li>
        <li>路飞</li>
    </ul>
    </body>
    <script src="jquery-3.3.1.js"></script>
    <script type="text/javascript">
        // 文档加载
        $(document).ready(function () {
            // ul下的每个li  先点击
            // $('ul>li').bind('click',function () {
            //     console.log($(this));    // 点击li会在控制台打印出对应的html标签信息
            // })
            //另一种写法:
            // $('ul>li').click(function () {
            //     console.log($(this));
            // })
    
            //事件代理   自己完成不了当前的点击事件,交给父级元素来做这件事情
            //父级.on('事件名字','点击当前的标签元素',fn)  第二个参数其实是选择器
            // $('ul').on('click','li',function () {
            $('ul').on('click','#namei,.luffy',function () {  // 绑定多个选择器:注意用逗号分隔
                console.log(this);
            })
    
            // 后来添加的元素
            $('ul').append('<li>娜美</li>');
            $('ul').append('<a id="namei">娜美</a>')
    
            // 其他事件代理方法:delegate(绑定的选择器,绑定事件,回调函数)
            // on(绑定事件,选择器,回调函数)  注意两者主要是参数的区别
        })
        
    </script>
    </html>
    事件代理示例代码

      $('ul').on('click','#nami, .luffy'.function) () {}  是绑定了两个选择器,两个选择器用逗号分隔。进在点击id=namei和class=luffy的元素时会在控制台打印相关信息:<li class="luffy">路飞</li>  、 <a id="namei">娜美</a>。

    十、鼠标事件

    1、鼠标点击

      click():鼠标单击触发事件,参数可选(data,fn)

    // 点击事件
    $('#box').click(function () {
        console.log('click');
    })

      dbclick():鼠标双击触发

    // 双击事件 dblclick
    $('#box').dblclick(function () {
        console.log('dbclick');
    })
    

      mousedown():鼠标按下触发事件

    // 鼠标按下不松开
    $('#box').mousedown(function () {
        console.log('mousedown');
    })

      mouseup():鼠标弹起触发事件

    // 鼠标松开触发
    $('#box').mouseup(function () {
        console.log('mouseup');
    })
    

    2、鼠标移动

      mouseover():鼠标移入触发事件;mouseout():鼠标移出触发事件。mouseover()/out()鼠标指针穿过/离开被选元素或者当前元素的子元素,会触发事件。

    //被选元素和子元素被选中时会触发函数 移入移出
    $('#box').mouseover(function () {
        console.log('mouseover')
    })
    $('#box').mouseout(function () {
        console.log('mouseout')
    })
    

      mouseenter():鼠标进入触发事件;mouseleave():鼠标离开触发事件。mouseenter()/leave()鼠标指针只在穿过/离开被选元素触发事件。

    // 鼠标指针只在穿过/离开被选元素触发事件
    $('#box').mouseenter(function () {
        console.log('mouseenter');
    })
    $('#box').mouseleave(function () {
        console.log('mouseleave');
    })
    

      mousemove():鼠标移动触发事件。实时监听鼠标移动事件(元素范围内) ————常用于做拖拽

    // 实时监听鼠标移动事件(元素范围内) ————常用于做拖拽
    $('#box').mousemove(function () {
        console.log('mousemove');
    })
    

    3、鼠标聚焦/失焦

      focus():鼠标聚焦触发事件;blur():鼠标失焦触发事件。

          

    // 鼠标聚焦/失去焦点触发事件(不支持冒泡)
    // 获焦:文本输入框边框变蓝色
    $('input[type=text]').focus(function () {
        console.log($(this).val());
    })
    
    // 在文本框修改123为其他字符,然后在input元素外点击,完成失焦,console打印出修改后的字符串
    $('input[type=text]').blur(function () {
        console.log($(this).val());
    })
    

    4、键盘按键

      keydown():键盘按键按下触发;keyup():键盘按键弹起触发。

    // keydown键盘按下
    $('input[type=password]').keydown(function () {
        console.log($(this).val())   // 最开始按下1是取的是空值
    })
    
    $('input[type=password]').keyup(function () {
        console.log($(this).val())   // 最开始按下1松开,取到了1
    })
    

      在这里需要注意,点击输入框用键盘输入时,按下取一次值,松开取一次值(这一次包含刚刚按下的键的值)。

          

     十一、表单事件

    1、change():表单元素发生改变时触发事件

    //change()事件————表单元素发生改变时触发事件
    //此事件仅限于input元素、textarea框、select元素。
    //对于选择框,复选框和单选按钮,当用户使用鼠标进行选择时,会立即触发事件。但对于其他元素类型,事件将延迟到元素失去焦点
    $('select').change(function(){
        console.log($('select option:selected').text());
    
        $('.show').text($('select option:selected').text());
    })
    

    2、select():文本元素发生改变时触发事件

    // select()事件————文本元素发生改变时触发事件
    // 仅限于用在input type=text 或 textarea  表单元素
    $('#other').select(function () {
        console.log($(this).val());
    })
    

      

    3、submit():表单元素发生改变时触发事件

    // form表单和服务端有很大的挂钩:form表单有默认的submit行为,当对input type=submit按钮点击的时候会触发form的默认action行为,
    // 此时可以调用 jquery的submit方法通过e.preventDefault()来阻止默认事件,这样我们就能动态的跟服务端来发送数据了
    $('form').submit(function (ev) {
        // alert(1111);  // 触发submit事件弹出1111,再触发form表单的默认行为跳转到路飞官网
    
        // 阻止默认事件
        ev.preventDefault();
        alert(1111);  // 只会触发submit事件弹出1111
    })
    

      表单事件代码示例:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Page Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <style>
        .show{
            color: red;
        }
        </style>
        
    </head>
    <body>
        <form action="https://www.luffycity.com">
            <select name="sweets" multiple=''>
                <option value="">巧克力</option>
                <option value="" selected=''>糖果</option>
                <option value="">焦糖</option>
                <option value="" selected=''>曲奇饼</option>
                <option value="">烧饼</option>
                <option value="">麦香饼</option>
                <option value="">曲奇饼2</option>       
            </select>
    
            <input type="text" value="hello" id='target'>
            <input type="submit" value="Luffy"/>
            <input type="button" value="按钮" />
            
        </form>
    
        <input id="other" type="text" value="Trigger the handler">
    
        <div class="show"></div>
    
        <script src="./jquery-3.3.1.js"></script>
    
        <script type="text/javascript">
    
            $(function() {
                
                
                //change()事件————表单元素发生改变时触发事件
                //此事件仅限于input元素、textarea框、select元素。
                //对于选择框,复选框和单选按钮,当用户使用鼠标进行选择时,会立即触发事件。但对于其他元素类型,事件将延迟到元素失去焦点
                $('select').change(function(){
                    console.log($('select option:selected').text());
    
                    $('.show').text($('select option:selected').text());
                })
    
                // select()事件————文本元素发生改变时触发事件
                // 仅限于用在input type=text 或 textarea  表单元素
                $('#other').select(function () {
                    console.log($(this).val());
                })
    
    
                // form表单和服务端有很大的挂钩:form表单有默认的submit行为,当对input type=submit按钮点击的时候会触发form的默认action行为,
                // 此时可以调用 jquery的submit方法通过e.preventDefault()来阻止默认事件,这样我们就能动态的跟服务端来发送数据了
                $('form').submit(function (ev) {
                    // alert(1111);  // 触发submit事件弹出1111,再触发form表单的默认行为跳转到路飞官网
    
                    // 阻止默认事件
                    ev.preventDefault();
                    alert(1111);  // 只会触发submit事件弹出1111
                })
    
                
            })
    
        </script>
        
    </body>
    </html>
    表单事件代码示例
  • 相关阅读:
    使用Swagger2构建强大的RESTful API文档(2)(二十三)
    使用Swagger2构建强大的RESTful API文档(1)(二十二)
    开发Web应用(2)(二十一)
    开发Web应用(1)(二十)
    RESTful API单元测试(十九)
    构建RESTful API(十八)
    Spring boot exe4j可执行exe与jre1.8捆绑
    Spring boot项目 jar转exe执行(exe4j)
    分布式消息事务一致性,以及rocketMq实现
    Linux node 安装
  • 原文地址:https://www.cnblogs.com/xiugeng/p/9190303.html
Copyright © 2011-2022 走看看