jQuery系统学习笔记

2019-12-16

<body>
    <div></div>
    <script src = './jquery.js'></script>
    <script>
        // css selector
        // 实例方法
        $('div').css({width:100,height:100,backgroundColor:'red'});
    
    </script>
    
</body>

$(’ ')里面可以放什么?
1.放css selector

$('.wrapper ul li')

2.jQ里面的选择器jquery unique selector

$('.wrapper ul:li:first').css({width:100,height:100,backgroundColor:'red'});//odd:奇数,even:偶数,eq(1):第一个;
$('li[date = 'duyi']');
$('li[date ^= 'duyi']');//选中
li中属性是date还必须以duyi结尾

3.ele传递原生dom,jQuery把原生dom包装成jq对象,使用方法$(ele).find().css();jQuery有容错机制,就算find里面传送空值,也不会报错,继续往下进行。

  var oDiv = document.getElementById('demo')
 $(oDiv).css({color:'red'});
//function
  //DOMContentLoaded

//页面所有东西加载完触发

  window.onload = function(){
     console.log('window.onload');
}

//第二个和第三个一样,都是在dom事件加载完成后触发,比第一个触发早。

$(function(){
console.log('DOMContentLoaded');
})
$(document).ready(function(){
console.log('DOMContentLoaded');
})

5.jQuery的原码
jQuery的三大精髓:选择元素,循环操作,链式调用;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div class="dome">1</div>
    <div class="dome">2</div>
    <div class="dome">8</div>
    <!-- <script src = './jquery.js'></script> -->
    <script>
      //jQuery库 :自己封闭自己的作用域
      //立即执行函数里面一个jQuery函数
      (function(){
          function jQuery(selector){
               return new jQuery.prototype.init(selector);
              
          }
          jQuery.prototype.init = function(selector){
              //this = {};
              //选出dom标签并且包装jQuery对象 返回
              //id class
              this.length = 0;
              if(selector.indexOf('.') != -1){
                  var dom = document.getElementsByClassName( selector.slice(1) );
              }else if(selector.indexOf('#') != -1){
                  var dom = document.getElementById( selector.slice(1) );
              }
              if(dom.length == undefined){
                  this[0] = dom;
                  this.length++;
              }else{
                  for(var i = 0;i<dom.length;i++){
                      this[i] = dom[i];
                      this.length++
                  }
              }
//return this;
          }
        //   任何的实例方法在内部都是定义在jQ原型上的
        //   //现在需要让这个css具备对象解析的功能
          jQuery.prototype.css = function(config){
              //循环操作每一个dom
              for(var i = 0;i<this.length;i++){
                  //谁调用this指向谁
                  for(var attr in config){
                      this[i].style[attr] = config[attr];
                  }
              }
              //链式操作
              return this;
          }
          jQuery.prototype.init.prototype = jQuery.prototype;
        //   立即执行函数执行完后,jQ不会被销毁
          window.$ = window.jQuery = jQuery;
      })();
        $('.dome') 
            .css({width:'100px',height:'100px',backgroundColor:'orange'})//第一个css执行完操作后返回操作后的再css
            .css({color:'red'});   
    </script>
</body>
</html>

2019-12-17
1.jQuery的实例方法-DOM操作
进一步选择元素的相关方法:.get() .eq() .find() .filter() .not() .is .has()
.add()集中操作。 .end()退回操作;

 //.get()从指定的框里拿出元素,并且元素是原生的
        //0 1 2 3
        //-1 -2 -3 倒着拿
        //null undefined [dom,dom,dom]
        console.log($('.dome').get());

//原码
 jQuery.prototype.get = function(num){
        //    //   if(num == null){
        //     //       return [].slice.call(this,0);
        //     //   }
        //     // else {
        //     //     if(num >= 0){
        //     //         return this[num];
        //     //     }else{
        //     //         // 正数和倒数相对应
        //     //         return this[num+this.length]
        //     //     }
        //     // }
            return num != null ? (num >= 0 ? this[num] : this[num + this.length]) : [].slice.call(this,0);
           }

 <script>
       console.log($('.dome').eq(0));
    </script>
    //原码
      jQuery.prototype.eq = function(num){
               var dom = num != null ?  (num >= 0 ? this[num] : this[num + this.length]) : null;
               return jQuery(dom);
           }
  //find 在原有的基础上往下查找
        $('.wrapper')
              .css({position:'relative'})
                .find('ul')
                   .css({listStyle:'none'})
                       .find('li')
                          .css({color:'red'})

      //prevObject都指向前身
 //filter
        //css selector jQ
        $('.wrapper ul li').filter(function(index,ele){
            //ele是原生的
            return  index % 2 == 0;
        }).css({color:'red'});
//.has() 后代中有例如 $('li').has('ul').css();
  //is
        $('ul').click(function(e){
            if($(e.target).is('li')){
                alert( $(e.target).text() );
            }else{
                alert( $(this).text())
            }
        });
 $('.wrapper')
            .css({position:'relative'})
             .find('ul')
              .css({position:'relative'})
        //.add()  集合将所有的标签集合然后设置属性
    $('.wrapper')
      .add('ul')    
       .css({position:'relative'});
       //.end() 给一个回退的机会回退到prevObject
       $('.wrapper')
          .css({position:'relative'})
           .find('ul')
             .css({pisition:'absolute'})
               .end()
                 .css({position:'absolute'})

2019-12-18

 //attr 基于 setAttribute getAttribute
    //取值
    $('.demo').attr('class');
    //赋值
    $('.demo').attr('id','test1');

1.attr和prop都可以取值赋值他们的区别是:jQ认为attr的checked selecked disabled就是表示该属性初始状态的值,prop的checked selecked,disabled表示该属性实时状态的值(true/false)
2.

 //html
        console.log( $('ul li').html());//只返回第一个li中的值
          $('ul li').html('9');//赋值的时候给所有li全部赋值

        //把数组中的值插入li中
        var arrName = ['dd','ds','aa','ss','ww'];
        $('ul li').html(function(index,ele){
            return '<p style = "color:orange">'+arrName[index]+'<p>';
        });

 //text   innerText  文本形式,不会当html解析
       console.log($('ul li').text());
       $('ul').text('9');

//返回挂载数组长度
      $('ul li').size();
 //addClass removeClass hasClass
        //''
        $('.demo').eq(0).addClass('active ');
        $('demo').addClass(function(index,ele){
            if(index % 2 == 0){
                return 'a'
            }
            return 'b'
        });
// removeClass
        $('div').removeClass('demo active');
//hasClass 有类名返回true没有返回false
 //注册一个点击事件,点击后只有一个div颜色改变
     <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    .demo{
        width: 100px;
        height: 100px;
        background: orange;
        margin-bottom: 10px;
    }
    .demo.active{
        background: red;
    }
    
    </style>
</head>
<body>
    <div class="demo active"></div>
    <div class="demo"></div>
    <div class="demo"></div>
    <script src="./jquery.js"></script>
    <!-- <script src="./myjQuery.js"></script> -->
    
    <script>
        //注册一个点击事件,点击后只有一个颜色改变
        $('.demo').click(function(e){
            $('.demo').removeClass('active');
            $(this).addClass('active');

        });
                
        </script>
</body>
</html>
 //.val()操作表单元素
       //获取表单元素的val值 获取全部的时候只能获取第一个值
                console.log($('input[type = "checkbox"]').eq(0).val());
                //把所有信息连接起来传递
                $('form').serialize();

4.基于jQ的增删改查操作

//符合条件的下一个
        $('button').click(function(){
            $(this).next('p').css({fontSize:'20px',color:'orange'});
        });
 //符合条件的上一个
        $('button').click(function(){
            $(this).prev('div').css({fontSize:'20px',color:'orange'});
        });
 <div class="wrapper">
        全选:<input type="checkbox"></input>
        banana:<input type="checkbox">
        apple:<input type="checkbox">
        orange:<input type = "checkbox">
        <input type="submit" value="login"></input>
    </div>
    <script>
       //点全选,其余选项都选中,
       $('input[type = "checkbox"]').eq(0).click(function(){
           if($(this).prop('checked')){
               $(this).nextAll('input[type = "checkbox"]').prop('checked',true);
           }else{
               $(this).nextAll('input[type = "checkbox"]').prop('checked',false);
           }
       })
 <div class="wrapper">
        <h1>水果</h1>
        全选:<input type="checkbox"></input>
        banana:<input type="checkbox">
        apple:<input type="checkbox">
        orange:<input type = "checkbox">

        <h1>nba</h1>
        全选:<input type="checkbox"></input>
        rose:<input type="checkbox">
        curry:<input type="checkbox">
        james:<input type = "checkbox">

    </div>
    <script>
       //nextUntil到。。。为止
       $('h1').next().click(function(){
           if($(this).prop('checked')){
               $(this).nextUntil('h1','input[type="checkbox"]').prop('checked',true);
           }else{
               $(this).nextUntil('h1','input[type="checkbox"]').prop('checked',false);
           }
       })
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
   
</head>
<body>
  
    <script src="./jquery.js"></script>
    <!-- <script src="./myjQuery.js"></script> -->
    <div class="wrapper">
        all:<input type="checkbox">
        <h1>吃货清单</h1>
        all:<input type="checkbox">
        <h2>水果</h2>
        全选:<input type="checkbox"></input>
        banana:<input type="checkbox">
        apple:<input type="checkbox">
        orange:<input type = "checkbox">
         <h2>vegetables</h2>
        全选:<input type="checkbox"></input>
        tomato:<input type="checkbox">
        potato:<input type="checkbox">
        parrot:<input type = "checkbox">
        <h1>star</h1>
        all:<input type="checkbox">
        <h2>nba</h2>
        全选:<input type="checkbox"></input>
        rose:<input type="checkbox">
        curry:<input type="checkbox">
        james:<input type = "checkbox">

    </div>
    <script>
      $('input').eq(0).click(function(){
          if($(this).prop('checked')){
              $(this).nextAll('input[type="checkbox"]').prop('checked',true);
          }else{
              $(this).nextAll('input[type="checkbox"]').prop('checked',false);
          }
      });

      $('h1').next().click(function(){
          if($(this).prop('checked')){
              $(this).nextUntil('h1','input[type="checkbox"]').prop('checked',true);
          }else{
              $(this).nextUntil('h1','input[type = "checkbox"]').prop('checked',false);
          }
      })


       
        </script>
</body>
</html>
//siblings 所有的兄弟节点
        $('li')
            .eq(4)
              .css('backgroundColor','red')
                 .siblings('span')
                    .css('backgroundColor','orange');
  //parent 寻找上一级的父级
        //parents 寻找上两级的父级
        //closest 寻找离他最近的父级,从自己开始找
        //offsetParent 离他最近有定位的父级
        //slice 截取 左闭右开
        console.log($('li').slice(2,5));
  //插入到''之前insertBefore(''),添加jQ对象,before里面添谁,谁在前before();
      //after insertafter 同上;
      //appengTo():把谁添加到什么里面; 
      //append(''):把''添加到谁里
      //prepend prependTo 同上添加到之前
 //remove detach 删除元素,区别在于事件上
    //remove 删除元素和事件 返回删除的东西
    //detach 删除元素后事件不删除
    //$('<div><span style = "color:red;">ss</span></div>')  也可以创建标签
//.wrap()  为demo创建一个父级
   $('.demo').wrap('<div class = "wrapper"></div>');
        //  wrapInner 在demo里面包裹
        //wrapAll 以第一个选中的div为基准包裹所有
        //unwrap 解绑 父级解绑
//clone() data()
   //clone()根据dom对象克隆,完全克隆
   //事件不能被克隆
   $('.demo').clone().appendTo('body');
    //当clone(true)时,有些事件值会被克隆;
    //prop操作js dom对象
    $('.demo').prop('data-log','111');
    $('.demo').clone().prop('date-log');//这样不会clone出来
    //data jQuery dom 存信息存数据存状态
    $('.demo').date('date-jj','ll')

date方法
当我们进行一些操作时,dom结构和存在数据存在对应关系,需要将他们绑定在一起。
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
   <style>
       .tpl{
           display: none;
       }
   </style>
</head>
<body>
   <div class="wrapper">
       <div class="tpl">
           <!-- 名称 -->
           <p></p>
           <!-- 价格 -->
           <span></span>
           <button>add</button>
       </div>
       <p class="show">
           <span>sum</span>
           <span class='sum'>0</span>
       </p>
   </div>
    <script src="./jquery.js"></script>
    <!-- <script src="./myjQuery.js"></script> -->
      
    <script>
        var shopArr = [{
            name:'jj',
            shopName:'nike',
            price:'110',
            id:'100'
        },
        {
            name:'kk',
            shopName:'adidas',
            price:'111',
            id:'102'
        },
        {
            name:'jk',
            shopName:'puma',
            price:'199',
            id:'123'
        }
    ];
    shopArr.forEach(function(ele,index){
        var oCloneDom = $('.tpl').clone().removeClass('tpl');
        oCloneDom.data({
            id:ele.id,
            shopName:ele.shopName,
            price:ele.price
        })
        .find('p')
            .text(ele.name)
               .next()
                  .text(ele.price);
                  oCloneDom.insertBefore($('.show'));

    });
    // $('.wrapper button').click(function(){
    //     $(' .sum').text( +$(' .sum').text() + $(this).parent().data('price') );
    // });
    $('.wrapper button').click(function(){
        $(' .sum').text( parseInt($(' .sum').text()) + parseInt($(this).parent().data('price') ));
    });
        </script>
</body>
</html>

2019-12-19
1.绑定事件

 //on
   //系统事件1.type 2.selector 3.data 4.handle
   $('.demo').on('click',function(){
       alert(0);
   });
   $('.demo').on('mouseenter',function(){
       alert(0);
   });
//事件委托 给li绑定事件委托,如果是li才触发
$('ul').on('click','li',function(){
    alert($(e.target).text());
});
// 绑定多个事件
$('.demo').on({
    click:function(){

    },
    mouseenter:function(){

    },
    mouseleave:function(){
        
    }
});
//one
//一次性需求先跳a,后点击在一直跳b
$('a').one('click',function(){
    window.open('http://www.baidu.com');
    return false;
});
 //off 取消已绑定事件
       //trigger:主动触发 自定义事件
       $('.demo').on('click',function(e,a,b,c,d){
           console.log('click',a,b,c,d);
       });
       $('.demo').trigger('click',[10,20,30,40]);
       //trigger自定义事件的原理
       //hover  移入移除场景
       $('demo').hover(function(){
           console.log('enter');

       },function(){
           console.log('leave');
       })

2019-12-21
1.jQuery实例方法-动画
//hide() show()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
   <style>
       *{
           margin: 0;
           padding: 0;
       }
       .demo{
           width: 100px;
           border: 1px solid black;
       }
       ul{
           display: none;
       }
   
   </style>
</head>
<body>
<!-- //鼠标移入,下拉列表出现,移除消失 -->
<div class="demo">
    <p>ROSE</p>
    <ul>
        <li>nba</li>
        <li>mvp</li>
        <li>kk</li>
    </ul>
</div>
    <script src="./jquery.js"></script>
    <!-- <script src="./myjQuery.js"></script> -->
   <script>
      //  show,hide
      $('p').on('mouseenter',function(){
          //width height opacity padding margin 一起变(延迟)
          $(this).next().show(3000,'swing');//(执行完的延迟数,以什么样的方式过渡);
      });
      $('.demo').on('mouseleave',function(){
          $('p').next().hide(330,'linear');
      });
            </script>
</body>
</html>
//toggle(),实现点击和消失
    //fadeIn渐入 fadOut渐出  fadeTo(时间,淡入到什么程度,淡入方式,函数)  fadeToggle点击淡入和淡出消失;
    //slideDown卷入,slideUp卷出
         

//animate(); stop(); finish(); delay();

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
   <style>
     .demo{
         position: absolute;
         width: 100px;
         height: 100px;
         background: orange;
     }
   </style>
</head>
<body>
   <button id = 'stopBtn'>stop</button>
   <button id = 'finishBtn'>finish</button>
   <button id = "startBtn">start</button>
    
<div class="demo"></div>

    <script src="./jquery.js"></script>
    <!-- <script src="./myjQuery.js"></script> -->
   <script>
    //animate() 目标点   stop() finish()
    //target(目标点)  duration(运动时间) easing(运动方式) callback(回调函数)
    $('#startBtn').on('click',function(){
        //内置队列,执行完第一个任务后在执行第二个;
        $('.demo')
        .animate({width:'+=50',height:'+=50',left:'+=50',top:'+=50'},1000,'swing')
          .delay(2000)//第一个到第二个运动间进行延迟    
        .animate({width:'+=50',height:'+=50',left:'+=50',top:'+=50'},1000,'swing')
           });
     $('#stopBtn') .on('click',function(){
         $('.demo').stop(true,true);//若传递true戛然而止,若不传递参数则会从第一个任务直接进行第二个任务
         //第二个true,停止当前运动,并立马运动到当前目标点

     })  ; 
            </script>
</body>
</html>

jQuery工具方法

 //typeof() 里面的数据是什么类型:typeof(null)-->object,typeof(new date())-->object;
        //typeof(new Number())-->object;
        //$.type()   里面的数据到底是啥:$.type(null)-->null
        console.log($.type({}));//对象返回object
        console.log($.type(new Date()));//-->date
        console.log($.type(new Number()));//-->number
        console.log($.isArray([1,2,3,4]));//true;
        //$.trim('   22   ')

jQuery实例方法-位置图形
位置坐标图形大小相关方法

//   获取一个标签距离文档的绝对值(永远参照文档定位) .offset()  返回对象:left/top距离值
    //.position()  获取标签相对于(谁定位)父级的距离的
    //$(window).scrollTop()  scrollLeft() 滚动距离
    //width height --> content
    //innerwidth -->content+padding
    //outerwidth -->content+padding+border
    //console.log($('.demo').outerwidth(true));-->content+padding+border+margin;

Jquery实例方法-遍历索引

 //.each()
    //.children() 返回所有子元素
    //.index() 获得到原生dom
    $('ul').on('click','li',function(e){
        console.log($(e.target).index());
    })
    

2019-12-27
1.$.proxy(function,this) 改变this指向

//单对象式编程
 var list = {
        init:function(){
            this.ms = 123;
            this.dom = document.getElementById('demo');
            this.bindEvent();
        },
        bindEvent:function(){
            this.dom.onclick = $.proxy(this.show,this);
        show:function(){
            console.log(this,produseMs(this.ms));
            produseMs:function(ms){
                return ms+234;
            }
        }

        }
    }

2,$noConflict()
防止变量命名冲突。
3,

 $.each()//
   $.$map()//对数组的每一位进行操作
   $.parseJSON()//严格json字符串转换成对象
   $.makeArray();//传一个类数组变成数组(一个参数时),两个参数时,把前面的参数家发哦后面的参数里
   

4.$.extend()插件扩展,继承问题

$.fn.extend()和$.extend();
//前者添加到实例方法里面,后者添加到工具方法里面;
//①扩展方法 ②浅层克隆③深层克隆

//   自定义随机数,将自己定义的方法加到jQ中(工具方法中添加)
$.extend({
    defiendMandom:function(start,final){
        //[0,1) * len + start;
        var len = final-start;
        return Math.random()*len+start;

    }
})
// 加到实例方法里面
$.fn.extend({
    var disX,
        disY,
        self = this;
    $(this).on('mousedown',function(e){
        disX = e.pageX-$(this).offset().left;
        diaY = e.pageY-$(this).offset().top;
        $(document).on('mousemove',function(e){
            $(self.CSS({left:e.pageX-disX,top:e.pageY-disY}))
        });
        $(document.on('mouseup',function(e){
            $(document).off('mousemove').off('mouseup');
        }
        ))
    })

})
// 浅层克隆
$.ajax({
    url:'______dizhi',
    type:GET;
    success:function(res){
        $.each(res.data,function(index,ele){
            console.log(ele);
        })
    },
    error:function(e){
        console.log(e.status,e.statusText);
    },
    complete:function(){

    },
    // context改变执行上下文,async:是否异步,dataType:期待以什么方式;
})
   
   

4.callbacks()回调
当单线程的JS向浏览器发送一些事件请求时,浏览器中的线程如(定时触发器线程,http网络请求线程,事件监听线程,)同时工作处理完成后执行回调函数。

var cb = $.Callbacks();
// ('memory')后加上的构造函数也会执行,('unique')不会执行重复项,('stopOnFalse')若函数返回值有false直接停止
// 回调处理函数
function a(x,y){
    console.log('a',x,y);
}
function b(x,y){
    console.log('b',x,y);
    cb.add(a,b);
    cb.fire('10','20')
}
   </script>

5.$.deferred();

//延迟
var df = $.deferred();
//done 成功  fail 失败  progress 正在进行
//resolve       reject     notify
//注册成功的回调函数
df.done(function(){
    console.log('oh yeah');
})

6.$.then()

//核心 then
  <script>
        // 核心 then 
        var df = $.Deferred();

        // df.done(function () {
        //     console.log('done1');
        // }).fail(function () {
        //     console.log('fail');
        // })
        // .progress(function () {
        //     console.log('progress');
        // })
        // .done(function () {
        //     console.log('done2');
        // });
 
        // 
        // df.then(function () {
        //     console.log('done1');
        // }, function () {
        //     console.log('fail1');
        // }, function () {
        //     console.log('progress1');
        // }).then(function () {
        //     console.log('done2');
        // }, function () {
        //     console.log('fail2');
        // }, function () {
        //     console.log('progress2');
        // });

        function createScore () {
            var df = $.Deferred();
            setInterval(function () {
                var score = Math.random() * 100;
                if (score > 60) {
                    df.resolve('congradulation!!!');
                }else if (score < 50) {
                    df.reject('get out');
                }else {
                    df.notify('go on');
                }
            }, 1500);
            // done fail progress
            return df.promise();
        }

        var df = createScore();
        df.then(function (ms) {
            console.log('oh Yeah!' + ' ' + ms);
            var innerDf = $.Deferred();
            // 
            setTimeout(function () {
                innerDf.resolve('duyi resolve');
            }, 1500);

            return innerDf.promise();
        }, function (ms) {
            console.log('oh No!' + ' ' + ms);
            var innerDf = $.Deferred();
            // 
            setTimeout(function () {
                innerDf.reject('duyi reject');
            }, 1500);

            return innerDf.promise();
        }, function () {
            console.log('what?' + ' ' + ms);
            setTimeout(function () {
                innerDf.notify('duyi notify');
            }, 1500);

            return innerDf.promise();

        }).then(function (ms) {
            console.log(ms);
        }, function (ms) {
            console.log(ms);
        }, function (ms) {
            console.log(ms);
        });     



        // $.ajax({url, type, data}).then(function () {
        //     // 发送请求
        //     return $.ajax();
        // }).then(function () {
        //     return $.ajax();
        // })





        // 
        // df.then(function (ms) {
        //     console.log('oh Yeah!' + ' ' + ms);
        //     return 'ok';
        // }, function (ms) {
        //     console.log('oh No!' + ' ' + ms);
        //     return 'no';
        // }, function () {
        //     console.log('what?' + ' ' + ms);
        //     return 'go on';
        // }).then(function (param) {
        //     console.log('娉″' + param);
        // }, function (param) {
        //     console.log(param + '鑴?);
        // }, function (param) {
        //     console.log(param + '鍔犳补');
        // });
    </script>

发布了60 篇原创文章 · 获赞 17 · 访问量 6419

猜你喜欢

转载自blog.csdn.net/qq_42177478/article/details/103572370
今日推荐