jQuery

什么是jQuery
  1. jQuery是: 第三方开发的,执行DOM操作的,极简化的,函数库
    (1). 第三方开发: 要下载
    (2). 执行DOM操作: jQuery还是在执行DOM的增删改查+事件绑定,学习jQuery等于把DOM重新学一遍!
    (3). 极简化: 将DOM操作的每一步都进行了终极的简化!
    但是: 没有减少步骤!所以还不是最终的简化
    框架: 才是根本上对开发步骤的优化和革新!
    (4). 函数库: jQuery中没有属性!都是用函数来解决一切问题!
  2. 为什么:
    (1). 简单!
    (2). 解决了大部分浏览器兼容性问题: 凡是jQuery让用的,都没有兼容性问题!
  3. 何时: 几乎所有大型项目,大型框架的低层都是用JQUERY开发的!
  4. 问题:
    (1). jQuery依然需要DOM4步实现功能,依然包含大量繁琐的步骤代码!不是终极的简化!
    (2). jQuery只支持PC端,极大的限制了使用的领域。
如何使用jQuery
  1. 下载: jquery.com
    版本:
    (1). 未压缩版: jquery.js
    包含完备的注释和代码格式,以及见名知义的变量名
    优: 可读性好——开发和学习时使用
    缺: 体积大,下载慢
    版本号:
    1.x 唯一支持旧浏览器的版本
    2.x 不再支持旧浏览器
    3.x 也不再支持旧浏览器,且开始支持ES6的特性
    (2). 压缩版: jquery.min.js
    去掉了所有注释和代码格式,将变量名也极简化
    优: 体积小,下载极快——生产环境用
    缺: 毫无可读性

  2. 引入页面:
    (1). 将jquery.js下载到项目本地文件夹中,使用相对路径引入文件:
    比如: <script src="js/jquery-1.11.3.js">
    问题: 因为我们的服务器将来只可能部署在一个位置。所有将来来自不同国家和地区的人访问我们的服务器,可能网速差异很大!
    (2). 使用CDN网络上的共享jquery.js文件
    a. CDN网络: 内容分发网络:
    1). 在全球各地都有服务器,
    2). 且在一台服务器上保存的文件,会自动被同步到全球各地的服务器上
    3). 当客户端想从这个网络中下载一个文件时,CDN网络会自动根据当前客户端到网络中某一台服务器的网络状况优劣,来自动为客户端选择最快的服务器下载文件!
    b. 好处: 全球各地的用户,访问相同的文件,网速几乎是一致的。

    c. 如何引用: <script src="http://CDN网络地址">

  3. 我的第一个jQuery功能: DOM4步
    强调: 一定要先引入jquery.js文件,再编写自定义的<script>
    (1). 示例: 用DOM实现点击按钮,记录点击次数

<h1>jQuery/$工厂函数</h1>
<button id="btn1">click me(0)</button>
<script src="js/jquery-1.11.3.js"></script>
<script>
//DOM4步:
//1. 查找触发事件的元素
//本例中: 查找id为btn1的元素
var btn1=document.getElementById("btn1")
//2. 绑定事件处理函数
btn1.onclick=function(){
  //this->btn1
  //3. 查找要修改的元素
  //本例中: 就是要改当前按钮本身
  //4. 修改元素
  //4.1 先获得当前按钮的内容中的数量
  var html=this.innerHTML;
  //html="click me(1000)"
  //      01234567890123
  //                  -1
  //               |   |
  //         slice(9, -1)
  //parseInt(            )
  var n=parseInt(html.slice(9,-1));
  //4.2 给数量+1
  n++;
  //4.3 将新数量放回当前按钮的内容中
  this.innerHTML=`click me(${n})`
}
</script>

(2). 示例: 用jQuery实现点击按钮,记录点击次数

<h1>jQuery/$工厂函数</h1>
<button id="btn1">click me(0)</button>
<script src="js/jquery-1.11.3.js"></script>
<script>
//DOM4步:
//1. 查找触发事件的元素
//本例中: 创建jQuery类型的一个子对象,并查找id为btn1的元素,最后保存到新创建的jQuery子对象中
var $btn1=$("#btn1")
//2. 绑定事件处理函数
//用jQuery子对象调用jQuery家简化版的函数
$btn1.click(function(){
//被自动翻译为: btn1.addEventListener("click",function(){
  //this->btn1DOM元素,不能用jQuery家函数
  //3. 查找要修改的元素
  //本例中: 必须再创建一个jQuery家子对象,包裹this引用的当前按钮的DOM元素
  var $btn1=$(this);
  //4. 修改元素
  //4.1 先获得当前按钮的内容中的数量
  //用jQuery家子对象调用简化版函数
  var html=$btn1.html();
  //会被自动翻译为btn1.innerHTML
  //html="click me(1000)"
  //      01234567890123
  //                  -1
  //               |   |
  //         slice(9, -1)
  //parseInt(            )
  var n=parseInt(html.slice(9,-1));
  //4.2 给数量+1
  n++;
  //4.3 将新数量放回当前按钮的内容中
  //用jquery子对象,调用简化版函数
  $btn1.html(`click me(${n})`)
  //自动翻译为btn1.innerHTML=`click me(${n})`
})
</script>
jQuery原理
  1. 引入<script src="js/jquery-1.11.3.js">后,内存中:
    (1).其实是在全局添加了一种新的类型: jQuery
    任何一种类型都包含2部分:
    a. 构造函数: 负责创建该类型的子对象
    b. 原型对象: 负责集中保存该类型所有子对象共有的方法
    (2). 要想使用jQuery家简化版函数,必须先创建jQuery家子对象才行。只有jQuery家的子对象,才能使用jQuery简化版函数。原生DOM的元素对象,无法使用jQuery家简化版函数。

  2. $("选择器")创建jQuery家子对象,并用选择器查找DOM元素,并将找到的DOM元素放入jQuery家子对象内部保存起来
    强调: 保存jQuery家子对象的变量,通常建议以$开头,用来与普通DOM家的元素对象变量区分。
    其实: jQuery子对象是一个类数组对象,其中包含了找到的一个或多个DOM元素对象——jQuery对象的本质!

  3. 用jQuery家子对象调用jQuery家简化版函数,会被自动翻译为对应的原生DOM的函数或属性。其实最终作用在内部DOM元素上的还是原生的DOM函数和属性而已。只不过不用我们自己写那么长的函数名和属性名而已。

  4. 原生DOM中的this,引用的是原生DOM的元素对象。无法使用jQuery家简化版函数。必须再用$(this)包一下,包装进一个jQuery家子对象中,才能调用jQuery家简化版函数

  5. jQuery函数的三大特点:
    (1). 每个函数都自带for循环:
    对整个jQuery子对象调用一次简化版函数,等效于自动对jQuery对象内部保存的每个DOM元素都调用一次对应的原生函数
    (2). 一个函数两用: (通常用在能够获取或修改元素的内容或属性或样式的函数上!)
    a. 即可获取值: 如果函数实参中没有提供新值,默认执行获取旧值的操作
    比如: 要获得一个元素的HTML内容: $元素.html()
    b. 又可修改值: 如果函数实参中提供了新值,则该函数自动切换为执行修改操作!
    比如: 要修改一个元素的HTML内容: $元素.html("新HTML内容")
    (3). ?

    示例: 为三个按钮分别实现记录点击次数(DOM实现)

<h1>jQueryAPI特点</h1>
<button id="btn1">click me(0)</button>
<button id="btn2">click me(0)</button>
<button id="btn3">click me(0)</button>
<script src="js/jquery-1.11.3.js"></script>
<script>
//DOM4步
//1. 查找触发事件的元素
//本例中: 因为三个按钮都能点击,所以要找到三个按钮
var btns=document.getElementsByTagName("button");
//2. 绑定事件处理函数
//本例中: 遍历找到的每个按钮
for(var btn of btns){
  //每遍历一个按钮,就绑定单击事件
  btn.onclick=function(){
    //this->当前点击的某一个按钮对象
    //3. 查找要修改的元素
    //本例中: 就是要改当前按钮本身
    //4. 修改元素
    //4.1 先获得当前按钮的内容中的数量
    var html=this.innerHTML;
    //html="click me(1000)"
    //      01234567890123
    //                  -1
    //               |   |
    //         slice(9, -1)
    //parseInt(            )
    var n=parseInt(html.slice(9,-1));
    //4.2 给数量+1
    n++;
    //4.3 将新数量放回当前按钮的内容中
    this.innerHTML=`click me(${n})`
  }
}
</script>

示例: 为三个按钮分别实现记录点击次数 (jQuery实现)

<h1>jQueryAPI特点</h1>
<button id="btn1">click me(0)</button>
<button id="btn2">click me(0)</button>
<button id="btn3">click me(0)</button>
<script src="js/jquery-1.11.3.js"></script>
<script>
//DOM4步
//1. 查找触发事件的元素
//本例中: 因为三个按钮都能点击,所以要找到三个按钮
var $btns=$("button");
console.log($btns);
//2. 绑定事件处理函数
//本例中: 遍历找到的每个按钮
//for(var btn of $btns){//jquery从3.x开始才支持ES6语法
//for(var i=0;i<$btns.length;i++){
//其实: jQuery中多数简化版函数内都*自带for循环*!
$btns.click(function(){
  //alert("疼!");
  //this->当前点击的某一个按钮对象
  //3. 查找要修改的元素
  //本例中: 就是要改当前按钮本身
  var $btn=$(this);
  //4. 修改元素
  //4.1 先获得当前按钮的内容中的数量
  var html=$btn.html();
  //html="click me(1000)"
  //      01234567890123
  //                  -1
  //               |   |
  //         slice(9, -1)
  //parseInt(            )
  var n=parseInt(html.slice(9,-1));
  //4.2 给数量+1
  n++;
  //4.3 将新数量放回当前按钮的内容中
  $btn.html(`click me(${n})`)
})
</script>
查找
  1. $(“选择器”):
    (1). 创建一个jQuery家的子对象
    (2). 用选择器去DOM树查找符合条件的一个或多个元素
    (3). 将找到的一个或多个元素,装进jQuery子对象中保存
    (4). 结果: 返回一个包含一个或多个DOM元素的类数组对象——jQuery家的子对象
  2. jQuery支持所有CSS3选择器
  3. jQuery还新增了一批jQuery独有的选择器:
    (1). 基本过滤选择器:
    a. 回顾: CSS3中的子元素过滤选择器
    1). 包括: :first-child :last-child :nth-child(i) :only-child
    2). 特点: 用元素在其父元素下的相对位置为条件选择元素
    3). 示例: 查找每个ul下指定位置的li
<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("border","1px solid red")
//相当于: .style.border="1px solid red"
//查找每个ul中最后一个li
$("ul>li:last-child")
.css("box-shadow","0 0 5px blue")
//查找每个ul中处于偶数位置的
$("ul>li:nth-child(2n)")
.css("background-color","yellow")
//查找每个ul中第2个li
$("ul>li:nth-child(2)")
.css("color","red")
//查找作为ul下唯一子元素的li
$("ul>li:only-child")
.css("font-size","32px")
</script>

b. 基本过滤:
1). 先提取出所有符合条件的元素放入一个集合中,再统一排好,且编号从0开始
2). 包括:
i. :first :last 选择所有符合条件的元素中第一个元素或最后一个元素
ii. :eq(i) :lt(i) :gt(i) 选择所有符合条件的元素中处于i位置的一个元素,或小于或大于i位置的所有元素
iii. :even :odd 选择所有符合条件的元素中处于偶数位置或奇数位置的元素
在这里插入图片描述
3). 示例: 根据要求选择处于指定位置的元素

<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
$("ul>li:first")
.css("border","1px solid red");
//查找最后一个li
$("ul>li:last")
.css("box-shadow","0 0 5px blue");
//查找处于偶数位置的li
$("ul>li:even")
.css("background-color","yellow");
//查找第2个li
$("ul>li:eq(1)")
.css("color","red");
</script>

4). 示例: 使用css和js两种方式实现按钮组效果

<head>
<meta charset="utf-8" />
<title>...</title>
<style>
ul{
  list-style:none
}
ul>li{
  float:left;
  border:1px solid #555;
  padding:5px 10px;
}
/*让ul下第一个li左上,左下圆角*/
/* ul>li:first-child{
  border-radius:5px 0 0 5px;
} */
/*让ul下最后一个li右上,右下圆角*/
/* ul>li:last-child{
  border-radius:0 5px 5px 0;
} */
/*去掉每个li的下一个兄弟li的左边框*/
/* ul>li+li{
  border-left:0;
} */
</style>
</head>
<body>
<h1>实现按钮组效果</h1>
<ul>
  <li>上一页</li>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>下一页</li>
</ul>
<script src="js/jquery-1.11.3.js"></script>
<script>
/*让ul下第一个li左上,左下圆角*/
$("ul>li:first")
.css("border-radius","5px 0 0 5px")
/*让ul下最后一个li右上,右下圆角*/
$("ul>li:last")
.css("border-radius","0 5px 5px 0")
/*去掉处第一个li之外的所有li的左边框*/
$("ul>li:gt(0)")
.css("border-left",0)
</script>
</body>

(2). 可见性过滤:
a. 什么是: 根据元素是否可见来选择元素:
b. 包括:
1). :visible: 选择可以看见的元素
2). :hidden: 选择隐藏的元素
强调:
可以识别: style="display: none"和<input type=“hidden”
认不出: style="visibility: hidden"和style=“opacity: 0”
c. 示例:

<div class="container">
  <h1>可见性选择器</h1>

  <div id="d1" style="display: none">lorem</div>
  <div id="d2" style="visibility: hidden">lorem</div>
  <div id="d3" style="opacity: 0">lorem</div>
  <input id="d4" type="hidden" name="aa" value="bb"/>

</div>
<script src="js/jquery-1.11.3.js"></script>
<script>
  console.log( $('div.container>:hidden') )
</script>

d. 示例: 下拉菜单

<h1>下拉菜单</h1>
<div class="dropdown">
  <a data-trigger="dropdown" href="#">Dropdown</a>
  <ul class="dropdown-menu">
    <li><a href="#">Action</a></li>
    <li><a href="#">Another action</a></li>
    <li><a href="#">Something else here</a></li>
    <li><hr></li>
    <li><a href="#">Separated link</a></li>
  </ul>
</div>
<script src="js/jquery-1.11.3.js"></script>
<script>
//DOM4步
//1. 查找触发事件的元素
//本例中: 查找有data-trigger属性,且属性值为dropdown的元素
var $a=$("[data-trigger=dropdown]");
console.log($a);
//2. 绑定事件处理函数
//本例中: 单击a,展开a的下一个兄弟ul
$a.click(function(e){
  //防止a默认修改地址栏中的内容
  e.preventDefault();
  //this->a按钮->DOM元素
  var $a=$(this);
  //3. 查找要修改的元素
  //本例中: 要展开a旁边的下一个兄弟元素ul
  var $ul=$a.next();
  console.log($ul);
  //4. 修改元素
  //本例中: 要么让$ul显示,要么让$ul关闭
  //如果现在$ul是关着的,才打开
  if($ul.is(":hidden")){ 
    $ul.show()
    //自动翻译为.css("display","block")
    //自动翻译为.style.display="block"
  }else{//否则就关闭
    $ul.hide()
    //自动翻译为.css("display","none")
    //自动翻译为.style.display="none"
  }
})
</script>

(3). 内容过滤: (了解)
a. 什么是: 根据元素的内容来选择元素
b. 何时: 靠元素,属性,别的条件无法区分元素时,可用元素的内容来选择元素
c. 包括: 4种:
1). :contains(关键词) 选择元素内容中包含指定"关键词"的元素
2). :has(另一个选择器) 选择子元素中包含符合指定选择器要求的元素的父元素
3). :parent 选择内容非空的元素
4). :empty 选择内容为空的元素
d. 示例:

<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-color","green")
//选中包含.close按钮的.alert元素,让它们变为红色的警告框
$(".alert:has(.close)")
.css("background-color","pink")
//选中不包含.close按钮的.alert元素,让它们变为绿色的警告框
$(".alert:not(:has(.close))")
.css("background-color","lightGreen")
</script>

(4). 表单元素过滤选择器:
a. 什么是: 根据表单元素的类型选择不同的表单元素
b. 包括:
1). :input 选择所有表单元素,
包括:input textarea button select
vs input 只能选择input元素——元素选择器
2). :类型名 根据input元素不同的type类型选择元素
input的type属性有几种类型,就有几种对应选择器
包括: :text :password :checkbox :radio …
c. 示例:

<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>
//DOM4步
//1. 查找触发事件的元素
//本例中: 点checkbox元素,决定其他元素启用和禁用
var $chb=$(":checkbox");
//2. 绑定事件处理函数
$chb.click(function(){
  //this->chb元素->DOM元素
  var $chb=$(this);
  //3. 查找要修改的元素
  //本例中: 要修改除:checkbox以外的其它表单元素
  var $others=$(":input:not(:checkbox)")
  //4. 修改元素
  //如果当前chb元素是选中的
  if($chb.is(":checked")){
    //其它表单元素就启用:disabled=false
    //            (不禁用,才是启用)
    //DOM中: others.disabled=false
    //但是jQuery是函数库,所以不能用属性方式!
    //jQ中: 又专门的函数代替DOM中.操作
    $others.prop("disabled",false)
    //自动翻译为: .disabled=false
  }else{//否则
    //其它表单元素就禁用
    $others.prop("disabled",true)
    //自动翻译为: .disabled=true
  }
})
</script>
总结

(1). 如果CSS3选择器就可找到想要的元素,一定首选CSS3的选择器——效率高!
(2). 如果CSS3选择器实现不了,才被迫用jQuery新增的选择器——本质: 低层用js程序模拟的选择器效果,效率低!

补: jQuery中事件绑定:
$查找结果.click(function(){ … })
会被自动翻译为:
for(var 元素 of查找结果){
元素.οnclick=function(){
… …
}
}

补: 获取或修改元素的HTML内容:
$元素.html()
会被自动翻译为: 元素.innerHTML
一个函数两用:
(1). 获取元素的HTML内容: $元素.html()
(2). 修改元素的HTML 内容: $元素.html(“新HTML内容”)

补: 修改元素的样式:
DOM中:
(1). 修改css属性值: 元素.style.css属性=“属性值”
(2). 获取css属性值: getComputedStyle()
Jq中: $元素.css(“css属性”,“属性值”)
也是一个函数两用:
(1). 如果没有给新属性值,则默认执行获取属性的操作:
$元素.css(“css属性”)
自动翻译为: getComputedStyle()
(2). 如果给了新属性值,则切换为修改属性的值:
$元素.css(“css属性”,“属性值”)
自动翻译为: 元素.style.css属性=“属性值”

补: 按节点间关系查找:
查找下一个兄弟元素
(1). DOM中: 元素.nextElementSibling
(2). Jq中: $元素.next()

补: 判断一个元素是否符合指定的条件
var bool=$元素.is(“任意选择器”)
如果元素特征符合选择器要求,则返回true,否则返回false

修改

内容:
(1). 原始HTML内容:
a. DOM中: 元素.innerHTML
b. jq中: $元素.html(“新HTML内容”);
(2). 纯文本内容:
a. DOM中: 元素.textContent
b. jq中: $元素.text(“新纯文本内容”);
(3). 表单元素的值:
a. DOM中: 元素.value
b. jq中: $元素.val(“新值”);
(4). 清空元素的内容:
a. DOM中: 元素.innerHTML="";
b. jq中: $元素.empty()
(5). 示例: 用修改内容方式实现表单验证

<form action="">
  用户名:<input name="uname">
        <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();
//DOM4步
//1. 查找触发事件的元素
//本例中: 当两个文本框失去焦点时
//先查找type为text的用户名文本框
var $txtName=$(":text");
//$txtName.css("background-color","pink")
//再查找type为password的密码框
var $txtPwd=$(":password");
//$txtPwd.css("background-color","lightgreen")
//2. 绑定事件处理函数
//先为姓名文本框绑定失去焦点事件
//DOM中: txtName.οnblur=function(){ ... }
$txtName.blur(function(){
  //this->txtName->DOM元素
  //先定义正则描述用户名的规则
  var reg=/^\w{3,9}$/;
  vali.call(this,reg,"用户名必须介于3~9位之间!")
})
function vali(reg, errMsg){
  var $txt=$(this);
  //3. 查找要修改的元素
  //本例中: 查找当前文本框的下一个兄弟span
  var $span=$txt.next();
  //4. 修改元素
  //如果用正则验证当前文本框的内容通过
  if(reg.test($txt.val())){
    //就设置span的内容为: <img src='img/ok.png'>
    $span.html(`<img src='img/ok.png'>`);
    return true;
  }else{//否则(如果验证未通过)
    //就设置span的内容为: <img src='img/err.png'>错误提示
    $span.html(`<img src='img/err.png'>${errMsg}`);
    return false;
  }
}
//再为密码框绑定失去焦点事件,并验证密码框内容是否符合要求
$txtPwd.blur(function(){
  var reg=/^\w{6,8}$/;
  vali.call(this,reg,`密码必须介于6~8位之间!`)
})

//点击提交按钮时,重新验证两个文本框,哪个文本框出错,就将焦点定位到出错的文本框上
//先查找type=submit的按钮
var $btn=$(":submit");
//再绑定单击事件
$btn.click(function(e){
  //阻止submit按钮自带的提交行为
  e.preventDefault() //同DOM
  //是否提交,有我自己的程序说了算!
  //先验证用户名文本框
  var bool=vali.call($txtName,/^\w{3,9}$/,"用户名必须介于3~9位之间!")
  //如果验证不通过
  if(bool==false){
    //就让用户名文本框获得焦点
    //DOM中: txtName.focus()
    $txtName.focus();
  }else{//否则(如果用户名文本框验证通过)
    //才验证密码框
    var bool=vali.call($txtPwd,/^\w{6,8}$/,`密码必须介于6~8位之间!`)
    //如果密码框验证不通过
    if(bool==false){
      //就让密码框获得焦点
      $txtPwd.focus();
    }else{//否则(如果连密码框也验证通过)
      //将来会发送ajax请求
      //才提示提交成功!
      alert("提交成功");
    }
  }
})
</script>
  1. 属性:
    (1). 字符串类型的标准属性
    a. 用核心DOM4个函数: 元素.get/setAttribute()
    jq中: $ 元素.attr(“属性名”,“属性值”)
    b. 用HTML DOM的.访问: 元素.属性名
    jq中: jq是函数库,不能用属性语法
    所以改为$元素.prop(“属性名”,“属性值”)
    (2). Bool类型的标准属性
    a. DOM中: 只能用.访问: 元素.disabled 元素.checked …
    b. jq中: 也可用.prop()带DOM中.操作
    $元素.prop(“disabled”,true/false)
    $元素.prop(“checked”,true/false)
    (3). 自定义扩展属性
    a. DOM中: 只能用核心DOM的get/setAttribute()访问
    b. jq中: 只能用.attr()访问: $元素.attr(“属性名”,“属性值”)
    在这里插入图片描述
    (4). 示例: 点击图片切换下一张
    a. 原理:
    在这里插入图片描述
    b. 代码:
<img src="img/1.jpg" alt="1">
<script src="js/jquery-1.11.3.js"></script>
<script>
//DOM4步
//1. 查找触发事件的元素
//本例中: 查找img元素
$("img")
//2. 绑定事件处理函数
.click(function(){
  //this->img->DOM元素
  //3. 查找要修改的元素
  //本例中: 要修改的就是当前元素自己
  var $img=$(this);
  //4. 修改元素: 
  //本例中: 修改当前元素的src属性为下一张图片的地址
  //先从当前图片的alt属性中取出序号,转为整数
  var i=parseInt($img.attr("alt"))
                  // .prop("alt")
  //如果i<4,就i+1,否则i=1
  if(i<4){
    i++;
  }else{
    i=1
  }
  //最后:i有两个用途
  //1. 用序号生成新的图片路径,放入img的src属性中
  //2. 放回alt属性中,记录当前打开的是第几张图片,为下一次点击做准备
  //$img.attr("src",`img/${i}.jpg`);
      //.prop("src",`img/${i}.jpg`)
  //$img.attr("alt",i);
      //.prop("alt",i)
  $img.attr({
    src:`img/${i}.jpg`,
    alt:i
  })
})
</script>

(5). 示例: 使用jquery读取自定义扩展属性

<div id="container">
  <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">
</div>
<hr/>
<img src="img/1-l.jpg" class="my-big">

<script src="js/jquery-1.11.3.js"></script>
<script>
//DOM4步:
//1. 查找触发事件的元素
//本例中: 因为多个平级小图片都可单击,所以用事件委托优化,事件只绑定在父元素div上一份
$("#container")
//2. 绑定事件处理函数
.click(function(e){
  //用e.target代替所有this
  //获得当前点击的这一张小图片
  var $small=$(e.target);
  //只允许class为my-small的元素触发事件
  if($small.is(".my-small")){
    //3. 查找要修改的元素
    //本例中:查找class为my-big的大图片
    $(".my-big")
    //4. 修改元素
    //本例中: 修改大图片的src属性为当前小图片的自定义扩展属性data-target的属性值
    .attr("src",$small.attr("data-target"))
  //.prop()         //.prop()
  //可以换           //不能换
  }
})
</script>
  1. 样式:
    (1). 获取或修改css属性:
    a. DOM中:
    1). 修改css属性: 元素.style.css属性=值
    2). 获取css属性: getComputedStyle(元素)
    b. jq中: 合并为: $元素.css(“css属性名”, “值”)
    c. 问题: 如果同时修改多个css属性,用css()修改,代码会很繁琐
    (2). 用class方式批量修改css属性
    a. DOM中: 元素.className=“class名” ——只能整体替换
    b. HTML5: 元素.classList.add(“class名”)
    .remove(“class名”)
    ——兼容性问题
    c. jq中: 4个函数:
    1). $元素.addClass(“class名”)
    2). $ 元素.removeClass(“class名”)
    强调: removeClass()不是移除class属性的意思,而是移除class属性值中众多class名中的一个指定的class名。其余class保持不变。
    3). var bool=$元素.hasClass(“class名”)
    4). $ 元素.toggleClass(“class名”)
    i. 在有和没有这个class之间来回切换。
    ii. 等效于:
    if($元素.hasClass(“class名”)){
    $元素.removeClass(“class名”)
    }else{
    $元素.addClass(“class名”)
    }
    5). 强调: toggleClass()不能代替addClass()和removeClass()因为toggleClass()反复调用,不是总添加,也不是总删除,而是一次添加,一次删除,交替执行。所以toggleClass()时无法保证这次点击是添加还是删除。所以,只有确实要在有没有一个class之间来回切换时,才能用toggleClass()。如果确定只希望添加class,则必须用addClass(),如果只希望移除class,就必须用removeClass()

    d. 示例: 双态按钮(麻烦)

<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>
//DOM4步
//1. 查找触发事件的元素
//本例中: 查找class为btn的元素
$(".btn")
//2. 绑定事件处理函数
.click(function(){
  //3. 查找要修改的元素
  //本例中: 就是修改当前按钮自己
  var $btn=$(this)
  //4. 修改元素
  //如果当前元素有class down
  if($btn.hasClass("down")){
    $btn.removeClass("down");//就移除掉class down
  }else{//否则(如果当前元素没有class down)
    //就添加class down
    $btn.addClass("down")
  }
})
</script>
</body>

e. 简写: 双态按钮(简写)

<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>
//DOM4步
//1. 查找触发事件的元素
//本例中: 查找class为btn的元素
$(".btn")
//2. 绑定事件处理函数
.click(function(){
  //3. 查找要修改的元素
  //本例中: 就是修改当前按钮自己
  //var $btn=$(this)
  //4. 修改元素
  //如果当前元素有class down
  // if($btn.hasClass("down")){
  //   $btn.removeClass("down");//就移除掉class down
  // }else{//否则(如果当前元素没有class down)
  //   //就添加class down
  //   $btn.addClass("down")
  // }
  $(this).toggleClass("down")
})
</script>
</body>

f. 示例: 万能对话框效果:

<head>
<title> new document </title>
<meta charset="utf-8">
<style>
.alert{
  border:1px solid #a33;
  color:#922;
  background:#fee;
  padding:10px;
  box-sizing: border-box;
  position:fixed;
}
.alert>.close{
  float:right;
  font-weight:bold;
  opacity:.5;
  cursor:pointer;
}
.alert>.close:hover{opacity:1}
/*定义淡入淡出动画的初始状态,常驻元素*/
.fade{ 
  width:0px;
  height:100px;
  top:50%;
  left:50%;
  margin-left:0px;
  margin-top:-50px;
  opacity:0;
  overflow:hidden;
  transition:all .5s linear;
}
/*定义淡入淡出动画的结束状态*/
.in{ 
  width:300px;
  height:100px;
  top:50%;
  left:50%;
  margin-left:-150px;
  margin-top:-50px;
  opacity:1;
}
</style>
</head>
<body>
<button id="btn">click me!</button>
<div class="alert fade">
  <span class="close">×</span>
  <p>您的浏览器版本太低!请下载最新版本的浏览器</p>
</div>
<script src="js/jquery-1.11.3.js"></script>
<script>
//当单击按钮时,弹出对话框
$("#btn").click(function(){
  //$(".alert").show();//show()->display=block
  //为.alert添加class in
  $(".alert").addClass("in");
})
//当单击x时,关闭对话框
$(".close").click(function(){
  //$(".alert").hide();//hide()->display=none
  //为.alert移除class in
  $(".alert").removeClass("in");
})
</script>
</body>
  1. 简写: 针对.attr()/.prop()/.css()
    如果需要同时修改一个元素的多个属性时
    $元素.attr/prop/css({
    “属性名”:“属性值”,
    … : …
    })
    更简写:
    (1). 如果属性名中不带-,可省略""
    反之如果属性名中带-:
    1). 可以加引号,保留-: 比如: $ 元素.css({ “font-size”:16 })
    2). 去-变驼峰,也无需加"": $元素.css({ fontSize:16 })
    (2). 长度,大小,距离等属性值不需要加单位px!可直接写数字!——只有jQuery才能这么写
按节点间关系查找
  1. 父子关系:
    (1). 获得父元素:
    a. DOM中: 元素.parentNode
    b. jq中: $元素.parent();
    (2). 获得所有直接子元素:
    a. DOM中: 元素.children
    b. jq中: $元素.children(“选择器”) 可用选择器仅获取符合调价的个别子元素,而不一定总是选择所有直接子元素
    c. children的问题: 只能查找直接子元素,无法在所有后代中查找!
    d. jq中新增: $元素.find(“选择器”) 在所有后代中查找符合条件的元素。
    强调: “选择器"参数,必须要写!
    (3). 获得第一个直接子元素:
    a. DOM中: 元素.firstElementChild
    b. jq中: $元素.children(”:first-child")
    (4). 获得最后一个直接子元素:
    a. DOM中: 元素.lastElementChild
    b. jq中: $元素.children(":last-child")
  2. 兄弟关系:
    (1). 下一个兄弟:
    a. DOM中: 元素.nextElementSibling
    b. jq中: $元素.next();
    c. 问题: 只能选择下一个兄弟,无法选择之后所有兄弟
    d. jq中新增: $元素.nextAll(“选择器”) 可选择当前元素之后所用平级兄弟元素。
    (2). 前一个兄弟:
    a. DOM中: 元素.previousElementSibling
    b. jq中: $元素.prev();
    c. 问题: 只能选择前一个兄弟,无法选择之前所有兄弟
    d. jq中新增: $元素.prevAll(“选择器”) 可选择当前元素之前所用平级兄弟元素。
    (3). $元素.siblings(“选择器”) 可获得除当前元素之外的所有兄弟元素!
选择指定的li
<!-- ul.top>(li.parent>ul>li.child*3)*2 -->
<ul class="top">
  <li class="parent1">parent1
    <ul>	
      <li class="child">5</li>
      <li class="child">4</li>
      <li class="child">3</li>
      <li class="child">2</li>
      <li class="child">1</li>
    </ul>
  </li>
  <li class="parent2">parent2
    <ul>
      <li class="child"></li>
      <li class="child"></li>
      <li class="child"></li>
    </ul>
  </li>
</ul>
<script src="js/jquery-1.11.3.js"></script>
<script>
//修改class为top的ul的所有直接子元素
$(".top")
.children().css("border","1px solid red")
//修改class为top的ul的所有后代li
$(".top")
.find("li").css("box-shadow","0 0 5px green")
//为class为child的li绑定单击事件
$(".child").click(function(){
  //选择当前元素的下一个元素/前一个元素/之前所有/之后所有/除自己之外所有
  $(this)
  .siblings()//.nextAll()//.prevAll()//.prev()//.next()
  .css("background-color","yellow")
})
</script>
两种常用的打分和点赞
<ul class="top">
  <li class="parent1">parent1
    <ul>
      <li class="child">5</li>
      <li class="child">4</li>
      <li class="child">3</li>
      <li class="child">2</li>
      <li class="child">1</li>
    </ul>
  </li>
  <li class="parent2">parent2
    <ul>
      <li class="child"></li>
      <li class="child"></li>
      <li class="child"></li>
    </ul>
  </li>
</ul>
<script src="js/jquery-1.11.3.js"></script>
<script>
//为class为parent1下的所有li绑定单击事件
//用事件委托优化,事件只绑定在父元素parent1上一份
$(".parent1").click(function(e){
  //用e.target代替this
  var $li=$(e.target);
  //只允许class为child的子级li触发事件
  if($li.is(".child")){
    //先把自己变为黄色
    $li.css("background-color","yellow")
     //return $li
    //再把自己之后的都变为黄色
       .nextAll() //让主语变成当前li之后的所有兄弟
       .css("background-color","yellow");
      //return 当前li之后的所有兄弟
      //因为下一句话的主语不是之后的所有兄弟,而是$li,所以链式操作到此结束!

    //再把自己之前的都变为白色
    $li.prevAll()
      .css("background-color","#fff")
  }
})

//为class为parent2下的所有li绑定单击事件
//用事件委托优化,事件只绑定在父元素parent2上一份
$(".parent2").click(function(e){
  //用e.target代替this
  var $li=$(e.target);
  //只允许li触发事件
  if($li.is("li")){
    //先将自己变为黄色
    $li.css("background-color","yellow")
      //return $li
    //再将除自己之外的所有兄弟都变为白色
       .siblings()
       .css("background-color","#fff")
  }
})
</script> 
标签页效果
<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>
//DOM4步
//1. 查找出发事件的元素
//本例中: 因为三个a都可点击,所以用事件委托优化,事件只绑定在父元素ul上一份
$("ul.tabs")
//2. 绑定事件处理函数
.click(function(e){
  //防止a擅自修改地址栏
  e.preventDefault();
  //用e.target代替this
  var $a=$(e.target);
  //只允许有data-toggle属性,且属性值为"tab"的元素触发事件
  if($a.is("[data-toggle=tab]")){
    //3. 查找要修改的元素
    //4. 修改元素
    //先找到当前a的爹li,添加class active
    $a.parent() //当前a的爹li
      .addClass("active")
      //return $a.parent() //当前a的爹li
    //再将当前a的爹li的所有兄弟li都移除class active
      .siblings() //当前a的爹li的其余兄弟li
      .removeClass("active")
  }
})
</script>
</body>
添加/删除/替换/克隆
  1. 添加元素:
    (1). DOM中: 3步:
    a. 创建新的空元素: var a=document.createElement(“a”)
    b. 设置关键属性:
    a.innerHTML=“go to tmooc”
    a.href=“http://tmooc.cn”
    c. 将新元素添加到DOM树
    1). 末尾追加: 父元素.appendChild(a)
    2). 中间插入: 父元素.insertBefore(a, 现有子元素)
    3). 替换: 父元素.replaceChild(a, 现有子元素)
    (2). Jq中: 2步:
    a. 用HTML片段创建新元素:
var $新元素=$(`HTML代码片段`)

结果: HTML代码片段中写了哪些元素 $ ()就会批量创建那些元素,又因为HTML代码片段中肯定已经设置了必要的属性,$ ()就会自动为元素添加指定的属性。不需要再额外添加关键属性。
b. 将新元素添加到DOM树:
1). 末尾追加:
$ 父元素.append ($新元素) //return $父元素
$ 新元素.appendTo ($父元素) //return $新元素
根据链式操作的要求,下一步操作,需要以哪个元素作为主语,则前一步就要选择相同主语的函数使用,才能让前后两步串联起来
2). 开头插入: $ 父元素.prepend ($新元素)
$ 新元素. prependTo ($父元素)
3). 插入到现有元素前:
$ 现有子元素.before($新元素)
$ 新元素.insertBefore($现有子元素)
将新元素插入到现有元素之前
4). 插入到现有元素后:
$ 现有子元素.after($新元素)
$ 新元素.insertAfter($现有子元素)
5). 替换: $ 现有子元素.replaceWith($新元素)
$ 新元素.replaceAll($现有子元素)
用新元素代替现有子元素
在这里插入图片描述
2. 删除元素:
(1). DOM中: 父元素.removeChild(子元素)
(2). Jq中: $任意元素.remove();
3. 示例: 点击按钮添加div

<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>
//DOM4步
//1. 查找触发事件的元素
//本例中: 查找id为add-block的按钮
$("#add-block")
//2. 绑定事件处理函数
.click(function(){
  //3. 查找要修改的元素
  //本例中: 新添加的元素要放入容器元素container中
  //4. 修改元素
  //先用HTML片段创建一个新元素(同时自动创建子元素)
  $(`<div class="block">
    <span class="close">×</span>
  </div>`)
  //再为$block设置随机背景颜色
  .css(
    "background-color",
    `rgb(${
      parseInt(Math.random()*256)
    },${
      parseInt(Math.random()*256)
    },${
      parseInt(Math.random()*256)
    })`
  )
  //将新创建的元素插入到class为container的父元素内部的开头
  .prependTo(".container");
})

//DOM4步
//1. 查找触发事件的元素
//本例中: 因为多个x可以点击,所以利用事件委托优化,事件应该只绑定在父元素.container上一份即可
$(".container")
//2. 绑定事件处理函数
.click(function(e){
  //用e.target代替this
  var $x=$(e.target);
  //只允许class为close的元素触发事件
  if($x.is(".close")){
    //3. 查找要修改的元素
    //本例中: 要删除当前x的爹
    $x.parent()
    //4. 修改元素
      .remove();
  }
})
</script>
</body>

克隆: var $ 新元素=$元素.clone()

选择飞机
<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>
//DOM4步
//1. 查找触发事件的元素
//本例中: 三个img都能点,所以用事件委托优化,事件只绑定在id为list的父元素上一份即可
$("#list")
//2. 绑定事件处理函数
.click(function(e){
  //用e.target代替this
  var $img=$(e.target);
  //只允许img元素触发事件
  if($img.is("img")){
    //3. 查找要修改的元素
    //4. 修改元素
    //用当前图片的克隆的副本替换id为chosen下的img
    $img.clone().replaceAll("#chosen>img")
  }
})
</script>
jQuery函数三大特点
  1. 自带for循环: 对整个jQuery子对象调用一次简化版函数,等效于对jQuery子对象内部保存的每个DOM元素都调用一次原生的函数或属性。
  2. 一个函数两用: 对于具有修改功能的函数,一个函数既可以获取值,又可以修改值:
    (1). 如果调用函数时,没有给新值,则默认执行读取旧值的操作
    (2). 如果调用函数时,给了新值,则自动切换为修改值
  3. 几乎每个函数都会返回正在操作的jQuery对象:
    可以使用链式操作减少变量的使用
    链式操作: 前一步的返回值,刚好是下一步所需的主语
    比如: 当前后两句话主语刚好相同时:
    //自己变成黄色
    $li.css(“background-color”,“yellow”)
    //自己的兄弟都变为白色
    $li.siblings().css(“background-color”,"#fff")
    可简化为:
    //自己变成黄色
    $li.css(“background-color”,“yellow”)
    //因为.css()又return $li
    //所以,可继续:
    .siblings().css(“background-color”,"#fff")
事件
  1. DOM中最灵活的事件绑定:
    (1). 添加事件监听:
    元素.addEventListener(“事件名”,事件处理函数)
    (2). 移除事件监听:
    元素.removeEventListener(“事件名”,原事件处理函数)
  2. jq中:
    (1). 添加事件监听:
    $元素.on(“事件名”,事件处理函数)
    (2). 移除事件监听:
    $元素.off(“事件名”,原事件处理函数)
    (3). 示例: 用on绑定事件
<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").on("click",function(){
  console.log(`发射普通子弹...`)
})
//如果一个处理函数可能被移除,则必须用有名称的函数绑定
function shoot2(){
  alert("发射跟踪导弹=>=>=>")
}
//为btn2绑定单击事件处理函数
$("#btn2").on("click",function(){
  //想给btn1再添加一种新的跟踪导弹
  $("#btn1").on("click",shoot2)
})
//当单击btn3时,从btn1上移除shoot2函数
$("#btn3").on("click",function(){
  $("#btn1").off("click",shoot2)
})
</script>
  1. 简写: 对常用的事件提供了更简化的绑定方式:
    (1). $元素.事件名(处理函数)
    click => on => addEventListener
    (2). 常用事件列表: 思维导图jQuery/事件/常用事件列表
    blur 失去焦点
    change 下拉列表选中项改变
    click 单击
    dblclick 双击
    focus 获得焦点
    keydown 键盘按键按下
    keyup 键盘按键抬起
    mousedown 鼠标按键按下
    mouseenter 鼠标进入(jq)
    mouseleave 鼠标移出(jq)
    mousemove 鼠标移动
    mouseout 鼠标移出(dom)
    mouseover 鼠标进入(dom)
    mouseup 鼠标按键抬起
    resize 窗口大小改变
    scroll 网页滚动
简化jq事件绑定
<!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绑定单击事件处理函数
$("#btn2").click(function(){
  //想给btn1再添加一种新的跟踪导弹
  $("#btn1").click(shoot2)
})
//当单击btn3时,从btn1上移除shoot2函数
$("#btn3").click(function(){
  $("#btn1").off("click",shoot2)
})
</script>
</body>
</html>
事件委托

(1). DOM中:
a. 事件只绑定在父元素上一份
b. 用e.target代替this
c. 判断e.target特征,只允许符合要求的元素触发事件
d. 比如:

//三个img都能点,所以用事件委托优化,事件只绑定在id为list的父元素上一份即可
$("#list").click(function(e){
  //用e.target代替this
  var $ img=$ (e.target);
  //只允许img元素触发事件
  if($img.is("img")){
    ... ...
  }
})

(2). Jq中:
a. 事件还是绑在父元素上,只不过必须用on绑定:
b. 不需要e.target,this又可以用了!this->e.target
c. 不用自己写if判断,而是使用选择器参数自动过滤符合条件的元素
d. 比如:
//三个img都能点,所以用事件委托优化,事件只绑定在id为list的父元素上一份即可
//只允许img元素触发事件
$("#list").on(“click”, “img” ,function(e){
//用e.target代替this
var $ img=$ (this); //this->e.target
if($img.is(“img”)){
… …
}
})
e. 示例: 用on简写飞机案例

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


//DOM4步
//1. 查找触发事件的元素
//本例中: 三个img都能点,所以用事件委托优化,事件只绑定在id为list的父元素上一份即可
$("#list")
//2. 绑定事件处理函数
//本例中: 如果打算用事件委托,则必须用on绑定
//还要提前将判断目标元素的选择器条件,作为on的第二个参数
//本例中: 只允许img元素触发事件
.on("click","img",function(/*e*/){
  //this又->e.target
  $(this)
  //3. 查找要修改的元素
  //4. 修改元素
  //用当前图片的克隆的副本替换id为chosen下的img
  .clone().replaceAll("#chosen>img")
})
</script>
  1. 页面加载后自动执行:
    (1). 问题1: js应该放在开头还是放在结尾?
    a. 答: 最好放在body的结尾
    b. 因为: 不应该让js的加载,影响页面内容的加载!
    (2). 问题2: 但是今后在项目中不是所有人都习惯将js放在结尾,有的人就会将js放在开头,这时就会带来执行顺序的问题: 当js提前执行时,浏览器还没有读到body的内容,所以此时如果执行查找,绑定事件等操作,都将不成功!
    a. 解决: 今后所有js代码应该放在一个事件中执行: 页面加载完成事件。
    b. 因为: 放在这个事件中的代码,无论何时绑定,注定只会在页面加载完成后才自动触发执行!
    在这里插入图片描述
    c. 如何:
    window.οnlοad=function(){
    希望在页面加载完成后才自动执行的代码
    比如: 查找元素,绑定事件,初始化页面元素的内容给和样式等。。。
    }
    d. 示例: 使用window.onload保证代码永远在页面加载完成后才自动执行:
    14_ready1.js
//希望以下事件绑定代码永远在窗口内容加载完成后才自动执行
window.onload=function(){
  $("#btn1").click(function(){
    alert("我是btn1")
  })
}

14_ready.html

<!DOCTYPE html>
<html>
<head>
<title> new document </title>
<meta charset="utf-8">
<script src="js/jquery-1.11.3.js"></script>
<script src="14_ready1.js"></script>
</head>
<body>
<button id="btn1">click me1</button>
</body>
</html>

(3). 问题3: window.οnlοad=function(){}用赋值方式给窗口绑定事件,如果多个js文件中都有window.οnlοad=function(){},结果只有一个window.onload能保存下来!
b. 解决: 用addEventListener()代替οnlοad=
window.addEventListener(“load”, function(){ … })
c. 因为:window.addEventListener,可以为window.load事件添加多个处理函数而不会发生覆盖。
d. 示例:用addEventListener代替οnlοad=function(){ … }
14_ready1.js

//希望以下事件绑定代码永远在窗口内容加载完成后才自动执行
window.addEventListener('load',function(){
  $("#btn1").click(function(){
    alert("我是btn1")
  })
})

14_ready2.js

//希望当窗口内容加载完成时,为btn2绑定单击事件
window.addEventListener('load',function(){
  $("#btn2").click(function(){
    alert("我是btn2")
  })
})

14_ready.html

<head>
<title> new document </title>
<meta charset="utf-8">
<script src="js/jquery-1.11.3.js"></script>
<script src="14_ready1.js"></script>
<script src="14_ready2.js"></script>
</head>
<body>
<button id="btn1">click me1</button>
<button id="btn2">click me2</button>
</body>

(4). 问题4: window.onload必须等待所有页面内容(HTML+JS+CSS+图片)加载完成才能执行——晚。但是,有些操作,根本不关心样式和图片,就要快!就要早一步用上!
a. 解决: 其实在window.onload之前还有一个加载完成事件:
DOMContentLoaded: 仅DOM内容(HTML+JS)加载完成就提前触发——早!
b. 今后,凡是和css和图片无关的页面初始化操作,都应该放在DOMContentLoaded事件中,提前执行。让用户能早一步用上功能,而不是被迫等待样式和图片加载完才能使用功能。

c. 但是, 因为DOMContentLoaded事件有兼容性问题,所以,jq中: $(document).ready(function(){ … }) 代替了DOMContentLoaded
d. 但是, 函数名太长了!
简化: $(function(){ … })

用jQuery实现DOM内容加载完就提前执行

14_ready1.js

//希望以下事件绑定代码永远在窗口内容加载完成后才自动执行
//window.addEventListener('load',function(){
//DOMContentLoaded
//$(document).ready(function(){
$(function(){
  alert("为btn1绑定单击事件")
  $("#btn1").click(function(){
    alert("我是btn1")
  })
})

14_ready2.js

//希望当窗口内容加载完成时,为btn2绑定单击事件
//window.addEventListener('load',function(){
//DOMContentLoaded
//$(document).ready(function(){
$(function(){
  alert("为btn2绑定单击事件")
  $("#btn2").click(function(){
    alert("我是btn2")
  })
})

14_ready.html

<head>
<title> new document </title>
<meta charset="utf-8">
<script src="js/jquery-1.11.3.js"></script>
<script>
window.onload=function(){
  alert("整个页面加载完成")
}
</script>
<script src="14_ready1.js"></script>
<script src="14_ready2.js"></script>
</head>
<body>
<button id="btn1">click me1</button>
<button id="btn2">click me2</button>
</body>

(5). 总结:
a. 今后所有和css和图片无关的jq代码都应该放在
$(function(){
… …
})中
b. 但是,必须依赖css和图片的jq代码要是要放在window.onload中,但是可以用jquery的写法
$(window).load(function(){ … })
等效于window.addEventListener(“load”,function(){ … })

鼠标事件

(1). DOM中:
onmouseover 当鼠标进入元素时
onmouseout 当鼠标移出元素时
(2). 问题: 反复进出子元素,也会反复触发父元素上的进出事件——歧义
(3). 解决: jq中: 用mouseenter和mouseleave代替了mouseover和mouseout
(4). 示例:

<head>
<title>事件处理</title>
<meta charset="utf-8"/>
<style>
  #d1 #d2 #d3{cursor:pointer}
  #d1 {
    background-color: green;
    position: relative;
    width: 150px;
    height: 150px;
    text-align: center;
    cursor: pointer;
  }

  #d2 {
    background-color: blue;
    position: absolute;
    top: 25px;
    left: 25px;
    width: 100px;
    height: 100px;
  }

  #d3 {
    background-color: red;
    position: absolute;
    top: 25px;
    left: 25px;
    width: 50px;
    height: 50px;
    line-height: 50px;
  }
</style>
</head>
<body>
<div id="d1">
  <div id="d2">
    <div id="d3">
    </div>
  </div>
</div>
<script src="js/jquery-1.11.3.js"></script>
<script>
//只想在最外层元素d1上绑定鼠标进入和移出事件,监视鼠标
$("#d1")
//.mouseover(function(){
.mouseenter(function(){
  console.log("进入d1范围")
})
//return $("#d1")
//.mouseout(function(){
.mouseleave(function(){
  console.log("移出d1范围")
})
</script>
</body>

(5). 简写: 如果同时绑定mouseenter和mouseleave事件,可简写为hover:
a. $元素.hover( //=mouseenter和mouseleave
function(){ … }, //给mouseenter
function(){ … } //给mouseleave
)
b. 用hover简化上一个示例:

//只想在最外层元素d1上绑定鼠标进入和移出事件,监视鼠标
$("#d1")
.hover(
  function(){
    console.log("进入d1范围")
  },
  function(){
    console.log("移出d1范围")
  }
)

©. 更简化: 如果刚巧两个处理函数可统一为一个处理函数
a. $元素.hover(function(){ … })
b. 强调: .hover()只给一个函数绝对不是只绑定mouseenter的意思,而是同时绑定mouseenter和mouseleave两个事件的意思。只不过两个事件共用同一个处理函数!
c. 示例: 用hover进一步简化程序

<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-color: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时,为target添加hover class。当鼠标移出#target时,从target移除hover class
$("#target").hover(
//mouseenter+mouseleave
  function(){
    $(this).toggleClass("hover")
  }
)
</script>
</body>

模拟触发:
(1). 什么是: 即使没有点击一个按钮,也能触发这个按钮的单击事件,执行和单击按钮相同的操作。
(2). 如何:
a. 标准写法: $元素.trigger(“事件名”)
比如: 想触发一个按钮的单击事件: $btn.trigger(“click”)
b. 简写: 如果要触发的事件属于常用事件列表里边的
可简写为: $元素.事件名()
比如: 想触发一个按钮的单击事件: $btn.click()

实现单击按钮、一边输入、按回车都可执行查找操作
<input><button>百度一下</button>
<script src="js/jquery-1.11.3.js"></script>
<script>
//基本功能: 
//单击百度一下按钮,获得input中用户输入的内容,执行查找操作
$("button").click(function(){
  var value=$(":text").val().trim();
  if(value!==""){
    console.log(`查找 ${value} 相关的内容...`);
  }
})
//高级功能: 
//在文本框中一边输入,一边查询结果
$(":text").on("input",function(){
  $("button").click();//.trigger("click")
})
//按回车也能查找!
$(":text").keyup(function(e){
  if(e.keyCode==13){
    $("button").click();
  }
})
</script>
动画
  1. 简单动画: 写死的固定的三种动画效果
    (1). 显示隐藏:
    a. $元素.show() 是让一个元素显示
    b. $元素.hide() 是让一个元素隐藏
    c. $元素.toggle() 是让一个元素在显示隐藏之间来回切换
    d. 问题: 以上三个函数,如果没有参数,默认采用display方式瞬间显示隐藏,不带动画效果。
    e. 解决: 如果希望以上三个函数带动画效果,必须传入一个动画持续时间参数(ms)
    (2). 上滑下滑:
    a. $元素.slideUp() 上滑
    b. $元素.slideDown() 下滑
    c. $元素.slideToggle() 在上滑和下滑之间来回切换
    (3). 淡入淡出:
    a. $元素.fadeOut() 淡出
    b. $元素.fadeIn() 淡入
    c. $元素.fadeToggle() 在淡入和淡出之间来回切换
    jQuery简单动画的致命问题:
  2. 动画效果是在jQuery函数库中的js代码里写死的,几乎不可维护!
  3. jQuery动画效果使用js定时器模拟的——效率远不如css的transition
    例外: .show() .hide() .toggle()在不加毫秒数参数时,单纯是display:block/none的简写,还是和好用!
测试淡入淡出效果的样式
<head>
<title> new document </title>
<meta charset="utf-8">
<style>
#target{
  border-radius:10px;
  background:#eee;
}
</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(){
  var $target=$("#target");
  //如果$target是显示的
  // if($target.is(":visible")){
  //  $target.hide(2000);//就让$target隐藏
  // }else{//否则
  //  $target.show(2000);//就让$target显示
  // }
  //如果在显示隐藏之间来回切换
  //$target.toggle(2000);
  //$target.slideToggle();
  $target.fadeToggle();
});
</script>
</body>
控制元素显示隐藏
<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>
//DOM4步:
//1. 查找触发事件的元素
$("[data-toggle=brandlist]")
//2. 绑定事件处理函数
.click(function(){
  //3. 查找要修改的元素
  //本例中: 查找>4位置的且不是最后一个的li
  $("li:gt(4):not(:last-child)")
  //4. 修改元素
  //本例中: 切换显示隐藏
  .toggle();

  //其实当前文本框的字也要更换
  //如果这次是精简显示品牌,就换成显示全部品牌,否则就换成精简显示品牌
  var $btn=$(this);
  $btn.html(
    $btn.html()=="精简显示品牌"?
    "显示全部品牌":"精简显示品牌"
  )
})
</script>
</body>
手风琴效果
<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;
}
/*让出了第二个content之外的其余content都暂时隐藏*/
.accordion>.content:not(:nth-child(2)){
  display:none
}
</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>
//DOM4步
//1. 查找触发事件的元素
//本例中:因为多个.title都可单击,所以用事件委托优化,事件只绑定在父元素上一份
$(".accordion")
//2. 绑定事件处理函数
//本例中:因为要用事件委托,所以必须用on绑定,且只允许.title元素触发事件
.on("click",".title",function(){
  //3. 查找要修改的元素
  //4. 修改元素
  //先修改当前title的下一个兄弟content,切换显示隐藏
  $(this).next().slideToggle()
  //title content           return content
  //然后再将兄弟content的其余兄弟中class为content的兄弟隐藏
  .siblings(".content").slideUp();
})
</script>
</body>
万能动画

(1). 什么是: 能对各种css属性应用动画效果
(2). 问题: 不如transition
a. 也是用js定时器模拟的——效率低
b. 不支持:颜色动画,CSS3变换等
(3). 如何:
a. $元素.animate({
Css属性: “目标值”,
… : …
},持续时间)
b. 强调: 只写目标值,不用写起始值。Animate()会自动获取元素当前的状态,根据目标值,自动计算动画变化过程。
c. 只支持单个数值的css属性: 比如: 大小,位置,距离等
d. 示例: 测试animate支持哪些属性?

<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>
<div id="d1">abcd</div>
<script src="js/jquery-1.11.3.js"></script>
<script>
$("#btn1").click(function(){
  $("#d1").animate({
    //width:300,//height
    //left:300,//bottom, top, right
    //marginLeft:200,
    //padding:100,
    //fontSize:32,
    //borderRadius:25

    //backgroundColor:"red"
    //transform:"rotate(60deg)"
  },2000)
})
</script>
</body>

(4). 排队和并发:
a. 并发变化: 多个css属性同时改变
放在一个animate中的多个css属性,是并发变化
b. 排队变化: 多个css属性依次顺序变化!
1). 对同一个元素,先后调用多个动画函数,则多个动画函数中的变化是排队执行的
2). 原理:
i. jQuery为每个元素都创建了一个动画队列
ii. 以上动画函数,其实都不是立刻开始播放动画的意思,都是将一个动画效果,加入这个元素的动画队列中
iii. 如果队列中没有其他动画正在执行,则新加入的动画效果,会立刻执行
iv. 如果队列中前边已经有一个正在执行的动画,则新加入的动画效果,必须等待前一个动画播放完,才能执行
(5). 停止动画: $元素.stop()
a. 坑: 只能停止当前正在播放的一个动画
b. 解决: $元素.stop(true) 停止动画,并清空队列
3. 专门匹配正在播放动画的元素:
jQuery新增选择器: :animated
4. 希望动画结束后自动执行一项任务:
(1). 错误: 直接将下一项任务在动画结束后调用
(2). 因为: 动画低层是js定时器,是异步的!后一项任务不会等前一项任务播放完才执行,而是同时执行。
(3). 正确: 其实每个动画函数都有最后一个参数: 回调函数
放在动画函数最后一个参数回调函数中的代码,只有在动画结束后才自动被调用!
(4). this->当前正在播放动画的元素
5. 示例: 四颗小星星,按照要求动画变化

<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
img { position: relative; }
#s4{
  left:45%;
}
</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(){
  var $star=$(this);
  //如果现在正在播放动画,就停止动画
  if($star.is(":animated")){
    $star.stop()
  }else{//否则才启动动画
    $star.animate({
      left:300
    },1000)
  }
})
$("#s2").click(function(){
  var $star=$(this);
  //如果现在正在播放动画,就停止动画
  if($star.is(":animated")){
    $star.stop(true)
  }else{//否则才启动动画
    $star
    .animate({
      left:300,
    },1500)
    .animate({
      top:100,
    },1500)
  }
})
$("#s3").click(function(){
  var $star=$(this);
  //如果现在正在播放动画,就停止动画
  if($star.is(":animated")){
    $star.stop()
  }else{//否则才启动动画
    $star.animate({
      left:300,
      top:100,
    },3000)
  }
})
$("#s4").click(function(){
  alert("疼!");
  $(this)
  .animate(
    {
      width:172,
      height:172,
      marginLeft:-22,
      marginTop:-50,
      opacity:0
    },
    2000,
    function(){ //在动画播放后自动执行!
      //this->当前正在播放动画的元素
      $(this).hide();
    }
  )
  //希望动画播放完之后,自动隐藏
})
</script>
</body>
类数组对象操作

因为原生js中类数组对象非常受歧视,长得像数组,却用不了数组家函数。但是,jquery家子对象全是类数组对象,如果用不了数组家函数,可能限制jQuery的功能发挥。
所以,jQuery仿着原生js中的数组,添加了两个一模一样功能的函数。让jQuery家孩子也能具有原生js数据的基本功能。

  1. 遍历:
    (1). 原生js中:
    arr.forEach(function(elem, i, arr){
    … …
    })
    原理: 遍历数组arr中每个元素值,对每个元素值调用相同的回调函数。
    (2). Jq中:
    $ 查询结果.each(function(i, elem){
    //i 自动拿到当前遍历的位置
    //elem 自动难道当前正在遍历的一个DOM元素
    //elem不能继续调用jQuery家函数
    //必须$(elem)一下,才能调用jQuery家函数
    })
    原理: 遍历jQuery家子对象(类数组对象,包含了找到的DOM元素)中的每个DOM元素。对每个DOM元素执行相同的回调函数。
    (3). 何时: 今后,只要希望遍历jQuery查询结果中每个DOM元素,对每个DOM元素执行相同操作时,都用.each()方法
    (4).示例: 遍历ul下每个li元素
<script>
//复习原生js的arr.forEach()
var arr=[1,2,3,4,5];
arr.forEach(function(elem,i,arr){
  arr[i]=elem*2
});
console.log(arr);
</script>
<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分的成绩用绿色背景标识出来
$("#list>li").each(function(i,elem){
  //elem->DOM元素li->$(elem)->$li
  var $li=$(elem);
  //如果当前li的内容不足60分
  if($li.html()<60){
    var score=parseFloat($li.html());
    score+=10;
    $li.html(score);//就+10分
  }else if($li.html()>=90){//否则如果当前li的内容>=90分
    //当前li就变为绿色
    $li.css("background-color","green")
  }
})
</script>
  1. 查找元素的位置:
    (1). 回顾原生js中:
    var i=arr.indexOf(“要查找的值”)
    原理: 默认从0位置开始查找第一个等于要找的值的元素出现的值i
    (2). Jq中:
    var i=$查询结果.index(要查找的DOM元素)
    原理: 从查询结果的0位置开始,找第一个和要找的DOM元素相同的元素是第几个
    返回值: 如果找到,返回元素的位置i,如果没找到,返回-1
    (3). 何时: 只要想知道当前这个DOM元素在整个查找结果中是第几个,就用.index()函数
    (4). 示例: 5星评价:
<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>
<script>
//回顾原生js的arr.indexOf()
var arr=[1,2,3,4,5];
      // 0 1 2 3 4
console.log(
  arr.indexOf(3), //2
  arr.indexOf(6)  //-1
)
</script>

<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>
//DOM4步
//1. 查找触发事件的元素
//本例中: 因为多个li都可点击,所以用事件委托优化,事件只绑定在父元素上一份即可
$("ul.score")
//2. 绑定事件处理函数
//本例中: 只允许li元素触发事件
.on("click","li",function(){
  //this->e.target->当前单击的li
  //3. 查找要修改的元素
  //4. 修改元素
  //先获得现在点的是第几个li
//var i=$("ul.score>li").index(this)
      //   查询结果集合       要找的DOM元素
  var i=$(this).index();
  //alert(i);
  //<i+1位置的元素都变黄
  $(`ul.score>li:lt(${i+1})`)
  // 如果i=2    :lt(3)
  .css("background-color","yellow");
  //>i位置的元素都变白
  $(`ul.score>li:gt(${i})`)
  // 如果i=2    :gt(2)
  .css("background-color","#fff");
})
</script>
</body>

(5). 简写: 如果只在一个父元素内查找某个元素的位置:
$(要找的DOM元素).index()
默认就在要找的DOM元素的父元素下查找

添加自定义函数
  1. 如果觉得jQuery家的函数不够用,可以向jquery家添加我们自己定义的函数
  2. 如何添加: 因为jQuery家的函数都是只允许自己家孩子使用,所以我们添加的自定义的jQuery家函数一定也只允许jQuery家孩子使用,所以,应该放在jQuery家的原型对象中:
    jQuery.prototype.自定义方法=function(){
    //this->将来调用这个函数的 $ 查询结果
    //不用$(this)
    //this就可直接继续调用jQuery家其余函数
    }
    强调: 先引入jquery.js
  3. 如何调用: jQuery家的函数都是只允许自己家孩子使用
    $查询结果.自定义方法()
  4. 其实: jQuery.fn=jQuery.prototype
    所以: jQuery.prototype.自定义函数=function(){ … }
    可简写为: jQuery.fn.自定义函数=function(){ … }
  5. 示例: 为jQuery家添加求和的函数
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="js/jquery-1.11.3.js"></script>
<script>
//向jQuery家添加一个sum函数,可以对找到的所有DOM元素内容求和
//jQuery.prototype.sum=function(){
jQuery.fn.sum=function(){
  //alert("调用我们自己添加到jQuery原型对象中的sum函数")
  //因为将来: $("ul>li").sum();
  //所以this->$("ul>li")已经是jQuery家孩子,也是一个类数组对象
  var total=0;
  for(var i=0;i<this.length;i++){
    //因为jQuery家孩子内部保存的是多个DOM元素
    total+=parseFloat($(this[i]).html())
    //                $(  li   )
  }
  return total;
}
</script>
</head>
<body>
<ul>
  <li>85</li>
  <li>91</li>
  <li>73</li>
  <li>59</li>
</ul>
<script>
console.log($("ul>li").sum());
</script>
</body>
封装自定义组件
  1. 组件(component): 拥有专属的HTML,JS,CSS甚至数据的可重用的页面独立功能区域。
  2. 为什么:
    (1). 代码重用!
    (2). 松耦合!便于分工协作!
  3. 何时: 只要发现多个页面中包含相同的功能,都要先封装成组件,再反复使用组件
  4. jQuery官方提供了组件库: jQuery UI
    (1). 下载: jqueryui.com
    jquery-ui.css images文件夹 jquery-ui.js
    (2). 引入:
<link rel="stylesheet" href="css/jquery-ui.css">
	<script src="js/jquery-1.11.3.js">
	//因为jQuery UI的代码都是用jQuery写的,所有必须先引入jQuery,才能使用jQuery UI
	<script src="js/jquery-ui.js">
	结果: jquery-ui.js自动向jQuery家的原型对象中添加一批好用的插件函数

在这里插入图片描述
(3). 使用某个组件:
a. 按组件的要求编写HTML代码(不要加任何class!)
b. 用jQuery()查找要应用组件的父元素,调用组件函数
(4). jQuery UI特点: 侵入性:
a. 什么是侵入性: 不需要程序员敢于,就可自动向元素上添加所需的class和自定义属性。
b. 优点: 简单!
c. 缺点: 不可维护!

使用jQuery实现手风琴效果
<head>
<title> new document </title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/jquery-ui.css">
<script src="js/jquery-1.11.3.js"></script>
<script src="js/jquery-ui.js"></script>
</head>
<body>
<h1>jQueryUI:Widgets —— Accordion</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>
$("#my-accordion").accordion();
</script>
</body>
自定义jQueryUI组件

(0). 前提: 一定是先用HTML,CSS,js已经在页面上实现了插件的效果!只不过是和页面中其他效果的代码混在一起的,不便于重用而已!封装插件的过程,其实是一个提取代码的过程!
(1). 先提取插件的css到一个独立的.css文件中
a. 问题: 如果不同插件间,包含同名的class,会发生覆盖或层叠!最后只有一个class可以保留下来!——插件之间class互相干扰!

BS: 如何避免组件间样式冲突

1). 所有插件的父元素上都要定义一个统一插件名class
比如: 要定义手风琴效果: 在手风情效果的父元素div上,先写 class=“accordion”
2). 只要属于这个插件的子元素的选择器类名,都要以这个插件父元素共同的class名为开头:
比如: 只要属于手风琴效果的子元素的选择器,都要以这个统一的class名作为开头: .accordion>.content.fade
结果: 即使别的插件,刚好也用到了样式类名fade,也不会和手风琴效果的fade样式类冲突!
比如: 对话框插件,也需要一个样式类fade,因为对话框插件的父元素class,通常都会命名为.alert,所以,对话框下的样式类fade,很可能是.alert.fade。
.alert.fade{…}
不会覆盖
.accordion>.content.fade{…}
但是将来在各自组件内使用样式类时,都可用fade
(2). 向jQuery原型对象中添加一个插件函数:
jQuery.fn.插件函数=function(){
//向当前插件元素上自动侵入class
//为当前插件元素绑定事件处理函数
}
(3). 示例: 封装自定义手风琴插件:

my-ui/my-ui.css
/*集中保存我的插件中所有插件的css代码*/
/************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;
}
.accordion>.content.fade{
  height:0;
  opacity:0;
  overflow:hidden;
  transition:all .5s linear;
}
.accordion>.content.in{
  height:84px;
  opacity:1;
}
/************alert************/
.alert.fade{

}
.alert.in{

}

my-ui/my-ui.js
在这里插入图片描述

/***********accordion插件的函数**********/
jQuery.fn.myAccordion=function(){
  //this->$("#my-accordion")->刚好是插件的父元素
  //1. 自动为插件元素侵入class
  //1.1. 为当前插件父元素添加accordion class
  this.addClass("accordion")
  //return $("#my-accordion")
  //1.2. 为当前父元素下的直接子元素中奇数位置的元素加title class
  .children(":nth-child(2n+1)")
  //可以找到三个title div
  .addClass("title")
  //return 三个title div!
  //1.3. 为偶数位置(奇数位置元素的下一个兄弟)的元素加content和fade class
  .next() //return 三个content div
  .addClass("content fade")
  //return 三个content div
  //1.4. 为偶数位置的元素中第一个加in class
  .first() //三个content div中的第一个div
  .addClass("in");
  //2. 为插件元素绑定事件
  //本例中: 因为多个title都可以点,所以用事件委托优化,应该绑定在当前插件的父元素上!
  //只允许class为title的元素触发事件
  this.on("click",".title",e=>
    $(e.target).next(".content").toggleClass("in")
      .siblings(".content").removeClass("in")
  );
}
//想象将来找个插件函数会被怎样调用?
//$("#my-accordion").myAccordion()
//找到插件父元素,调用插件函数

14_accordion.html

<head>
<title> new document </title>
<meta charset="utf-8">
<link rel="stylesheet" href="my-ui/my-ui.css">
<script src="js/jquery-1.11.3.js"></script>
<script src="my-ui/my-ui.js"></script>
</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>
  $("#my-accordion").myAccordion();
</script>
</body>
jQuery中的ajax函数
  1. $.ajax({
    url: “服务器端接口地址”, //不要用相对路径!必须用http://开头的绝对地址!
    type:“get或post”, //请求类型
    data: { //要发送给服务器端的参数,如果没有参数可不写~
    参数1: 值1, //uname:“dingding”,
    参数2: 值2 //upwd:“123456”
    }, //将来发送给服务器的就是uname=dingding&upwd=123456
    dataType:“json”, //如果服务器端返回的是json字符串,则自动调用JSON.parse()将json字符串转为js数组或对象
    success:function(result){ //像onreadystatechange 是回调函数
    //只有请求响应成功后,才会自动调用!
    //result会自动接住服务器端返回的结果数组或对象
    //今后所有对服务器端返回结果(result)的处理,都要放在success函数内部,不要放在外部!
    }
    })
  2. 原理:
    (1). 客户端网页$.ajax()函数先向服务器端发送ajax请求
    (2). 如果有data,则携带参数到服务器端
    (3). $.ajax()函数可自动接收到服务器端的响应结果
    (4). 如果dataType为json,则自动调用JSON.parse()将json字符串转化为数组或对象
    (5). 自动调用success函数,执行其中早就准备好的处理响应结果的代码
  3. 示例: 使用jquery ajax函数请求学子商城首页商品,并添加到页面指定父元素中:

xzserver_start/public/js/index.js

//只要jquery代码都加
$(function(){ 
  $.ajax({
    url:"http://localhost:5050/index",
    type:"get",
    dataType:"json",
    success:function(result){
      console.log(`index.js中获得的数据:`)
      console.log(result);
      //将result中第一个商品的数据,填入第一个商品的HTML片段中,再将html片段填充回id为p1的元素内
      //先取出result中第一个商品对象
      var p1=result[0];
      //定义模板字符串html,保存第一个商品的HTML片段,并用p1的属性填充HTML片段中的内容
      var html=`<div class="card border-0 flex-md-row box-shadow h-md-250">
        <div class="card-body d-flex flex-column align-items-start">
          <h5 class="d-inline-block mb-2">${p1.title}</h5>
          <h6 class="mb-5">
            <a class="text-dark" href="javascript:;">${p1.details}</a>
          </h6>
          <span class="text-primary">¥${p1.price.toFixed(2)}</span>
          <a class="btn btn-primary" href="${p1.href}">查看详情</a>
        </div>
        <img class="card-img-right flex-auto d-none d-md-block" data-src="holder.js/200x250?theme=thumb" alt="Thumbnail [200x250]" src="${p1.pic}" data-holder-rendered="true">
      </div>`;
      //最后将HTML片段填充回id为p1的内容中
      $("#p1").html(html);
    }
  })
})

xzserver_start/public/index.html
… …

<footer id="footer" class="container">
</footer>
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<!-- <script src="js/header.js"></script> -->
<script src="js/index.js"></script>
总结
  1. 查找:
    (1). 用选择器查找: $(“选择器”)
    (2). 节点间关系查找:
    a. 父子关系:
    1). $元素.parent()
    2). $元素.children(“选择器”)
    3). $元素.find(“选择器”)
    b. 兄弟关系:
    1). $元素.next()
    2). $元素.nextAll(“选择器”)
    3). $元素.prev()
    4). $元素.prevAll(“选择器”)
    5). $元素.siblings(“选择器”)
  2. 修改:
    (1). 内容:
    $元素.html(“新HTML内容”)
    $元素.text(“新纯文本内容”)
    $表单元素.val(“新表单元素值”)
    $元素.empty()
    (2). 属性:
    a. 字符串格式的标准属性
    $元素.attr(“属性名”,“属性值”)
    $元素.prop(“属性名”,“属性值”)
    b. bool类型的标准属性
    $元素.prop(“属性名”,新值)
    c. 自定义扩展属性
    $元素.attr(“属性名”,“属性值”)
    (3). 样式:
    a. 修改内联样式或获取完整样式:
    $元素.css(“css属性”,“属性值”)
    b. 修改class属性:
    1). $元素.addClass(“class名”)
    2). $元素.removeClass(“class名”)
    3). $元素.hasClass(“class名”)
    4). $元素.toggleClass(“class名”)
  3. 添加删除替换克隆元素:
    (1). 创建新元素:
    Var $ 新元素=$(“HTML片段”)
    (2). 将新元素添加到DOM树
    a. $ 父元素.append ($新元素)
    $ 新元素.appendTo($父元素)
    b. $ 父元素.prepend ($新元素)
    $ 新元素.prependTo($父元素)
    c. $ 现有子元素.before($新元素)
    $ 新元素.insertBefore($现有子元素)
    d. $ 现有子元素.after($新元素)
    $ 新元素.insertAfter($现有子元素)
    e. $ 现有子元素.replaceWith($新元素)
    $ 新元素.replaceAll($现有子元素)
    (3). 删除元素: $元素.remove();
  4. 事件绑定:
    (1). 标准的绑定写法: $元素.on(“事件名”,事件处理函数)
    (2). 简化绑定写法: $元素.事件名(function(){ … })
    (3). 事件委托: $父元素.on(“事件名”, “选择器”, 事件处理函数) //this->e.target
    (4). 页面加载完成自动执行:
    a. $ (document).ready(function(){ … })
    可简写为:$ (function(){ … })
    b. $(window).load(function(){ … })
    (5). 鼠标事件:
    a. $元素.mouseenter() $元素.mouseleave()
    b. $元素.hover( function(){…}, function(){ … } )

重要函数:
var bool=$元素.is(“选择器”) 专门判断一个元素是否符合选择器的要求!
$查询结果.each(function(i,elem){ … }) 遍历jquery查询结果中每个DOM元素
$查询结果.index(DOM元素) 查找某个DOM元素在jQuery查询结果中的下标位置
如果在一个父元素内查找,可简写为: $(DOM元素).index()
$查找结果.first() 获得查找结果中的第一个元素,并重新包装为jQuery对象。vs [0],只取出第一个位置的元素,是DOM元素
$.ajax({
url:“服务器端接口地址”,
type:“get/post”,
data:{
参数1:值1,
参数2:值2,
},
dataType:“json”,
success:function(result){
… …
}
})

jQuery函数三大特点:

  1. 自带for循环: 对整个jQuery子对象调用一次简化版函数,等效于对jQuery子对象内部保存的每个DOM元素都调用一次原生的函数或属性。
  2. 一个函数两用: 对于具有修改功能的函数,一个函数既可以获取值,又可以修改值:
    (1). 如果调用函数时,没有给新值,则默认执行读取旧值的操作
    (2). 如果调用函数时,给了新值,则自动切换为修改值
  3. 几乎每个函数都会返回正在操作的jQuery对象:
    可以使用链式操作减少变量的使用
    链式操作: 前一步的返回值,刚好是下一步所需的主语

jQuery中$的原理:
$=jQuery=new jQuery()
一共有四种用法:
4. $ (“选择器”) 查找元素,创建jQuery对象,将找到的元素保存进jQuery对象中
$ (“选择器”)在查找时,有优化
(1). 如果传入的是id选择器,则 $ ()自动调用getElementById
(2). 如果传入的是元素选择器,则 $ ()自动调用getElementsByTagName
(3). 如果传入的是类选择器,则 $ ()自动调用getElementsByClassName()
(4). 如果传入的选择器复杂,则自动调用querySelectorAll()
5. $(DOM元素) 无需查找,直接将DOM元素保存进jQuery对象中
比如: $(this) $(e.target)
6. 创建新元素

$(`HTML片段`) 

$(function(){ … }) 绑定DOMContentLoaded事件,在DOM内容加载完成后,就提前自动执行代码

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值