jQuery

一. 什么是jQuery:

 jQuery是 第三方开发的  —— 先下载才能使用

          执行DOM操作的 —— 学jQuery依然在学DOM

          极简化的 —— 对DOM API的终极简化

          函数库 —— jQuery中一切用函数来实现

二.为什么:

   两个原因:

  1. jQuery是DOM操作的终极简化:

    简化了: 增删改查、事件绑定、动画、ajax

  2. 解决了大部分浏览器兼容性问题:

     凡是jQuery让用的都没有兼容性问题:

 何时: 几乎所有项目或框架的底层DOM操作,都是由jQuery实现的

三. 如何使用jQuery:

 下载: jquery.com

 1.版本:

1.x 兼容IE、2.x 不再兼容IE8、3.x 不再兼容IE8,增加了新特性

       1). 运行在严格模式下

       2). 用for of代替了.each()方法

       3). 支持Promise

 2. 如何使用:

 1).先引入jQuery到页面中,再编写自定义js:<script src="js/jquery-1.11.3.js">/或者使用CDN网络上共享的jquery.js,内容分发网络,生产环境中用的最多

 2). 只要想使用jQuery简化版API,都要先创建jQuery对象并封装DOM元素对象

      2种:

      *). 用选择器先查找再创建:

        var $btn1=$("#btn1");

      *). 如果已经获得DOM元素,可直接封装:

        var $btn1=$(this);

3.什么是jQuery对象:

封装DOM元素对象,并提供操作DOM的简化版API 的类数组对象
  为什么jquery对象是是类数组对象:查找一次可以找到很多元素,把所有找到的元素都囊括进来,只有类数组对象(有length、有下标、可以遍历)才可以包含这么多元素

      对jQuery对象整体调用API,等效于对内部封装的DOM元素都调用API

        jQuery API 三大特性:

        1. 自带遍历效果: 对整个jQuery对象调用一次API,等效于自动对内部所有DOM元素都调用API

        2. 一个函数两用: 即可获取值,又可修改值

 如果调用时,没有给新值,则默认获取

     如果调用时,给了新值,则为修改

        3. 多数函数都返回正在操作的jQuery对象本身,所以有$().css(),或$().mouseover().mouseout()的链式操作

四. 查询:

 按选择器查找:  var $elem=$("选择器")

  1.基本选择器:

5个 同CSS

   #id  element  .class   *   selector1,selector2,...

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 <link rel="stylesheet" href="css/style.css" /> 
</head>
<body>
  <h3>基本选择器</h3>
  <!-- 测试的元素 -->
  <div class="one" id="one" >id为one,class为one的div
    <div class="mini">class为mini</div>
  </div>

  <div class="one" id="two" title="test" >id为two,class为one,title为test的div.
    <div class="mini"  title="other">class为mini,title为other</div>
    <div class="mini"  title="test">class为mini,title为test</div>
  </div>

  <div class="one">
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
      <div class="mini">class为mini</div>
      <div class="mini"></div>
  </div>

  <div class="one">
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
      <div class="mini">class为mini</div>
      <div class="mini" title="tesst">class为mini,title为tesst</div>
  </div>

  <div style="display:none;" class="none">style的display为"none"的div</div>
  
  <div class="hide">class为"hide"的div</div>
 
  <div>包含input的type为"hidden"的div<input type="hidden" size="8"/>
  </div>

  <span id="mover">正在执行动画的span元素.</span>
  
<h1 style="clear:both">
  <!-- 控制按钮 -->
  <input type="button" value="选择 id为 one 的元素." id="btn1"/>  
  <input type="button" value="选择 class 为 mini 的所有元素." id="btn2"/>
  <input type="button" value="选择 元素名是 div 的所有元素." id="btn3"/>
  <input type="button" value="选择 所有的元素." id="btn4"/>
  <input type="button" value="选择 所有的span元素和id为two的元素." id="btn5"/>
</h1>
<script src="js/jquery-1.11.3.js"></script>
<script>
$("#btn1").click(function(){
  $("#one").css("border","1px solid red");
         //.style.border=...
})
$("#btn2").click(function(){
  $(".mini").css("border","1px solid red");
         //.style.border=...
})
$("#btn3").click(function(){
  $("div").css("border","1px solid red");
         //.style.border=...
})
$("#btn4").click(function(){
  $("*").css("border","1px solid red");
         //.style.border=...
})
$("#btn5").click(function(){
  $("span,#two").css("border","1px solid red");
         //.style.border=...
})
</script>
</body>
</html>

selector
selector

2. 层级选择器: 同CSS

   父 后代   父>子    兄+弟    兄~弟

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 <title></title>
 <link rel="stylesheet" href="css/style.css" />  
</head>
<body>
  <h3>层次选择器</h3>
  <!-- 测试的元素 -->
  <div class="one" id="one">id为one,class为one的div
    <div class="mini">class为mini</div>
  </div>

  <div class="one"  id="two" title="test">id为two,class为one,title为test的div.
    <div class="mini"  title="other">class为mini,title为other</div>
    <div class="mini"  title="test">class为mini,title为test</div>
  </div>

  <div class="one">
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
      <div class="mini">class为mini</div>
      <div class="mini"></div>
  </div>

  <div class="one">
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
      <div class="mini">class为mini</div>
      <div class="mini" title="tesst">class为mini,title为tesst</div>
  </div>


  <div style="display:none;" class="none">style的display为"none"的div</div>
  
  <div class="hide">class为"hide"的div</div>
 
  <div>包含input的type为"hidden"的div<input type="hidden" size="8"/>
  </div>
  
  <span id="mover">正在执行动画的span元素.</span>

  <h1 style="clear:both">
    <input type="button" value="选择 body内的所有div元素." id="btn1"/>
    <input type="button" value="在body内,选择直接div子元素。" id="btn2"/>
    <input type="button" value="选择 class为one 的下一个兄弟div元素." id="btn3"/>
    <input type="button" value="选择 id为two的元素后面的所有兄弟div元素." id="btn4"/>
  </h1>
<script src="js/jquery-1.11.3.js"></script>
<script>
  $("#btn1").click(function(){
    $("body div").css("border","1px solid red")
  })
  $("#btn2").click(function(){
    $("body>div").css("border","1px solid red")
  }) 
  $("#btn3").click(function(){
    $(".one+div").css("border","1px solid red")
  })
  $("#btn4").click(function(){
    $("#two~div").css("border","1px solid red")
  })
</script>
</body>
</html>

selector
selector

3.过滤选择器

1).子元素过滤选择器: 同CSS

   按元素在其父元素中的相对位置选择元素

   下标i从1开始

   :first-child   :last-child     :nth-child(n)

   偶数行: tr:nth-child(2n) //even

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 <title></title>
</head>
<body>
  <h3>子元素过滤选择器.</h3>
  <ul>
    <li>child1-basic0</li>
    <li>child2-basic1</li>
    <li>child3-basic2</li>
  </ul>
  <ul>
    <li>child1-basic3</li>
    <li>child2-basic4</li>
    <li>child3-basic5</li>
  </ul>
  <ul>
    <li>child1-basic6</li>
  </ul>
  <script src="js/jquery-1.11.3.js"></script>
  <script>
    //查找每个ul中第一个li
    $("ul>li:first-child").css("background","red");
    //查找每个ul中最后一个li
    $("ul>li:last-child").css("background","green");
    //查找每个ul中处于偶数位置的
    $("ul>li:nth-child(2n)")//:nth-child(even)这样写也行
    .css("background","pink");
    //查找每个ul中第2个li
    $("ul>li:first-child(2)").css("border","2px soild red");
    //查找作为ul下唯一子元素的li
    $("ul>li:only-child").css("border","2px soild yellow");
  </script>
</body>
</html>

child filter
child filter

2). 基本过滤选择器(位置过滤): jQuery新增的

   打破父元素的界限,按绝对位置选择元素

   下标i从0开始

   :first/last   :even/odd(偶数/奇数)    :eq/gt/lt(i)(等于/大于/小于)(位置)

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 <title></title>
</head>
<body>
  <h3>基本过滤选择器.</h3>
  <ul>
    <li>child1-basic0</li>
    <li>child2-basic1</li>
    <li>child3-basic2</li>
  </ul>
  <ul>
    <li>child1-basic3</li>
    <li>child2-basic4</li>
    <li>child3-basic5</li>
  </ul>
  <ul>
    <li>child1-basic6</li>
  </ul>
  <script src="js/jquery-1.11.3.js"></script>
  <script>
    //查找第一个li
    $("li:first").css("background","red");
    //查找最后一个li
    $("li:last").css("background","green");
    //查找处于偶数位置的li
    $("li:odd").css("background","yellow");
    //查找第2个li
    $("li:eq(1)").css("color","bule");
  </script>
</body>
</html>

child filter
child filter

3). 属性过滤选择器: 同CSS

[属性名]   [属性名=值]  [属性名^=开头]

   [属性名$=结尾]    [属性名*=内容]   [属性名!=值]

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 <link rel="stylesheet" href="css/style.css" /> 
</head>
<body>
  <h3>属性过滤选择器.</h3>
  <!-- 测试的元素 -->
  <div class="one" id="one" >id为one,class为one的div
    <div class="mini">class为mini</div>
  </div>

  <div class="one"  id="two" title="test" >id为two,class为one,title为test的div.
    <div class="mini"  title="other">class为mini,title为other</div>
    <div class="mini"  title="test">class为mini,title为test</div>
  </div>

  <div class="one">
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
      <div class="mini">class为mini</div>
      <div class="mini"></div>
  </div>

  <div class="one">
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
      <div class="mini">class为mini</div>
      <div class="mini"  title="tesst">class为mini,title为tesst</div>
  </div>

  <div style="display:none;"  class="none">style的display为"none"的div</div>
  
  <div class="hide">class为"hide"的div</div>
 
  <div>包含input的type为"hidden"的div<input type="hidden" size="8"/>
  </div>
  
  <span id="mover">正在执行动画的span元素.</span>

  <br /><br />
  <h1 style="clear:both">
  <input type="button" value="选取title属性以te开头的div" id="btn1"/>
  <input type="button" value="选取title属性以est结尾的div" id="btn2"/>
  <input type="button" value="选取包含title属性的div" id="btn3"/>
  <input type="button" value="选取title属性等于test的div" id="btn4"/>
    <input type="button" value="选取title属性不等于test的div" id="btn5"/>
    <input type="button" value="选取title属性包含es的div" id="btn6"/>
    <input type="button" value="选取包含id属性且title属性值包含es的div" id="btn7"/>
  </h1>
  <script src="js/jquery-1.11.3.js"></script>
  <script>
    $("#btn1").click(function(){
      $("div[title^=te]").css("border","1px soild red")
    })
    $("#btn2").click(function(){
      $("div[title$=est]").css("border","1px soild red")
    })
    $("#btn3").click(function(){
      $("div[title]").css("border","1px soild red")
    })
    $("#btn4").click(function(){
      $("div[title=test]").css("border","1px soild red")
    })
    $("#btn5").click(function(){
      $("div[title!=test]").css("border","1px soild red")
    })
    $("#btn6").click(function(){
      $("div[title*=es]").css("border","1px soild red")
    })
    $("#btn7").click(function(){
      $("div[id][title*=es]").css("border","1px soild red")
    })
  </script>
</body>
</html>

attr filter
attr filter

4).可见性过滤: jQuery新增

   :hidden 匹配隐藏的元素

    比如: display:none / visibility: hidden / opacity:0 / <input type="hidden">

   :visible 匹配显示的元素

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8"/>
  <title>...</title>
  <style>
        /*解决: 网页body太小,导致点击空白菜单不隐藏*/
        body{height:600px}
        .dropdown{width:64px; height:20px;}
    .dropdown a{
            text-decoration:none; 
            color:#000;
            display:inline-block;
        }
        .dropdown>a{ 
            border:1px solid #000; padding:6px 12px;
        }
        .dropdown-menu{
            width:200px;
            list-style:none; margin:0; padding:0;
            border:1px solid #aaa;
            box-shadow:5px 5px 6px #000;
            display:none;
        }
        .dropdown-menu a{padding:6px 20px; width:160px}
        .dropdown-menu li:hover{background:#ddd}
  </style>
 </head>
  
<body>
<h1>下拉菜单</h1>
<div class="dropdown">
    <a data-trigger="dropdown" href="javascript:;">Dropdown</a>
    <ul class="dropdown-menu">
        <li><a href="javascript:;">Action</a></li>
        <li><a href="javascript:;">Another action</a></li>
        <li><a href="javascript:;">Something else here</a></li>
        <li><hr></li>
        <li><a href="javascript:;">Separated link</a></li>
    </ul>
</div>
<script src="js/jquery-1.11.3.js"></script>
<script>
//先实现单击按钮下拉
/*//1. 查找触发事件的元素
//2. 绑定事件处理函数
//当单击data-trigger属性为dropdown的按钮时
$("[data-trigger=dropdown]").click(
    function(e){
        e.stopPropagation();//取消冒泡!
        //e.preventDefault();//阻止默认行为
        //3. 查找要修改的元素: 当前按钮的下一个兄弟菜单元素
        var $menu=$(this).next();
        //4. 修改元素
        if($menu.is(":hidden")){//如果菜单是隐藏的
            //就显示菜单
            $menu.show();//css("display","block");
        }else{//否则,就隐藏菜单
            $menu.hide();//css("display","none");
        }
    }
)
//点空白处菜单隐藏:
$("body").click(function(){
    $(".dropdown-menu").hide();
})*/

//再实现鼠标移入下拉
//鼠标进入按钮的父元素div时,菜单显示
$("[data-trigger=dropdown]").parent()
.mouseover(function(){
    //this->父元素div
    //查找父元素下孩子中最后一个孩子,让其显示
    $(this).children().last().show();
             //.children()
             // return jQuery对象[ a,  ul ][1].show
             //                  DOM  DOM  DOM
})
//return $parent
//鼠标移出按钮的父元素div时,菜单隐藏
.mouseout(function(){
    $(this).children().last().hide();
})
</script>
</body>
</html>

dropdown
dropdown

5).内容过滤: jQuery新增

   :contains(文本) 匹配元素的内容中包含指定“文本”的元素

   :has(选择器) 匹配包含满足选择器要求的子元素的父元素

   :parent 选择内容非空的元素

   :empty 选择内容为空的元素

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <link rel="stylesheet" href="css/bootstrap.css"/>
  <style>
  </style>
</head>
<body>
<div class="container">
<h1>jQuery中的选择器——内容过滤选择器</h1>

  <button>提交订单</button>
  <button>Submit注册信息</button>
  <button>马上提交</button>
  <button>清空重填</button>

  <hr/>
  <div class="alert" id="alert1">
    第一个警告框
  </div>
  <div class="alert" id="alert2">
    <span class="close">×</span>
    第一个警告框
  </div>

</div>
<script src="js/jquery-1.11.3.js"></script>
<script>
  //选择包含"提交"二字的按钮,变为绿色按钮
$("button:contains(提交)").css("background","lightGreen")
  //选中包含.close按钮的.alert元素,让它们变为红色的警告框
$(".alert:has(.close)").css("background","red")
  //选中不包含.close按钮的.alert元素,让它们变为绿色的警告框
$(".alert:not(:has(.close))").css("background","lightGreen")
</script>
</body>
</html>

content filter
content filter

6).状态过滤: 同CSS

   :enabled  :disabled  :selected    :checked

7).表单元素过滤: jQuery新增:

   :input 匹配所有表单元素: input select textarea button

   :[type] 匹配type为指定类型的input元素:

    :text <input type="text">

    :password <input type="password">

    :...

<!DOCTYPE html>
<html>
 <head>
  <title>.....</title>
  <meta charset="utf-8"/>
  <style>
  </style>
 </head>
 <body>
    <form>
        用户名:<input disabled></br>
        密码:<input type="password" disabled></br>
        <input type="checkbox">我同意本站的使用条款<br>
        <input type="submit" value="提交注册信息" disabled/>
    </form>
    <script src="js/jquery-1.11.3.js"></script>
    <script>
        //查找type为CheckBox的input元素
        $(":checkbox").click(function(){
        //如果当前chb是选中的(is:checked)
        if($(this).is(":checked")){
         //则其他表单元素都启用(disabled为false)
         $("input:not(:checkbox)").prop("disabled",false)
        }else{//否则
            //其他表单元素都禁用(disabled为true)
            $(":input:not(:checkbox)").prop("disabled",true)
        }
       })
        
    </script>
 </body>
</html>

form state selector
form state selector

 按节点间关系查找:

  两大类:

 1. 父子: 

  1).  .parent() 获取当前元素的父元素    .parentNode

  2).  .children(["选择器"]) 可获得直接子元素中符合要求的元素

         比如: $main.children("div") 选择id为main下的直接子元素中的div。如果有ul,p,则不选择。

  3).  .find("选择器") 可在所有后代中查找符合条件的元素

         比如: $ul.find("li.active") 查找ul下所有后代li中class为active的li

  4).  .children(":first-child")     .firstElementChild

  5).   .children(":last-child")     .lastElementChild

 2. 兄弟:

  1).   .prev()       .previousElementSibling

         .prevAll(["选择器"])   选择当前元素之前所有兄弟元素

  2).   .next()        .nextElementSiblinlg

         .nextAll(["选择器"])   选择当前元素之后所有兄弟元素

 

 3).    .siblings(["选择器"])    选择除自己之外所有兄弟

  

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8"/>
  <title>...</title>
  <script>
  </script>
 </head>
  
 <body>
<!--    ul.top>(li.parent>ul>li.child*3)*2 -->
   <ul class="top">
       <li class="parent1">parent1
           <ul>
               <li class="child">child1</li>
               <li class="child">child2</li>
               <li class="child">child3</li>
           </ul>
       </li>
       <li class="parent2">parent2
           <ul>
               <li class="child">child1</li>
               <li class="child">child2</li>
               <li class="child">child3</li>
           </ul>
       </li>
   </ul>
<script src="js/jquery-1.11.3.js"></script>
<script>
//修改class为top的ul的所有直接子元素
$("ul.top").children()
.css("border","2px solid red")
//修改class为top的ul的所有后代li
$("ul.top").find("li").css("color","green")
//为class为child的li绑定单击事件
$("ul.top li.child").click(function(){
    //选择当前元素的下一个元素/前一个元素/之前所有/之后所有/除自己之外所有
    $(this).siblings()//.nextAll().prevAll().prev().next()
    .css("background","yellow")
})
    
</script>        
 </body>
</html>

next/sibiling
next/sibiling

      比如: //将当前li添加class active

      $a.parent().addClass("active")

      //return $当前li

      //将当前li之外的其余li去掉class active

      .siblings().removeClass("active")

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .tabs{ list-style:none; padding:0 }
    .tabs a{
      text-decoration:none;
            color:#000;
            padding:6px 12px;
            display:inline-block;
    }
    .tabs>li{
      float:left;
      border-bottom:1px solid #000;
    }
    .tabs>.active{
      border:1px solid #000;
      border-bottom:0;
    }
  </style>
 </head>
 <body>
        <h1>使用属性选择器实现标签页头的切换</h1>
        <ul class="tabs">
            <li class="active">
        <a data-toggle="tab" href="#">十元套餐</a>
      </li>
            <li>
        <a data-toggle="tab" href="#">二十元套餐</a>
      </li>
            <li>
        <a data-toggle="tab" href="#">三十元套餐</a>
      </li>
    </ul>
<script src="js/jquery-1.11.3.js"></script>
<script>
//如果多个子元素绑定相同的事件时,都要利用冒泡
//事件绑定在父元素上一次,所有子元素共用:
//2大难题:
  //1. this 要换成 e.target
  //2. 判断e.target是否想要的
$("ul.tabs").click(function(e){
  var $a=$(e.target);
  if($a.is("a")){
    //将当前li添加class active
    $a.parent().addClass("active")
    //return $当前li
    //将当前li之外的其余li去掉class active
    .siblings().removeClass("active")
  }
})
</script>
 </body>
</html>

tabs
tabs

五. 修改:

 1.内容:

    3种:

  1). 原始HTML片段: .innerHTML

    $elem.html(["html片段"])  一个函数两用

  2). 纯文本内容: .textContent

    $elem.text(["文本内容"])  一个函数两用

  3). 表单元素的值: .value

    $elem.val(["值"]) 一个函数两用

  4).清除内容

   $("...").empty()

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
 </head>
<body>
<h1>操作元素的内容和值</h1>
<form action="">
    用户名:<input name="uname" type="text">
                <span></span><br>
    密码:<input type="password" name="upwd">
                <span></span><br>
    <input type="submit" value="提交注册信息">
</form>
<script src="js/jquery-1.11.3.js"></script>
<script>
//正确时,使用图片:"<img src='img/ok.png'>"
//姓名错误时: "<img src='img/err.png'>用户名必须介于3~9位之间!"
//密码错误时: "<img src='img/err.png'>密码必须介于6~8位之间!"
//阻止默认行为: e.preventDefault();
//表单提交: $(form).submit();
//查找type为text的input元素,绑定失去焦点事件
$(":text").blur(function(){
    vali(this,3,9,"用户名必须介于3~9位之间!");
})
function vali(txt,min,max,msg){
    var $txt=$(txt);//获得当前文本框对象:
    //根据不同条件,设置$txt的内容为不同的值
    $txt.next().html(function(){
        //获得当前文本框内容的长度
        var length=$txt.val().length;
        //如果内容的长度在3~9位之间
        if(length>=min&&length<=max){
            //就设置文本框的下一个兄弟元素的内容为正确的html片段
            return `<img src='img/ok.png'>`
        }else{//否则,就设置文本框的下一个兄弟元素的内容为错误的html片段
            return `<img src='img/err.png'>${msg}`
        }
    });
}
$(":password").blur(function(){
    vali(this,6,8,"密码必须介于6~8位之间!")
})
</script>
</body>
</html>

val
val

2.属性:

  核心DOM API: $elem.attr("属性名"[,"属性值"]) 一个函数两用

  HTML DOM API: $elem.prop("属性名"[,"属性值"]) 一个函数两用

*以上[ ]的值是选填的,不是必须的

 

(property指的是内存中对象中的属性,而attribute指得是html的标签中的属性)

比如title属性prop和attr都可以访问,因为title属性是html标准属性既出现在标签中又出现在内存中对象身上

比如data-target属性只能用attr访问,自定义扩展属性没有未卜先知的封装所以不能prop访问

比如checked状态属性用prop访问,不能用attr,因为checked值是布尔类型不是字符串类型

  1). HTML标准属性:

       两种:

    *). 核心DOM: getAttribute()   setAttribute()

    *). HTML DOM: .属性名        .属性名=值

  2). 状态属性

      HTML DOM: .状态属性包括: disabled"checked selected

  3). 自定义扩展属性:

    1. 核心DOM: getAttribute()   setAttribute()

     问题: 一次只能修改一个属性,如果同时修改多个属性时,代码会很繁琐:

     解决: 同时修改多个属性:

    $elem.attr/prop({

     属性:值,

      ... : ...

    })

   样式:

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
 </head>
<body>
<h1>操作元素的属性</h1>
<img src="img/1.jpg" alt="1">
<script src="js/jquery-1.11.3.js"></script>
<script>
//单击图片,切换下一张
//1. 查找触发事件的元素
//2. 绑定事件处理函数
$("img").click(function(){
    var $img=$(this);//3. 查找要修改的元素
    //4. 修改元素
    //获得当前图片的alt属性值,转为整数i
    var i=parseInt($img.attr("alt"));
    if(i<4)//如果i没到4
        i++;//就可以继续+1
    else//否则(i==4)
        i=1;//就回到1
    $img//同时修改img的src和alt为新值
    .attr({src:`img/${i}.jpg`,alt:i});
})
</script>
</body>
</html>

attr
attr
<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    body {
      text-align: center;
    }
  </style>
</head>
<body>

<img src="img/1.jpg" data-target="img/1-l.jpg" class="my-small">
<img src="img/2.jpg" data-target="img/2-l.jpg" class="my-small">
<img src="img/3.jpg" data-target="img/3-l.jpg" class="my-small">
<img src="img/4.jpg" data-target="img/4-l.jpg" class="my-small">
<hr/>
<img src="img/1-l.jpg" class="my-big">


<script src="js/jquery-1.11.3.js"></script>
<script>
//点击小图片,下方my-big中显示大图片
//1. 查找触发事件的元素
//2. 绑定事件
$(".my-small").mouseover(function(){
  //3. 查找要修改的元素
  //4. 修改元素
  //获得当前小图片身上的data-target属性值
  var src=$(this).attr("data-target");
  $(".my-big").prop({src});
            //.attr()
})
</script>
</body>
</html>

attr
attr

3.样式:

  1).直接修改css属性

     $elem.css("css属性"[,值]) //单个数值的属性值不用加单位

      修改样式: elem.style.css属性=值

      获取样式: getComputedStyle()

  .css() 一次只能修改一个css属性。

   如果同时修改多个css属性:

     .css({

       css属性名:值,

         ... : ...

     })

     css属性名必须去横线变驼峰

  问题: 如果同时修改多个css属性,用.css()代码繁琐

   解决:用操作class来批量修改样式

  2). 用操作class来批量修改样式

   <button class="btn btn-danger active"

   $elem.addClass("class1 class2 ...")

   $elem.removeClass("class1")

   $elem.hasClass("class1")

        .is(".class1")

   比如: if($btn.hasClass("down"))//如果有down

              $btn.removeClass("down");//就移除down

               else//否则

              $btn.addClass("down");//就添加down

只有在有和没有一个class之间来回切换时,采用.toggleClass("class")

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    .btn {
      padding: 5px 10px;
      border-radius: 3px;
      border: 1px solid #aaa;
      outline: none;
    }
    .up {
      background: #fff;
      color: #333;
    }
    .down {
      background: #ddd;
      color: #fff;
    }
  </style>
</head>
<body>

<button class="btn up">双态按钮</button>


<script src="js/jquery-1.11.3.js"></script>
<script>
//双态按钮: 让按钮的class在up和down之间切换
$("button.btn").click(function(){
  var $btn=$(this);
  /*if($btn.hasClass("down"))//如果有down
    $btn.removeClass("down");//就移除down
  else//否则
    $btn.addClass("down");//就添加down*/
  $btn.toggleClass("down");//在有和没有down之间来回切换
})
</script>
</body>
</html>

双态按钮
双态按钮

 

 

六. 添加/删除/替换/克隆

 1.添加:

   两步:

  1). 用html片段创建新元素:

   var $a=$(`<a href="http://tmooc.cn">go to tmooc</a>`);

  2). 将新元素添加到DOM树上

   *).追加:

     $父元素.append($a)   末尾追加

      $a.appendTo(父元素).对a做其它操作  末尾追加

     $父元素.prepend($a)  在开头插入

      $a.prependTo(父元素) .对a做其它操作  在开头插入

   *). 中间插入:

       $child.before($a)  将a插入到child之前

       $a.insertBefore(child)  将a插入到child之前

       $child.after($a)   将a插入到child之后

       $a.insertAfter(child)   将a插入到child之后

 2. 替换:

     $child.replaceWith($a)  用a代替child

     $a.replaceAll(child) .对a做其它操作     用a代替child

 

3.删除:

$elem.remove();

4.克隆:

var $elem2=$elem.clone();

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
    <style>
        .container {
            border: 1px solid #aaa;  overflow:hidden;
        }
        .block {
            float: left; margin: 10px;
            border: 1px solid #aaa;
            background: #faa;
            width: 150px; height: 150px;
        }
        .block:hover{ box-shadow:0 5px 6px #000; }
        .close {
            float:right; padding:5px;
            font-weight:bold; opacity:.2; cursor: pointer;
        }
        .close:hover { opacity: .5; }
    </style>
 </head>
 <body>
  <h1>添加/删除节点</h1>
    <button id="add-block">添加区块</button>
    
    <div class="container">
<!--         <div class="block"> -->
<!--             <span class="close">×</span> -->
<!--         </div> -->
    </div>
    
    <script src="js/jquery-1.11.3.js"></script>
    <script>
        $("#add-block").click(function(){
            //创建一个block
            $(`<div class="block">
            <span class="close">×</span>
             </div>`)
             //将block插入到class为container的容器的开头
             .prependTo(".container")
             //return $新block
             //随机修改block的背景色
             .css("background",function(){
                 var r=Math.random()*256;
                 var g=Math.random()*256;
                 var a=Math.random()*256;
                 return `rgb(${r},${g},${b})`;
             });
        })
    </script>
    
 </body>
</html>

append
append
<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    body{
      text-align: center;
    }
  </style>
</head>
<body>
<h1>替换节点</h1>

<div id="chosen">
  <img src="img/p0.png">
</div>
<hr/>
<div id="list">
  <img src="img/p3.png">
  <img src="img/p4.png">
  <img src="img/p5.png">
</div>

<script src="js/jquery-1.11.3.js"></script>
<script>
  $("#list").click(function(e){
    var $img=$(e.target);
    if($img.is("img")){
      $img.clone()
      //$新img
      .replaceAll("#chosen>img")
    }
  })
</script>
</body>
</html>

clone
clone

 七.事件

1.事件绑定:

 1).绑定事件处理函数:

   .on("事件名",处理函数); //代替addEventListener()

   对于常用的21种事件,可进一步简写为:

   .事件名(处理函数)

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
 </head>
 <body>
    <h1>事件绑定</h1>
    <button id="btn1">发射子弹</button>
  <button id="btn2">获得奖励</button>
    <button id="btn3">失去奖励</button>
    <script src="js/jquery-1.11.3.js"></script>
    <script>
        //单击btn1,发射普通子弹
        $("#btn1").click(function(){
            console.log("发射普通子弹...");
        })
        function shoot2(){
                alert("发射跟踪导弹=>=>=>");
            }
        //单击btn2,给btn1添加一种导弹
        $("#btn2").click(function(){
            $("#btn1").click(shoot2)
        })
        //单击btn3,从btn1上移除导弹
        $("#btn3").click(function(){
            $("#btn1").off("click",shoot2)
        })
    </script>
 </body>
</html>

off
off

 2).利用冒泡:

    $父元素.on("事件名","选择器",处理函数)

    两个难题:

     *). this 又可以用了 => e.target

     *). if($xx.is("条件选择器")) 不用再写

        仅把选择器提前到第二个参数上。 

     强调: "选择器"必须现对于$父元素内编写

     解绑: .off("事件名",处理函数);

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    body{
      text-align: center;
    }
  </style>
</head>
<body>
<h1>替换节点</h1>

<div id="chosen">
  <img src="img/p0.png">
</div>
<hr/>
<div id="list">
  <img src="img/p3.png">
  <img src="img/p4.png">
  <img src="img/p5.png">
</div>

<script src="js/jquery-1.11.3.js"></script>
<script>
  /*$("#list").click(function(e){
    var $img=$(e.target);
    if($img.is("img")){
      $img.clone()
      //$新img
      .replaceAll("#chosen>img")
    }
  })*/
  $("#list").on("click","img",function(){
      $(this)
      .clone()
      //$新img
      .replaceAll("#chosen>img")
  })
</script>
</body>
</html>

利用冒泡
利用冒泡

 2.页面加载后自动执行:

  问题: 直接放在js文件中,不属于任何事件的代码,只要页面引入就立刻执行。如果在head中引入,极可能找不到页面元素,导致错误。

  解决: 所有代码都要放在“页面加载完成”事件中。等待事件发生时,才执行。

  两个“加载完成事件”

  1). 仅DOM内容加载完成:DOMContentLoaded (DOMContentLoaded这个事件名有兼容性问题所以jquery对它进行简化)提前

    仅等待HTML和JS加载完就提前触发

    何时: 和css,图片无关的代码,都要放在DOMContentLoaded中

    如何: $(document).ready(function(){

            //会在document(DOM)准备好之后自动触发

         })

        ||(简化)

         $().ready(function(){})

        ||(再简化)

                  简化$(function(){})

*所以把任何一个函数放到$中绝不是调用的意思,是事件绑定

2). 整个网页加载完成: Load 延迟

    需要等整个网页(HTML,JS,CSS,图片)都完成才触发

    何时: 依赖css和图片的代码,只能放在load中

    如何: $(window).load(function(){

                          //load是 .addEventListener("load",...)的简写

                       //所有页面内容都加载完才能触发

         })

*多数情况下都是选第一种$(document).ready(function(){……

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
    <script src="js/jquery-1.11.3.js"></script>
    <script>
        //在onload事件中显示整个页面加载完成的时间
        $(window).load(function(){
            alert(`页面加载完成事件,at:${new Date().toLocaleTimeString()}`);
        })
    //在ready事件中显示DOM内容加载完成的时间
    $(function(){
        $("p").css("color","red");
        alert(`仅dom内容加载完成,at:${new Date().toLocaleTimeString()}`)
    })
    </script>
 </head>
 <body>
  <h1>页面加载完成事件</h1>
    <p>welcome to my first web page</p>
    <script>
        //直接在此显示DOM内容加载完成的时间
    </script>
 </body>
</html>

load
load

3.鼠标事件:

   .mouseover()   .mouseout()

   问题: 即使进出子元素,也会频繁触发父元素上的处理函数

   解决: .mouseenter()  .mouseleave()

   如果同时绑定mouseenter和mouseleave

     其实,只需要绑定一个hover:

      $elem.hover(//等效于同时绑定了mouseenter和leave

         function(){ ... }, //给mouseenter

         function(){ ... } //给mouseleave

      )

     更简化: 如果两个处理函数可用toggleXXX简写为一个

       其实只要给一个处理函数即可。

       $elem.hover(function(){  xxxx.toggleXXX()  })

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
    <style>
        #target {
            border: 1px solid #eee;
            border-radius: 6px;
            padding: 10px;
            transition: all .5s linear;
        }
        #target.hover {
            border: 1px solid #aaa;
            box-shadow: 0 0 6px #aaa;
            color:#fff;
            background:red;
        }
    </style>
 </head>
 <body>
  <h1>使用hover(fn,fn)</h1>

    <h3>鼠标悬停在div上方,则突出显示;移出则取消突出显示</h3>
    <div id="target">
        <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>
    </div>
    <script src="js/jquery-1.11.3.js"></script>
<script>
$("#target")
.hover(
    function(){ $(this).toggleClass("hover") }
    //function(){ $(this).toggleClass("hover") }
)
/*.hover(
    function(){ $(this).addClass("hover") },
    function(){ $(this).removeClass("hover") }
)*/
/*.mouseenter(function(){
    $(this).addClass("hover")
})
.mouseleave(function(){
    $(this).removeClass("hover")
})*/
</script>
 </body>
</html>

mouse
mouse

模拟触发: 没有点击按钮,也想执行按钮的处理函数

  如何: $("按钮").trigger("事件名")

      比如: $("#btnSearch").trigger("click")

                                        触发

       可以更简化: $("按钮").事件名()

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
  </style>
</head>
<body>
<input><button>百度一下</button>
<script src="js/jquery-1.11.3.js"></script>
<script>
$("button").click(function(){
  alert("百度一下,你就知道!");
})
//在input上按回车时自动执行
       //当键 抬起
$("input").keyup(function(e){
  if(e.keyCode==13)
    $("button").click()
})
</script>
</body>
</html>

trigger
trigger

八. 动画API:

 1. 简单动画:

写死的三种动画效果

  1). 显示隐藏: $elem.show()   $elem.hide()  $.elem.toggle()

     默认没有动画效果,瞬间显示隐藏

     原理: .show()和.hide()默认使用display:block/none实现显示隐藏,所以不支持过渡

     如何添加动画效果: 添加"动画持续时间"参数,毫秒数

      原理: 用js定时器反复修改宽、高、透明度属性模拟过渡效果

扩展:计算机有俩个cpu,一个是进行计算使用的程序用的,一个是显卡上的独立的,也就是说在计算机的运行过程中,

程序和绘图不在同一个cpu上执行,当然绘图的效率更高,因为显卡只绘图不做其他,网页中js是程序,归计算程序的cpu解析,而css归绘图引擎解析来控制样式,

而css看不见样式的变化是因为渲染没有交给程序去做,交给显卡去绘制,如果以后一个动画效果既可以用js做也可以用css做 首选css

  2). 上滑下滑: slideUp()   slideDown()      slideToggle()

  3). 淡入淡出: fadeIn()   fadeOut()       fadeToggle()

      缺点: *). 用js程序写死的动画效果,不可维护。

               *). 用js程序模拟的动画效果,效率不如css的transition

                 总结: 简单动画API很少使用

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
    <style>
        *{margin:0; padding:0;}
        #target{
            border-radius:10px;
            background:#eee;
        }
        .fade{/*动画起始状态*/
            height:104px; width:970px; opacity:1;
            padding: 10px; overflow:hidden;
            border: 1px solid #aaa; 

        }
        .out{/*动画结束状态*/
      
        }
    </style>
 </head>
 <body>
    <h1>jQuery动画函数——显示隐藏动画</h1>
    <button id="btn1">显示/隐藏div</button>
    <div id="target">
        <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>
    </div>
    <script src="js/jquery-1.11.3.js"></script>
    <script>
        $("#btn1").click(function(){
            //让#target瞬间显示隐藏: 
            var $tar=$("#target");
            //如果#target是显示的
            /*if($tar.is(":visible"))
                $tar.hide(2000);//就让其隐藏
                    //.slideUp()
                    //.fadeOut()
            else//否则
                $tar.show(2000);//就让其显示
                    //.slideDown()
                    //.fadeIn()*/
            
            $tar.toggle(2000)
                //.slideToggle()
                //.fadeToggle()

      //让#target过度显示隐藏:

      //使用上滑下滑代替显示/隐藏效果
      //使用淡入淡出代替显示/隐藏效果
        });
    </script>
 </body>
</html>

hide
hide
<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    body {
      text-align: center;
    }
    ul {
      list-style: none;
    }
    li {
      margin: 0;
      padding: 0;
      display: inline-block;
      width: 30%;
    }
  </style>
</head>
<body>
<ul id="list">
  <li>尼康(234)</li>
  <li>佳能(22)</li>
  <li>索尼(932)</li>
  <li>宾得(11)</li>
  <li>爱国者(3234)</li>
  <li>欧巴(32)</li>
  <li>海鸥(2334)</li>
  <li>卡西欧(334)</li>
  <li>三星(834)</li>
  <li>松下(234)</li>
  <li>其它品牌(2343)</li>
</ul>

<button data-toggle="brandlist">精简显示品牌</button>

<script src="js/jquery-1.11.3.js"></script>
<script>
//为data-toggle="brandlist"绑定单击事件:
$("[data-toggle=brandlist]").click(function(){
  var $ul=$("#list");
  //如果ul#list下有隐藏的子元素li,就显示全部
  if($ul.is(":has(:hidden)")){
    $ul.children().show();
    //顺便改当前按钮内容为"精简显示品牌"
    $(this).html("精简显示品牌");
  }else{
  //否则,隐藏4以上,且不是最后一个的li:
    $ul.children("li:gt(4):not(:last)")
        .hide()
    //顺便改当前按钮内容为"显示所有品牌"
    $(this).html("显示所有品牌");
  }
})
</script>
</body>
</html>

hide_show
hide_show
<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
    <style>
        .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;
        }
    </style>
 </head>
 <body>
    <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>
//隐藏第一个.content之后的剩余.content
$(".content:gt(0)").hide();
//为整个.accordion绑定单击事件,只允许.title的元素触发单击事件
$(".accordion").on("click",".title",function(){
    //找到自己下边的.content
    var $content=$(this).next()
    //如果自己下边的.content是显示的
    if($content.is(":visible")){
        //只要关闭自己下边的.content
        $content.slideUp();
    }else{//否则(自己下边的是关着的)
        //先打开自己下边的.content
        $content.slideDown()
        //再关闭兄弟中其它.content
        .siblings(".content").slideUp();
    }
})
</script>
 </body>
</html>
手风琴
手风琴

2. 万能动画:

对任意css属性的变化应用动画效果

 1).    $elem.animate({

         css属性: 目标值

         //强调: *). 只能设置单个数值的属性

         //     *). 不支持颜色过渡和CSS3变换的过渡

         //     *). 也是用js定时器模拟的过渡效果

          },持续时间)

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
    <style>
        #d1{
            border:1px solid #aaa;
            border-radius:6px;
            background:#eee;
            width:50px; height:50px;
            position:absolute; top:120px; left:0;
        }
    </style>
 </head>
 <body>
    <h1>animate</h1>
    <button id="btn1">启动动画</button>
    <button id="btn2">停止动画</button>
    <div id="d1">abcd</div>
<script src="js/jquery-1.11.3.js"></script>
<script>
$("#btn1").click(function(){
    //测试animate支持哪些属性
    $("#d1").animate({
        //400//height
        //left:300//top  right   bottom
        //fontSize:64 //lineHeight borderRadio
        /*****不支持******/
        //backgroundColor:"rgb(255,0,0)"
        //transform:"rotate(90deg)"
    },2000)
    //测试启动和停止动画
    //测试延迟执行
})
</script>
 </body>
</html>

animate
animate

2).排队和并发:

   *). 排队: 多个css属性先后依次变化

    如何: 先后调用多个动画API,多个动画API是排队执行的

     原理: 每个元素其实都有一个动画队列

        调用动画API不是立刻执行动画的意思,而仅是将动画加入队列中等待执行。

   *). 并发: 多个css属性同时变化

    如何: 在一个animate中同时定义多个css属性

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    img { position: relative; }
  </style>
</head>
<body>
<img id="s1" src="img/star.png"><br/>
<img id="s2" src="img/star.png"><br/>
<img id="s3" src="img/star.png"><br/>
<img id="s4" src="img/star.png"><br/>

<script src="js/jquery-1.11.3.js"></script>
<script>
/*
s1在屏幕左上角的小星星, 点击后从左移动到屏幕右边
s2在屏幕左上角的小星星,点击后从左移动到屏幕右边,再移动到下边——走直角
s3在屏幕左上角的小星星,点击后从左上角移动到屏幕右下边,走斜线
s4点击小星星,变大、变淡....  直至消失
*/
$("#s1").click(function(){
  if($(this).is(":animated"))
    $(this).stop();//就停止动画
  else
    $(this).animate({left:300},2000)
})
$("#s2").click(function(){
  if($(this).is(":animated"))
    $(this).stop(true);//就停止动画
  else
    $(this).animate({left:300},2000)
        .animate({top:200},2000)
        .animate({left:0},2000)
        .animate({top:0},2000)
})
$("#s3").click(function(){
  $(this).animate({left:300,top:200},4000)
})
$("#s4").click(function(){
  $(this).animate({
    256,
    top:-300,
    opacity:0,
    left:-64
  },2000)
})
</script>

</body>
</html>

排队和并发
排队和并发

 3).停止动画: $elem.stop()

    问题: 默认仅停止当前正在播放的第一个动画,队列中后续动画依然执行

    解决: .stop(true) 停止动画,并清空队列!

 4).     :animated  专门匹配正在播放动画的元素

3.动画结束后自动执行:

   如何: 为动画API添加第三个参数: 回调函数

     回调函数就会在动画接收后自动执行!

 

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
  </style>
</head>
<body>
<img src="img/star.png">

<script src="js/jquery-1.11.3.js"></script>
<script>
  //单击小星星,闪烁三次,最后消失
  //(先使用回调函数实现,再使用排队简化)
  $("img").click(function(){
    for(var i=0;i<3;i++){
      $(this).fadeOut().fadeIn()
    }
    $(this).fadeOut();
  })
</script>
</body>
</html>

排队
排队

九. 类数组对象操作:

 1. 遍历类数组对象:

  $elems.each(function(i, elem){

    //elem->当前正在遍历的DOM元素对象

    $(elem)

  })

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
  </style>
</head>
<body>

<ul id="list">
  <li>98</li>
  <li>85</li>
  <li>33</li>
  <li>99</li>
  <li>52</li>
</ul>

<script src="js/jquery-1.11.3.js"></script>
<script>
  //请给每个不足60分的成绩+10分,并将超过90分的成绩用绿色背景标识出来
console.log($("#list>li"));
$("#list>li").each(function(i,li){
  var $li=$(li);
  //如果当前li的内容<60,就+10
  if($li.html()<60){
    var score=parseFloat($li.html())+10;
    $li.html(score);
  }else if($li.html()>=90){
  //否则如果当前li的内容>=90
    //就设置其背景色为绿色
    $li.css("background","green")
  }
})
</script>
</body>
</html>

each
each

 2. 查找一个元素在jQuery对象中的位置:

  var i=$elems.index(要查找DOM/jq对象)

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    .score {
      list-style: none;
      margin: 0;
      padding: 0;
    }
    .score li {
      display: inline-block;
      width: 50px;
      height: 50px;
      border: 1px solid #f00;
      border-radius: 50%;
      cursor: pointer;
    }
  </style>
</head>
<body>

<h3>请打分</h3>
<ul class="score">
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

<script src="js/jquery-1.11.3.js"></script>
<script>
//获得当前单击的li在所有li中的位置i,i及其执行的都变为红色,i之后的都变为白色
$(".score>li").click(function(){
  var i=$(".score>li").index(this);
  $(`.score>li:lt(${i+1})`)
    .css("background","red")
  $(`.score>li:gt(${i})`)
    .css("background","")
})
</script>
</body>
</html>

index
index

十、封装自定义插件

1. 自定义组件:

 1). 添加自定义函数:

  定义自定义函数:

       //fn=prototype 

  jQuery.fn.自定义函数=function(){

    this->将来调用当前函数的.前的jQuery对象$elems,所以不用$(this)

  }

 调用自定义函数:

  $elems.自定义函数()

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
<script src="js/jquery-1.11.3.js"></script>
<script>
//定义函数sum(),可以计算所有找到的元素的内容的和
     //fn=prototype
jQuery.fn.sum=function(){
  //this->将来调用sum函数的.前的jQuery对象
  var $elems=this;
  var result=0;
  //遍历$elems中每个DOM元素
  $elems.each(function(i,elem){
    //将DOM元素的内容累加到结果中
    result+=parseFloat($(elem).html())
  })
  //返回累加结果
  return result;
}
</script>
</head>
<body>
<ul>
  <li>85</li>
  <li>91</li>
  <li>73</li>
  <li>59</li>
</ul>
<script>
  console.log($("ul>li"))
  //自定义函数库myLib.js,为jQuery扩展sum函数,计算找到的所有元素内容的和。
  var result=$("ul>li").sum();
                      //this->.前的$("ul>li")
  console.log(result);
</script>
</body>
</html>

自定义
自定义

2. 封装自定义插件:

  插件/组件: 网页中拥有独立的HTML,CSS和js的页面区域

  为什么: 重用!

  何时: 今后在页面中只要反复使用的独立页面区域都要封装为插件。

  官方插件: jQuery UI

   1). 按照插件要求编写html内容,不用添加class

   2). 引出插件的css文件

   3). 先引入jQuery.js,再引入jQuery ui.js

   4). 添加自定义脚本,找到插件的父元素,调用插件API

如何:2种情况

1). jQuery官方插件: jQueryUI官网下载: jquery-ui.css.

      images/.
       jquer-ui.js.
      在页面中引入:
       <link rel="stylesheet"     href="css/jquery-ui.css".

      <!-先引入jquery,再引入jquery-ui-->
      <script src="js/jquery-1.11.3.js".
      <script src="js/jquery-ui.js".
      <script>自定义代码</script>

   html中:
按照插件的要求,定义HTML内容结构不需要加任何class
js:查找插件的HTML父元素,对父元素调用一次插件函数即可自动添加样式和行为。
$("my-accordion").accordion();

原理:侵入性:插件函数根据自己的需要,自动为元素添加class和行为

好处:简单

不好:不可维护

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
  <!--1. 引入插件库的css-->
  <link rel="stylesheet" href="css/jquery-ui.css">
 </head>
 <body>
  <h1>jQueryUI:Widgets —— Accordion</h1>
  <!--2. 复制3_accordion.html中div到此,并去掉所有class-->
    <div id="my-accordion">
    <div>《西游记》简介</div>
    <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>
    <div>《水浒传》简介</div>
    <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>
    <div>《红楼梦》简介</div>
    <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>
  </div>
  <!--3. 进入jQuery.js和jquery-ui.js-->
  <script src="js/jquery-1.11.3.js"></script>
  <script src="js/jquery-ui.js"></script>
  <!--4. 查找插件的父元素,调用插件函数()-->
  <script>
    $("#my-accordion").accordion();
    //1. jQuery简单还是Bootstrap简单
    //2. 为什么Bootstrap会代替jQueryUI更受欢迎
  </script>
 </body>
</html>

UI
UI

问题: vs bootstrap

   1). 兼容多种设备:

     jQuery UI仅用于PC端网站
     bootstrap同时支持PC端和移动端网页

   2). 可维护性:

     jQuery UI采用侵入(侵入的意思是指在不知情的情况下插件根据自身需要自动添加class)方式自动添加class,导致可维护性差

     bootstrap强迫手动添加class,但可维护性好。

  用jQuery Ui方式封装自定义插件:

   前提: 已经用传统的HTML,css和js实现了插件的效果

   封装插件的过程,其实是一个提取的过程

   1). 提取插件的css到独立的css文件中:

   2). 定义独立的js文件:

        向jQuery的原型对象fn中添加插件函数

         *侵入: 对插件中的元素自动添加所需的class

      绑定事件处理函数: 提取原页面中的事件绑定代码到插件函数中

  使用jQueryUI风格的插件:

    1). 引入插件.css

    2). 按插件要求编写HTML(不加class)

    3). 引入jquery.js和插件.js
    4). 查找插件父元素调用插件API

封装自定义插件:

前提:已经用html,css和js实现了插件的样式和功能。

如何:1.将插件相关的css,剪切到一个独立的css文件中保存。

   强调:如何避免插件/组件间class冲突:

一个组件内的选择器,都要以插件的父元素的class作为查找的开头/起点。

 2.定义独立的就是文件:

在jquery的原型对象中添加插件函数

1.添加样式:侵入:悄悄自动添加

2.添加行为:

使用自定义插件:同jQueryUI的用法

 

//$("父元素div").accordion()
jQuery.fn.accordion=function(){
  var $parent=this;//.前的$("父元素div")
  //1. 侵入class:
  //为当前插件父元素添加.accordion
  $parent.addClass("accordion")
  //为直接子元素中奇数位置的元素添加.title
  .children(":nth-child(odd)")
  .addClass("title")
  //为每个title的下一个元素添加.content .fade
  .next().addClass("content fade")
  //为所有content中第一个添加.in
  .first().addClass("in")
  //2. 事件绑定
//$(".accordion")
  $parent.on("click",".title",e=>
    $(e.target)
    .next(".content").toggleClass("in")
    .siblings(".content").removeClass("in")
  );
}
my-ui.js
/********accordion********/
.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;
}
my-ui.css

 使用:

<!DOCTYPE html>
<html>
 <head>
  <title> new document </title>
  <meta charset="utf-8">
    <link rel="stylesheet" href="my-ui/my-ui.css">
 </head>
 <body>
    <h1>使用“高度动画”实现“手风琴”组件</h1>
    <div id="my-accordion">
        <div>《西游记》简介</div>
        <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>
        <div>《水浒传》简介</div>
        <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>
        <div>《红楼梦》简介</div>
        <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>
    </div>
  <script src="js/jquery-1.11.3.js"></script>
  <script src="my-ui/my-ui.js"></script>
    <script>
    $("#my-accordion").accordion();
    </script>
 </body>
</html>
accordion.html

十一. ajax:

1.ajax:

jQuery中已经封装好了现成的ajax函数,我们可直接调用

$.ajax({
url:"url路径",
type:"get/post",

data:"uname=dingding&upwd=123456",

  //或者 {uname:"dingding", upwd:"123456"}

//如果本次请求没有参数,可省略data
dataTpye:"json",

//按照国际标准所有服务端接口,都应该返回json格式的字符串。
//但是也不排除例外
//如果返回的不是json,就不要写dataType:"json",会出错
 //因为dataTpye:“json”是自动执行JSON.parse()的意思。如果服务端返回的字符串不是json格式,则JSON.parse()会报错!

//success函数是一个回调函数,会在请求成功结束后,自动调用。参数result,会自动获得服务端返回的值。而且已经被JSON.parse(),范围为js对象了

//jQuery1.x和2.x版本中的写法
success:function(result){} })


//ES6 promise中才支持 .then的写法,如果浏览器不支持ES6,就采用success

//jQuery3.x版本中的写法,旧版也可以写

}).then(function(result){//result获得的就是服务端返回的数据。})

强调:success:和,then()二选一即可

十二. *****跨域:

 什么是: 一个域名向的网页,向另一个域名下的服务器发送请求

 1. 包括:

   1). 域名不同:

 http://www.a.com/index.html -> http://www.b.com/service

   2). 二级域名不同:

     http://mail.tedu.cn/index.html -> http://hr.tedu.cn/server

   3). 端口不同:

    http://localhost:5500/index.html->http://localhost:3000/index

   4). 协议不同:

    http://localhost/index.html -> https://localhost/index

                :80                       :443

   5). 相同机器上: 域名->IP

    http://localhost/index.html->http://127.0.0.1/index

   2.问题:

  浏览器禁止 ajax请求跨域获取数据:

   错误: No "Access-Control-Allow-Origin" headers

 *.(服务区端设置允许跨域):

     //也称CORS:方式: Cross Origin Resource Share

 node.js:

     res.writeHead(200,{

      "Access-Control-Allow-Origin":"*"

     })

     res.send(服务端返回结果)

         res.write(JSON.stringify(服务端返回结果))

     res.end(); 

原理:
1).浏览器其实是发出了请求的。
2).请求也确实成功了,返回的结果,也拿回来了。
3).因为响应结果中带着响应头,记录着数据来源的IP地址。所以,当浏览器查验服务端返回的数据时,发现响应头
中的IP不是当前网页的IP,不让用!

报错: No "Access-Control-Allow-Origin" headers

CORS: Cross Origin Resources Sharing.

跨 源头资源共享策略.

浏览器禁止与当前网页不同来源的数据被使用。

3. 解决:2种

  服务端配置响应头在服务端程序中,在发送消息之前:
1).手动修改响应头:

node.js:

     res.writeHead(200,{

      "Access-Control-Allow-Origin":"http://客户端网页地址栏中的地址"

     })

2).公司:JSONP--同时修改客户端和服务端程序才可支持

前后端分离:

this总结:

 

 

 

 

 

原文地址:https://www.cnblogs.com/liuqingqing-bloom/p/13053110.html