jQuery知识点整理

178 阅读20分钟

一、初识jQuery

1. 什么是jquery?

javascript库,即library,是一个封装好的特定的集合(方法和函数)。从封装一大堆函数的角度理解库,就是在这个库中,封装了很多预先定义好的函数在里面,比如动画animate、hide、show,比如获取元素等。

简单理解:就是一个js文件,里面对原生js代码进行了封装,存在了里面,这样我们就可以快速高效的使用这些封装好的功能了。

比如jquery,就是为了快速方便的操作dom,里面基本都是函数(方法)。

2.jquey的作用

解决操作DOM遇到 浏览器的兼容问题,不用担心兼容问题

开发使用:低版本的jquery文件 -- jquery 1.12 版本,兼容ie678

设计宗旨:write less, Do more 写更少的代码,做更多的事情。
jquery封装了js常用的功能代码,优化了DOM操作、事件处理、动画设计和ajax交互

3.原生js的缺点

 1、书写麻烦,必须重复书写getElementBy等方法来获取元素
2、操作不是批量的,必须书写for()循环语句来批量控制元素
3、存在兼容性问题
4、运动/动画实现非常复杂,需要使用setInterval()使元素动起来
5、操作类名、属性不方便

实例:点击按钮给3个div 设置边框和文本

<style> div { height:100px; margin-top:10px;} </style>

<input type="button" value="设置边框" id="btnOne"/>
<input type="button" value="设置文本" id="btnTwo"/>
div*3
  
<script>
window.onload=function(){
  var btn01 = document.getElementById("btnOne") ;
  var btn02 = document.getElementById("btnTwo") ;
  var divs = document.getElementsByTagName("div");
  btn01.onclick=function(){
    for(var i=0; i<divs.length;i++){
      divs[i].style.border = "1px solid blue";
  } }
  btn02.onclick=function(){
    for(var i=0; i<divs.length;i++){
      divs[i].textContent = "我是设置的文本";
  } } }
</script>

// 总结:上面 原生js的缺点:
// 1. 不能添加多个入口函数 window.onload,后面的会把前面的给覆盖
// 2. 获取dom元素 的 原生js的api 名称太长、难记
// 3. 原生js有的时候代码冗余,例:一个divs数组遍历了2次
// 4. 原生js中有些属性或者方法有浏览器兼容问题
  // 例:ie8 以下不认识textContent,与之相对应的是 innerText or innerHTML
// 5. 原生js容错率比较低,前面的代码出了问题,后面的代码执行不了 

4.JQuery的优点

<script src="./js/jquery-1.12.2.js"></script>
<script>
$(document).ready(function(){
  $("#btnOne").click(function(){
    $("div").css("border", "1px solid green");
  });
  $("#btnTwo").click(function(){
    $("div").text("我是设置的文本");
  })
})

/*
jQuery的优点:
轻量级,核心文件几十kb,不会影响页面加载速度。
1. 是可以写多个入口函数的
2. 简化DOM操作:获取dom元素的 jQuery的api名字容易记忆
3. jQuery代码简洁(隐式迭代),不用遍历div,也可以实现操作每个div
   dom操作时,想获得很多个相同标签,对它们做相同的功能,需要写循环遍历
   jquery中不需要遍历,一行代码就搞定
4. 跨浏览器兼容:jQuery 的属性和方法 解决了浏览器兼容性问题
5. 容错率高,前面的代码出了问题,后面的代码不受影响
*/

</script>

二、jQuery的使用方式

1. 使用 jquery 3步骤

<div></div>
<script src="./js/jquery-1.12.2.js"></script>
<script>
// 如何使用jQuery?
// 1. 引入jquery文件
// 2. 写一个入口函数-页面加载函数
// 3. 根据jquery选择器,找到要操作的元素,操作它(给它添加属性、样式、文本....)
$(function(){
  $("div").width(100).height(100).css("backgroundColor","skyblue").text("我是新添加的文本")
  })
</script>
jQuery中引入文件注意问题:
1、先引入jQuery 1.12 版本文件,然后再新的script标签中写js/jQuery 代码
2、压缩版和普通版的区别
压缩版:以正则表达式的方式将注释、空格、换行都替换掉,单词变字母,最终实现成了压缩版的版本文件
建议:开发时 用普通版    上线 用压缩版

2.入口函数-页面加载的4种写法

页面中所有的内容加载完毕后才触发,标签,图片,文字内容....

原生js: window.onload = function () {} 
在DOM中是对象的事件调匿名函数    注意:这个事件只能写一个,后面写的会覆盖前面
1、$(window).load(function(){ ... });   // 和DOM中的window.onload事件 是相同的
                            
2、$(document).ready(function(){ ... });   // 可以存在多个 只要DOM元素加载完就触发
// 这种加载方式比1的加载速度要快, 页面中的基本的标签加载完毕后就可以触发了
                               
3jQuery(function () { ... })

4、$(function(){ ... });   // 最简写的方式

3.jquery入口函数和window.onload函数的区别

a.window.onload入口函数不能写多个,但是jquery的入口函数是可以写多个的
b.执行时机不同:jquery入口函数要优于window.onload
jquery入口函数要等待页面上dom树加载完后执行;
window.onload要等待页面上所有的资源(dom树/外部css/js/图片)都加载完毕后才执行

4.jquery的顶级对象$

1. $是jquery的顶级对象,相当于原生js的window,把元素利用$包装成jQuery对象,就可以调用jQuery的方法。   $ 点出来的是jQuery 中的方法或属性

2. DOM页面中的顶级对象:document  document 点出来的是DOM中的属性和方法	

3.BOM浏览器中的顶级对象window   window 点出来的是浏览器中的属性和方法
注意: window也可以点出来 document,页面中的一切内容都属于window

5. DOM对象和jQuery对象

DOM 对象与jquery对象之间是可以相互转换的。

因为原生js比jquery更大,原生的一些属性和方法jquery没有给我们封装,要想使用这些属性和方法需要把jquery对选哪个转换为dom对象才能使用。

1. DOM对象和jQuery对象的区别

// 1. DOM对象:用原生js获取的对象就是DOM对象
var div01 = document.querySelector("div"); // div01是DOM对象
console.dir(div01);

// 2. jQuery对象:用jquery方式获取的对象是jquery对象
$("div");  // $("div") 是一个jquery对象
console.dir($("div"));

// jquery对象的本质是:利用$对DOM对象包装后产生的对象(伪数组形式存储)。两者本质有区别。
// 伪数组:有0-length-1属性,并且length属性 
// var obj= {0:1; 1:2; 2:3; 3:4; 4:5; length:5;} obj这个伪数组可以调用jquery的each()方法

// 3. jquery对象只能使用jquery方法,DOM 对象只能使用原生javascript的属性和方法
div01.style.display = "none";
$("div").hide();

2.DOM对象转 jQuery对象

语法:$(dom对象)

// 原生js: dom操作按钮,修改背景颜色
var btnObj=document.getElementById("btn");//DOM对象
btnObj.onclick = function(){this.style.backgroundColor = "red";}

// DOM 对象转jQuery 对象,只需要把DOM 对象 放在 $(dom对象)
var btn = document.getElementById('btn'); // 1.先获取dom对象
$(btn).click(function(){             // 2. 用$()包装dom对象 成jquery对象
  $(this).css('backgroundColor','red');
})

3.jquery对象转DOM对象 (2种方式)

// 1、$(btn).get(index) index是索引
var btn = document.getElementById('btn');   // DOM对象
var obj = $(btn).get(0);   // DOM对象
obj.onclick = function () { this.style.backgroundColor = "green";}

// 2、$(btn)[index] 推荐使用  index是索引
var btn = document.getElementById('btn');   // DOM对象
var obj = $(btn)[0];   // DOM对象
obj.onclick = function () { this.style.backgroundColor = "green";}

4.互转案例

<input type="button" value="显示效果" id="btn"/>
    
$(function(){
  $('#btn').click(function(){    // $("#btn")  ---> jquery 对象
    $(this).css('width','300px');
  });
  $('#btn').onclick = function(){   // jQuery 对象不能调取DOM对象的事件
    this.style.width = '300px';  // 无作用
  };
  $('#btn')[0].onclick = function(){   // jQuery 对象已转换成DOM对象
    this.style.width = '300px';  // 可以起到作用
  };
})    

三、jQuery选择器

1.基础选择器

原生js获取元素方式很多,很杂,而且兼容性情况不一样,因此jquery做了封装,使获取元素统一标准

$("选择器")  // 直接写css选择器即可,但是要加引号

$("*")          // 全选选择器:匹配所有元素
$("#id")        // id选择器:选取指定id的元素
$(".class")     // 类选择器:选择同一类class的元素
$("div")        // 标签选择器:获取同一类标签的所有元素
$("div,p,li")   // 并集选择器:选取多个元素
$("li.current") // 交集选择器:交集元素

// 2. 层级选择器
$("ul>li")   // 子代选择器:使用>号,获取儿子层级的元素,注意:并不会获取孙子层级的元素
$("ul li")   // 后代选择器:使用空格,代表后代选择器,获取ul下的所有li元素,包括孙子等

2. 内容选择器

// :empty  找到既没有文本内容也没有子元素的指定元素
$("div:empty") 

// :parent   找到有文本内容或有子元素的指定元素
$("div:parent") 

// :contains(text)  找到包含指定文本内容的指定元素
$("div:contains("我是div")")  

// :has(selector) 找到包含指定子元素的指定元素
$("div:has('span')") 

3.筛选选择器

:first     $("ul li:first")  // 获取第一个li元素 
:last      $("ul li:last")  // 获取最后一个li元素 
:eq(index) $("ul li:eq(2)")  // 获取li中索引号为2的元素,索引号index从0开始
:odd       $("ul li:odd")    // 获取li中索引号为奇数的元素
:even      $("ul li:even")   // 获取li中索引号为偶数的元素

4.筛选选择器方法(重点)

注意:都是方法,带括号

重点:parent()、children()、find()、siblings()、eq()

语法用法说明
parent()$("li").parent();查找最近一级的父级元素(亲爸爸)
children(selector)$("ul").children("li")相当于$("ul>li"),最近一级(亲儿子)
find(selector)$("ul").find("li")相当于$("ul li"),后代选择器
siblings(selector)$(".first").siblings("li")查找兄弟节点,不包括自己本身
nextAll()$(".first").nextAll()查找当前元素之后的所有同辈元素
prevAll()$(".first").prevAll()查找当前元素之前的所有同辈元素
hasClass(class)$("div").hasClass("current")检查当前的元素是否含有某个特定的类,如果有返回true
eq(index)$("li").eq(2)相当于$("li:eq(2)"),index从0开始
next()$("li").next()找下一个兄弟
prev()$("li").prev()找上一个兄弟

$(this).index() 得到当前元素索引号

手风琴实例:

// 需求:点击一级菜单li,对应的子级div显示,其它兄弟标签下的div隐藏
<ul class="parentWrap">
  <li class="groupTitle">
    <span>一级菜单1</span>
    <div>我是弹出来的div1</div>
  </li>
  <li class="groupTitle">
    <span>一级菜单2</span>
    <div>我是弹出来的div2</div>
  </li>
  <li class="groupTitle">
    <span>一级菜单3</span>
    <div>我是弹出来的div3</div>
  </li>
  <li class="groupTitle">
    <span>一级菜单4</span>
    <div>我是弹出来的div4</div>
  </li>
</ul>

<script src="./js/jquery-1.12.2.js"></script>
<script>
$(function(){
  $(".parentWrap li>div").hide();
  $(".parentWrap li").click(function(){
    // 用到了隐式迭代 链式编程  
    $(this).children("div").show().parent().siblings("li").children("div").hide();
  })
})
</script>

5. 隐式迭代

遍历内部dom元素(伪数组形式存储)的过程就叫做隐式迭代。

简单理解:给匹配到的所有元素进行循环遍历,执行相应的方法,而不用再进行循环,简化我们的操作,方便我们调用。

$("div").css("background", "pink"); // jquery对象不能使用style
// 隐式迭代就是把匹配的所有元素内部进行遍历循环,给每一个元素添加css()这个方法
// 隐式迭代
// 2. 显示迭代each()
// 需求:找到所有li,分别设置透明度,透明度是递增到1
var $lis = $("ul").children();
console.log($lis);
// $lis.css("opacity", 0.5); // 由于隐式迭代每一个li标签的透明度都设置成了0.5,不符合需求

$lis.each(function(index, item){
  console.log(index); // 每个li标签的索引
  console.log(item);  // 每个li标签, 是一个dom对象
  $(item).css("opacity", index/10);
})

6. jquery的排他思想

想要多选一的效果,排他思想:当前元素设置样式,其它的兄弟元素清除样式

<script src="./js/jquery-1.12.2.js"></script>
<script>
// 原生js排他思想的做法:遍历每个元素,给当前元素添加类,其它元素移除类

// 1. 隐式迭代 给所有按钮都绑定了点击事件
$(function(){
  $("button").click(function(){
    // 2.当前元素变化背景颜色
    $(this).css("background", "pink");
    // 3.其它兄弟去掉背景颜色  隐式迭代
    $(this).siblings("button").css("background", "");
  })
})
</script>

7. jquery的链式编程

链式编程在于一个方法返回的是jquery对象,既然是jquery对象就可以继续点出jquery对象的方法

button*6
<script src="./js/jquery-1.12.2.js"></script>
<script>
// 1. 隐式迭代 给所有按钮都绑定了点击事件
$(function(){
  $("button").click(function(){
    // 2.链式编程:当前元素变化背景颜色, 其它兄弟去掉背景颜色
    $(this).addClass("current").siblings().removeClass("current");
  })
})
</script>
// 链式编程
// 1. 什么时候可以链式编程?
// 如果给元素调用一个方法,这个方法有返回值,并且返回的是一个jquery对象,那就可以继续再点出jquery方法
// $("div").width(100).height(100).css("backgrondColor","green");

// 2. 必须是jquery对象才能点出jquery方法
// console.log($("div").width(100).width()); // 100
// console.log($("div").width(100).widh().height(100)); // 报错,因为数值不能点出jquery方法

// 3. 有些时候我们一个方法返回的确实是一个jquery对象
// 但是这个对象有不是我们想要的对象,那这个时候就不要再继续点下去了...

// 4. end();  回到上一个状态
// $(this).text("sx_wjx").prevAll().text("sx_wjx").end().nextAll().text("kx_wjx";)

// 5. end()方法也是jquery方法,只有jquery对象才能点出来
// width()方法返回的是一个数值,数组能点出end()方法来吗?显然不行
// $("div").width(100).width().end().height(100);  // 不行

四、jQuery操作样式css

box.style.backgroundColor = "green";  // 原生js:改变元素的css样式
box.className = "current"; // 改变元素的类

1. css() 方法 修改样式

// 1.参数只写属性名,则是返回属性值
$(this).css("width"); 

// 2.参数是属性名,属性值 逗号分隔,是设置一组样式,属性必须加引号,
// 值如果是数字可以不用跟单位和引号
$("div").css("属性","值")

// 参数可以是对象形式,方便设置多组样式。属性名和属性值用冒号隔开,属性可以不用加引号
$("div").css({"width":"300px", "height":"300px", "backgroundColor":"orange"}); // 如果是复合属性则必须采用驼峰命名法

2.操作类 修改样式

1.添加类 addClass()

$("div").addClass("current");  // 添加单个类 注意:操作类里面的参数 类名千万不要加.
$("div").addClass("current width200"); // 添加多个类时 类名中间用空格隔开

2.删除类 removeClass()

$("div").removeClass("current")  // 和添加类一样,可以移除单个类/多个类
$("div").removeClass()  // 移除所有类

3.判断类 hasClass()

$("div").hasClass("current");  // 有返回true,反之false

4.切换类 toggleClass()

$("div").toggleClass("current"); // 添加类和删除类之间切换

案例:tab栏切换

  1. 点击上部的li,当前的li添加current类,其余兄弟移除类;
  2. 点击的同时,得到当前li的索引号 index=$(this).index()
  3. 让下部里面相应索引号的item显示,其余的item隐藏
.box{ width: 60%; margin: 40px auto; }
.tabList{ width: 100%; height: 32px; line-height: 32px;font-size: 14px;
   background-color: #f7f7f7; border: 1px solid #eee;
  /* border-bottom: 1px solid #e4393c; */ }
.tabList li{ display: inline-block; width: 100px; text-align: center; }
.current{ color: #fff; background-color: #e4393c ;}
.tabContent{box-sizing: border-box;padding:20px;}
.tabContent .item{display: none;}
  
<div class="box">
  <div class="tabList">
    <ul>
      <li class="current">商品介绍</li>
      <li>规格与包装</li>
      <li>售后保障</li>
      <li>商品评价</li>
      <li>手机社区</li>
    </ul>
  </div>
  <div class="tabContent">
    <div class="item" style="display: block;">商品介绍模块内容</div>
    <div class="item">规格与包装模块内容</div>
    <div class="item">售后保障模块内容</div>
    <div class="item">商品评价模块内容</div>
    <div class="item">手机社区模块内容</div>
  </div>
</div>
<script src="./js/jquery-1.12.2.js"></script>
<script>
$(function(){
  $(".tabList li").click(function(){
    $(this).addClass("current").siblings().removeClass("current");
    var index = $(this).index();
    $(".tabContent .item").eq(index).show().siblings().hide();
  })
})
</script>

五、jQuery操作节点和元素

1.创建节点的2种方式$()

原生js中创建节点:document.write(); innerHTML; document.createElement();

1.html() 创建元素

<input type="button" value="html()" id="btn01">
<input type="button" value="$()" id="btn02">
<div>哈哈哈哈。。。。</div>
<script src="js/jquery-1.12.2.js"></script>
<script>
// 1. html(); 设置或者获取内容
$("#btn01").click(function() {
  // 1.1 没有参数时,是获取内容
  console.log($("div").html());
  // 1.2. 给参数时,是设置内容并替换掉原来的内容
  // 如果设置的内容中包含了标签,会解析标签
  $("div").html("我是新设置的html内容<a href='http://www.baidu.com'>去百度</a>");
})
</script>
// 案例:动态给表格添加数据
// 需求:点击获取数据按钮,根据data这个数组里面的数据来给tbody追加tr
<input type="button" value="获取数据" id="btn">
<table>
  <thead><tr><td>标题</td><td>地址</td><td>说明</td></tr></thead>
  <tbody id="tbData"></tbody>
</table>
<script src="js/jquery-1.12.2.js"></script>
<script>
  $(function(){
    // data数组中的每一个元素就是一个tr
    var data = [
      {name: "传智播客", url: "http://www.itheima.com", type: "IT最强培训机构"},
      {name: "黑马程序员",url: "http://web.itheima.com",type: "大学生IT培训机构"}, 
      {name: "传智前端学院",url: "http://web.itcast.com",type: "前端的黄埔军校"}
    ];
  // 需求:点击获取数据按钮,根据data这个数组里面的数据来给tbody追加tr
  // 每个对象里有多少键值对,就有多少td
  // 给获取数据按钮设置点击事件
  $("#btn").click(function(){
    // 1. html() 
    var list = [];
    for(var i=0; i<data.length; i++){
      list.push("<tr>");
      for(var key in data[i]){
        list.push("<td>");
        list.push(data[i][key])
        list.push("</td>");
      }
      list.push("</tr>");
    }
    $("#tbData").html(list.join(""))
  })
  })
</script>

2.$() 创建元素

// 2. $();
// 创建的元素只存在于内存中,如果要在页面上显示,就要追加
$("#btn02").click(function() {
  var $text = $("<p>我是$()里设置的新内容</p>");
  // 追加节点
  $("div").append($text);
})
// 2. $() 方式实现 动态填充表格数据
$("#btn").click(function(){
  for(var i=0; i<data.length; i++){
    var $tr = $("<tr><td>"+data[i]['name']+"</td><td>"+data[i]['url']+"</td><td>"+data[i]['type']+"</td></tr>")
    console.log($tr);
    $("#tbData").append($tr);
  }
})

2.获取/设置元素内容text()

1. text() 获取/设置元素内容

$("div").text(); //获取内容
$("div").text("hello"); // 设置内容
console.log($("select option:checked").text()); // 获取下拉框选中项的内容
console.log($("select option:checked").eq(0).text()) // 获取第一个下拉框选中项的内容

2.val() 获取/设置表单内容

// 原生js是通过value属性来获取或设置表单元素的值的
// jquery中如何来获取或设置表单元素的值的?
$("#btn04").on("click", function(){
  console.log($("#txt").val()); // 不给参数即获取内容
  $("#txt").val("我是设置的值");
})

3. 添加/插入节点append()、after()

1. 内部插入append()、prepend()、appendTo() 和 prependTo()

// 1. append()   作为最后一个子元素添加
// 用法:父元素.append(子元素);
// 用法1:新创建一个li标签,添加到ul01中去
var $liNew = $("<li>我是新创建的li标签</li>");
$("#ul01").append($liNew);

// 用法1:把ul中已经存在的li标签添加到ul中去,剪切后作为最后一个元素添加
var $li3 = $("#li3");
$("#ul01").append($li3);


// 2. prepend()  作为第一个子元素添加
// 用法和append()一样,向父元素的最前面添加子元素
// 父元素.prepend(子元素);


// 3. appendTo() 和 prependTo() 
// 子元素.appendTo(父元素); 把子元素作为父元素的最后一个子元素添加
$("#btn05").click(function(){
  var $liNew05 = $("<li>我是新建的li标签</li>");
  $liNew05.appendTo($("#ul02"));
})

2.外部插入after()、before()、insertAfter()和insertBefore()

// 1. after() 
// 元素A.after(元素B); 把元素B 插入到元素A的后面,作为兄弟元素添加
var $divNew = $("<div>我是新建的div标签</div>");
$("#ul01").after($divNew);

// 2. before() 
// 元素A.before(元素B); 把元素B 插入到元素A的前面,作为兄弟元素添加
var $divNew = $("<div>我是新建的div标签</div>");
$("#ul01").before($divNew);

// 3. insertAfter()和insertBefore()
新元素.insertAfter(兄弟元素);

案例-城市选择


  <h1>城市选择:</h1>
  <select name="src-city" id="src-city" multiple>
    <option value="1">北京</option>
    <option value="1">上海</option>
    <option value="1">广州</option>
    <option value="1">深圳</option>
    <option value="1">西红柿</option>
  </select>
  <div class="btn-box">
    <button id="btn01"> &gt;&gt; </button><br/>
    <button id="btn02"> &lt;&lt; </button><br/>
    <button id="btn03"> &gt; </button><br/>
    <button id="btn04"> &lt; </button><br/>
  </div>
  <select name="tar-city" id="tar-city" multiple></select>
select{ width: 200px;height: 200px;background-color: green;}
#src-city, .btn-box, #tar-city{float:left;}
.btn-box{text-align: center;width:40px;height: 200px;}
<script src="js/jquery-1.12.2.js"></script>
<script>
$(function(){
  // 1. 全选剪切至右侧
  $("#btn01").click(function(){
    // var $childs = $("#src-city>option"); // 找到左侧所有option
    // $("#tar-city").append($childs);
    $("#src-city>option").appendTo($("#tar-city")); // 写法同上
 })

  // 2. 全选剪切至左侧
  $("#btn02").click(function(){
    $("#tar-city>option").appendTo($("#src-city"));
  })

  // 3. 选中的剪切到右侧
  $("#btn03").click(function(){
    $("#src-city>option:selected").appendTo($("#tar-city"));
  })
 
  // 4. 选中的剪切到左侧
  $("#btn04").click(function(){
    $("#tar-city>option:selected").appendTo($("#src-city"));
  })
})
</script>

4. 清空/删除节点remove()

1. 清空元素: empty()

删除指定元素的内容和子元素,指定元素自身不会被删除

2. 删除节点: remove()

<input type="button" value="清空ul列表" id="btn">
<ul id="ul01">
  <li>我是第1个li标签</li>
  <li>我是第2个li标签</li>
  <li id="li03">我是第3个li标签</li>
  <li>我是第4个li标签</li>
  <li>我是第5个li标签</li>
</ul>
<script src="js/jquery-1.12.2.js"></script>
<script>
$(function(){
  $("#btn").click(function(){
    // 1. 清空ul,是清空ul里面的内容
    // $("#ul01").html(""); // 1.1 html("") 不安全,不推荐使用,有可能造成内存泄漏
  // $("#ul01").empty();  // 1.2 empty() 推荐使用 不仅清空了元素,还清空了元素的事件

  // 2. 移除某一个子元素
  $("#li03").remove();

  // 3. 移除ul,是整个ul都不在了但是只能获取li03 这个标签
  $("#li03").parent().remove(); // 和清空ul的区别:移除ul是整个ul都不在了
  })
})
</script>

3. detach() 删除元素

remove()用法、效果一样

4.案例:表格内容删除/删除当前行

$(function(){
  // 1. 清空内容
  $("#btn").click(function(){
    $("#tbody").empty();
  });

  // 2. 删除对应的行
  $("#tbody .delBtn").click(function(){
    $(this).parent().parent().remove();
  })
})

5. 替换节点

1. replaceWith(content)

$("#btn").click(function(){
  var $h6 = $("<h6>我是标题6</h6>"); // 1.新建一个元素
  $("h1").replaceWith($h6); // 2. 替换所有匹配的元素为指定元素
})

2.replaceAll(选择器)

// 和replaceWith(选择器)的区别就是顺序不一样
$("#btn").click(function(){
  var $h6 = $("<h6>我是标题6</h6>"); // 1.新建一个元素
  $h6.replaceAll("h1"); // 2. 替换元素
})

6.复制节点 clone()

浅复制 $("li:first").clone(false); // 不会复制元素的事件
深复制 $("li:last").clone(true);

只存在于内存中,如果要在页面上显示,就应该追加到页面上。

clone()方法参数不管是true还是false,都是会克隆到后代节点的。

clone()方法参数是true表示会把事件一起克隆,参数如果是false就不会克隆事件,不给参数默认是false

$(function(){
  $("#btn").click(function(){
    var $cloneDiv = $("#div1").clone();
    $cloneDiv.attr("id", "div2");
    $("body").append($cloneDiv);
  })
})

六、jQuery操作属性attr()

1. 什么是属性?  对象身上保存的变量就是属性
2. 如何操作属性?
  // 2.1 设置属性
    对象.属性名称 = 属性值;  
    对象["属性名称"] = 属性值; 
  // 2.2 获取属性
    对象.属性名称; 
    对象["属性名称"];
3. 什么是属性节点?
<span nam="it666"></span>
在编写html代码时, 在html标签中添加的属性就是属性节点。
例:F12-source-Watch添加:document.getElementsByTagName("span")
在浏览器中找到span这个dom元素后,展开看到的都是属性,在attributes属性中保持的所有内容都是属性节点
4. 如何操作属性节点?
  DOM元素.setAttribute("属性名称", "值");--设置属性
  DOM元素.getAttribute("属性名称");--获取属性
5. 属性和属性节点的区别?
任何对象都有属性,只有DOM对象才有属性节点。
// 4. 如何操作属性节点?
// 原生js 操作属性 
// DOM元素.setAttribute("属性名称", "值");
// DOM元素.getAttribute("属性名称");
var span = document.getElementsByTagName("span")[0];
span.setAttribute("name", "xd");  // 设置属性
console.log(span.getAttribute("name")); // 获取属性值

1. attr("属性名") 获取属性值

$("img").attr("src"); // 自带的属性可以获取 
$("img").attr("aaa"); // 自定义的属性也可以获取
$("img").attr("bbb"); // 如果没有这个属性,获取值时undefined

2. attr("属性名", "属性值") 设置属性

$("img").attr("src", "images/02.jpg"); // 设置单个属性
$("img").attr({src:"images/03.jpg",aaa:"hahahaha",bbb:"bbbbbb"}) // 设置多个属性,对象形式

3. removeAttr() 移除属性

$("img").removeAttr("alt"); // 移除单属性
$("img").removeAttr("alt aaa bbb");  // 移除多属性, 属性名之间空格隔开

4. 案例:美女相册

<h2>美女画廊</h2>
<ul id="gallery">
  <li><a href="images/large01.jpg"  title="图片1"><img src="images/mini01.jpg"></a></li>
  <li><a href="images/large02.jpg"  title="图片2"><img src="images/mini02.jpg"></a></li>
  <li><a href="images/large03.jpg"  title="图片3"><img src="images/mini03.jpg"></a></li>
  <li><a href="images/large04.jpg"  title="图片4"><img src="images/mini04.jpg"></a></li>
</ul>
<div id="box"><img id="img" src="images/large01.jpg" alt=""></div>
<div id="des">选择一个图片</div>
<script src="./js/jquery-1.12.2.js"></script>
<script>
$(function(){
  $("#gallery>li>a").click(function(){
    var srcValue = $(this).attr("href"); // 获取a标签的href值
    var contentValue = $(this).attr("title"); // 获取a标签的title值

    $("#img").attr("src", srcValue);  // 设置img的src为指定的值
    $("#des").text(contentValue);  // 设置文本为指定的值

    return false;  // 阻止a标签的跳转
  })
})
</script>

5. prop() 操作布尔类型的属性

在jquery1.6之后,对于checked、selected、disabled这类布尔类型的属性,不能用attr(),

只能用props()方法。

// 有一类属性,例 checked 写在元素身上表示选中,没有写在元素身上表示未选中
// 原生js操作这一类属性
var btn = document.getElementById("btn04");
btn.onclick = function(){
  // document.getElementById("ck01").checked = false; // 设置操作
  console.log(document.getElementById("ck01").checked); // 获取操作
}

// jquery 操作这一类属性
$("#btn04").click(function(){
  // console.log($("#ck01").attr("checked")); // 无论是选中还是未选中,返回的都是undefined
  // $(":checked").props("checked",true); // 设置属性
  console.log($("#ck01").prop("checked")); // 获取属性 返回true 或false
})

6.案例-表格全选/反选

<div class="wrap">
  <table>
    <thead>
      <tr>
        <th><input type="checkbox" id="j_cbAll" /></th>
        <th>课程名称</th>
        <th>所属学院</th>
      </tr>
    </thead>
    <tbody id="j_tb">
      <tr>
       <td><input type="checkbox" /></td>
       <td>JavaScript</td>
       <td>前端与移动开发学院</td>
      </tr>
      <tr>
        <td><input type="checkbox" /></td>
        <td>css</td>
        <td>前端与移动开发学院</td>
        </tr>
    </tbody>
  </table>
</div>
* {padding: 0;margin: 0;}
.wrap { width: 300px;margin: 100px auto 0;}
table {border-collapse: collapse;border-spacing: 0;border: 1px solid #c0c0c0;}
th,td {border: 1px solid #d0d0d0;color: #404060;padding: 10px;}
th {background-color: #09c;font: bold 16px "微软雅黑";color: #fff;}
td {font: 14px "微软雅黑";}
tbody tr {background-color: #f0f0f0;}
tbody tr:hover {cursor: pointer;background-color: #fafafa;}
// 1. thead 的复选框实现全选 / 全不选
$("#j_cbAll").click(function(){
  var ckValue = $(this).prop("checked"); //获取thead复选框的选中状态
  // console.log($("#j_tb input"));
  $("#j_tb input").prop("checked", ckValue);
})
// 2. tbody中的复选框 根据 复选框的总数 和 选中的数量 进行判断,控制 thead 复选框的选中/不选中
$("#j_tb input").click(function(){
  var inputSum =  $("#j_tb input").length;
  var checkedSum = $("#j_tb input:checked").length;
  console.log(inputSum, checkedSum)
  $("#j_cbAll").prop("checked", inputSum === checkedSum)
})

七、尺寸和位置相关

1. 宽高width() height()

// css() 方法 获取#box的高度
console.log($("#box").css("height"));  // 100px 字符串类型

// 1.1 width() height() 获取/设置宽高 :宽高不包括padding/border/margin
console.log($("#box").height()); // 获取高度 数值类型
$("#box").height(200); // 设置高度

// 1.2 innerWidth() innerHeight() 返回元素的宽高(包括内边距)
console.log($("#box").innerWidth()); 
console.log($("#box").innerHeight());

// 1.3 outerWidth() outerHeight() 返回元素的宽高(包括内边距和边框)

// 1.4 outerWidth(true) outerHeight(true) 返回元素的宽高(包括内边距和边框和外边距)

// 1.5 获取页面可视区的宽高
console.log($(window).width());  // 获取浏览器窗口可视宽度
console.log($(window).height());  // 获取浏览器窗口可视高度

2. offset() 和 position()

// 2.1 offset()
//  获取或设置元素距离文档的偏移位
// 获取会得到一个对象,对象里面包含了top和left的值
// offset()方法获取的是:元素距离document的距离
$("#btn01").click(function(){
  console.log($("#son").offset()); // {top: 150, left: 150}
  console.log($("#son").offset().left); // 150
  $("$son").offset({left:10});  // 设置元素距离文档的偏移位
})

// 2.2 position()  注意点:此方法只能获取,不能设置
//  获取元素距离定位元素的偏移位
// 获取会得到一个对象,对象里面包含了top和left的值
// position()方法获取的是元素距离有定位的父元素offsetParent的位置
$("#btn02").click(function(){
  console.log($("#son").position()); // {top: 50, left: 50}
})

3. scrollLeft()和scrollTop()

获取或设置垂直滚动条的位置

$(".box").scrollTop(); // 获取滚动的偏移位
$(".box").scrollTop(300);  // 设置滚动的偏移位

// 注意点:为了保证浏览器的兼容,需要按照如下写法:
// ie下使用 html 获取不到,需要使用body
console.log($("body").scrollTop()+$("html").scrollTop()); // 获取网页滚动的偏移位 
$("html,body").scrollTop(300); // 设置网页滚动的偏移位 
// 经典案例:固定导航栏
//滚动条事件
$(window).scroll(function () {
  //判断向上卷曲出去的距离是否大于等于 应用类样式top的div的高度
  if($(document).scrollTop()>=$(".top").height()){
     //获取导航栏的元素 .nav 脱离文档流
     $(".nav").css("position","fixed").css("top",0);
     $(".main").css("marginTop",$(".nav").height());
  }else{
    $(".nav").css("position","static");
    $(".main").css("marginTop",0);
  }
});

八、jQuery中的静态方法

静态方法和实例方法

回顾原生js:
直接添加到类上的是静态方法: 静态方法通过类名调用
直接添加到类的原型上的是实例方法: 实例方法通过实例调用

function AClass(){}  // 定义一个类
AClass.staticMethod = function(){alert("staticMethod")} // 给这个类添加静态方法
AClass.staticMethod() // 静态方法通过类名调用

AClass.prototype.instanceMethod = function(){alert("instanceMethod")} // 给这个类添加实例方法
var a = new AClass(); // 创建一个实例(创建一个对象)
a.instanceMethod(); // 实例方法通过类的实例调用

1. $.each() 遍历数组和伪数组

和原生js forEach()遍历数组的区别

var arr = [0, 3, 5, 5, 9];
arr.forEach((value, index)=> console.log(index, value)); 
// 参数1: 遍历到的元素  参数2:当前遍历到元素的索引
// 注意点:原生的forEach()只能遍历数组,不能遍历伪数组

var obj = {0:1; 1:3; 2:5; 3:7; length:4 };  // 创建一个伪数组
obj.forEach((val,index)=>console.log(index, val))//报错:obj.forEach is not a function
// jquery 的each() 静态方法遍历数组
var arr = [0, 3, 5, 5, 9];
$.each(arr, function(index, value){console.log(index, value)});
// 参数1:当前遍历到的索引  参数2:当前遍历到的元素
// 可以遍历伪数组;传参顺序和原生forEach()有区别
var obj = {0:1; 1:3; 2:5; 3:7; length:4 }; 
$.each(obj, function(index, value){console.log(index, value)});

2. $.map() 遍历数组

// 原生js 的 map() 遍历数组
// 参数1:当前元素   参数2:当前元素索引    参数3:当前被遍历的数组对象
// 和原生forEach()一样,不能遍历伪数组
var arr = [1, 2, 5, 7, 9];
arr.map((value, index, array)=>console.log(index, value, array));
// jquery 的map() 静态方法遍历数组
// 参数1:要遍历的数组
// 参数2:每遍历一个元素之后要执行的回调函数
// 回调函数的参数:1.遍历到的元素 2. 遍历到的索引
// 注意点:和jquery的each()方法一样,map静态方法也可以遍历伪数组
var arr = [1, 2, 5, 7, 9];
$.map(arr, (value, index)=> console.log(index,value));
var obj = {0:1; 1:3; 2:5; 3:7; length:4 }; 
$.map(obj, function(value,index){
  console.log(index, value);
  return value + index; // 返回一个新数组
});

each() 和map()的区别

each()静态方法默认的的返回值:遍历谁就返回谁
map()静态方法默认的返回值: 是一个空数组

each()静态方法不支持在回调函数中对数组进行处理
map()静态方法可以在回调函数中通过return 对遍历的数组进行处理,然后生成一个新的数组返回

3. $.trim() 清除字符串两端的空格

// 作用:去除字符串两端的空格
// 参数:需要去除空格的字符串
// 返回值:去除空格之后的字符串
var str = "    aaaa    ";
var res = $.trim(str);
console.log("----"+res+"----");  

4. $.isWindow() 判断是不是window

// 判断传入的对象是否是window对象
// 返回值: true/false  

5. $.isArray() 判断是不是数组

// 判断传入的对象是否是真数组
// 只有是真数组才会返回true

6. isFunction() 判断是不是函数

// 判断传入的对象是否是函数
console.log($.isFunction(jQuery)); // true

7. $.holdReady() 暂停/恢复 ready()入口函数

$.holdReady(true);  // 暂停ready函数的执行
$(document).ready(function(){
  alert("ready");
})

<button	id="btn">恢复ready事件</button>
<script>
  $("#btn").click(function(){ $.holdReady(false); })  // 恢复 ready()入口函数的执行
</script>

九、jQuery动画(效果)

// 原生js做动画: setInterval()

1. 三组基本动画

1. 显示与隐藏

hide() 和show()和toggle()

<script src="./js/jquery-1.12.2.js"></script>
<script>
$(function(){
  // 1. 显示  没有参数就没有动画效果
  // 参数1:代表执行动画的时长:毫秒数 or 代表时长的字符串 fast/normal/slow
  // 参数2:代表动画执行完毕后的回调函数
  $("#show").click(function(){
    // $("div").show();
    // $("div").show(500);
    $("div").show(500,function(){ alert("动画执行完了~~~") });
  })
  // 2. 隐藏 没有参数就没有动画效果
  $("#hide").click(function(){
    $("div").hide();
  })
  // 3. 切换 如果元素是隐藏状态就动画显示,如果元素是显示状态就隐藏
  $("#toggle").click(function(){
    $("div").toggle();
  })
})
</script>

2. 滑入滑出

slideDown()和slideUp()和slideToggle() 滑入与滑出与切换,效果与卷门帘类似

<script src="./js/jquery-1.12.2.js"></script>
<script>
$(function(){
  // 1. 滑入 
  // 参数1:执行动画的时长:毫秒数 or 代表时长的字符串 fast/normal/slow
  // 参数2:动画执行完毕后的回调函数
  $("#slideDown").click(function(){
    // $("div").slideDown(); // 没有给参数相当于给默认时长normal=400毫秒
    // $("div").slideDown(2000);
    $("div").slideDown(500,function(){
      alert("滑入动画执行完了~~~")
    });
  })
  // 2. 滑出 
  $("#slideUp").click(function(){
    $("div").slideUp();
  })
  // 3. 切换 如果元素是隐藏状态就动画显示,如果元素是显示状态就隐藏
  $("#toggle").click(function(){
    $("div").slideToggle();
  })
})
</script>

3. 淡入淡出

fadeIn()和fadeOut() 淡入与淡出与fadeToggle()

<input type="button" value="淡入" id="fadeIn">
  <input type="button" value="淡出" id="fadeOut">
  <input type="button" value="切换" id="toggle">
  <input type="button" value="切换" id="fadeTo">
  <div></div>
  <script src="./js/jquery-1.12.2.js"></script>
  <script>
    $(function(){
      // 1. 淡入
      // 参数1:执行动画的时长:毫秒数 or 代表时长的字符串 fast/normal/slow
      // 参数2:动画执行完毕后的回调函数
      $("#fadeIn").click(function(){
        // $("div").fadeIn(); // 没有给参数相当于给默认时长normal=400毫秒
        // $("div").fadeIn(2000);
        $("div").fadeIn(500,function(){
          alert("滑入动画执行完了~~~")
        });
      })
      // 2. 淡出 
      $("#fadeOut").click(function(){
        $("div").fadeOut();
      })
      // 3. 切换 如果元素是隐藏状态就动画显示,如果元素是显示状态就隐藏
      $("#toggle").click(function(){
        $("div").fadeToggle();
      })
      // 4. 淡入到哪里
      $("#fadeTo").click(function(){
        $("div").fadeTo(1000, 0.5);
      })
    })
  </script>

2. 自定义动画animate()

<input type="button" value="从左到右400">
<div id="div1"></div>
<div id="div2"></div>
<script src="./js/jquery-1.12.2.js"></script>
<script>
$(function(){
  $("input").click(function(){
    // 自定义动画 animate()
    // 参数1:必选的 {} 代表的是需要做动画的属性
    // 参数2:可选的  执行动画时长
    // 参数3:可选的 linear(匀速) swing(缓动)-默认
    // 参数4:动画执行完毕后的回调函数
    $("#div1").animate({left:600 }, 600, "linear")
    $("#div2").animate({left:600 }, 600, "swing")
  })
})
</script>

3.案例-弹框广告关闭动画

  <div id="box">
    <span id="closeBtn"></span>
    <div id="headPart"></div>
    <div id="bottomPart"></div>
  </div>

  <script src="./js/jquery-1.12.2.js"></script>
  <script>
    $(function(){
      $("#closeBtn").click(function(){
        $("#bottomPart").animate({
          height:0
        }, 500, function(){
          $("#box").animate({width:0},2000);
        })
      })
    })
  </script>

4. 动画队列与停止动画

前面的动画执行完了,在执行下一个

<input type="button" value="开始动画" id="start">
  <input type="button" value="停止动画" id="stop">
  <div></div>
  <script src="./js/jquery-1.12.2.js"></script>
  <script>
  // stop() 停止动画效果
  // 参数1:是否清除队列
  // 参数2:是否跳转到最终效果
  $(function(){
    // 1.开始动画:模拟一个动画队列
    $("#start").click(function(){
      $("div").slideDown(2000).slideUp(2000);
    })
    // 2. 停止动画:执行stop方法
    $("#stop").click(function(){
      $("div").stop(true, true);
    })
  })
  </script>

十、事件相关

// 用原生js给div注册单击事件
// 原生js注册相同事件,后面的会把前面的给覆盖
document.getElementById("btn").onclick = function(){
  alert("单击事件");}
document.getElementById("btn").onclick = function(){
  alert("单击事件,啦啦啦~~~");}

// jquery
// 给同一个元素注册同样的事件,后面的不会把前面的给覆盖
$("#btn02").click(function(){alert("单击事件");})
$("#btn02").click(function(){alert("单击事件,啦啦啦~~~");})

1. 2种绑定事件方式on()

document.getElementById("btn").onclick=function(){}   // 原生js给元素绑定事件
// 1. 事件名(fn)
// 编码效率高/部分事件jquery没有实现,所以不能添加
// 可以添加多个或者不同类型的事件,不会覆盖
$("#btn").click(function(){ ... })

// 2. on("事件名", fn)
// 编码效率稍低/所以js事件jquery都可以添加
// 可以添加多个或者不同类型的事件,不会覆盖
$("#btn").on("click", funciton(){ ... })

// 注意点:
// 推荐使用on(), 新添加的dom节点会注册事件

2. 事件解绑off()

function test1(){ alert("aaa")}
$("#btn").click(test1);

$("#btn").off(); // 不传参时,是删除所有事件
$("#btn").off("click");// 传一个参数,会移除所有指定类型的事件
$("#btn").off("click", test1);// 移除指定类型的指定事件处理函数

3. 事件自动触发triggerHandler("事件名")

// 1. trigger("事件名") 自动触发事件
// 注意点:子级事件触发时会触发事件冒泡,也会触发默认行为
$("#father").click(function(){alert("father")}); // 默认只有点击father才会触发
$("#father").trigger("click"); // 刷新页面时会自动触发
$("input[type='submit']").click(function(){ alert("submit"); })
$("input[type='submit']").trigger("click");

// 2. triggerHandler("事件名") 自动触发事件
// 子级触发事件时不会触发父级的事件冒泡,不会触发默认行为
$("#father").click(function(){alert("father")}); 
$("#father").triggerHandler("click"); 
$("input[type='submit']").click(function(){ alert("submit"); })
$("input[type='submit']").triggerHandler("click");

4. 事件对象

1. 什么是事件冒泡?
  事件从里向外,从子级向父级触发的过程
2. 如何阻止事件冒泡?
  子级的事件处理函数中添加:return false; 或者 event.stopPropagation();
3. 什么是默认行为?
  a标签的链接跳转,表单的提交按钮向服务器发送请求,提交数据
4. 如何阻止默认行为?
  return false; 或者 event.stopPropagation();event.preventDefault()
// screenX() screenY() 事件对象距离屏幕最左上角的值
// clientX() clientY() 事件对象距离页面文档左上角的位置(忽视滚动条) 
// pageX() pageY() 距离页面最顶部的左上角的位置(会计算滚动条的距离)

// event.stopPropagation() 阻止事件冒泡行为
// event.preventDefault() 阻止浏览器默认行为
//return false; 既能阻止事件冒泡,又能阻止浏览器默认行为

// event.keyCode  按下的键盘码

5.自定义事件

// 想要自定义事件,必须满足以下2个条件:
// 1. 事件必须是通过 on()来绑定, 不能通过 事件名(fn)
// 2. 事件必须通过trigger()来触发
$(".son").on("myClick", function(){  });
$(".son").triggerHandler("myClick");

6. 事件命名空间

// 团队开发中, 想要事件的命名空间有效,必须满足以下2个条件
// 1. 事假是通过on来绑定的
// 2. 通过trigger触发事件
$(".son").on("click.zs",function(){ alert("click1 -- zs"); })
$(".son").on("click.ls",function(){ alert("click2 -- ls"); })
$(".son").trigger("click.ls");

// 利用trigger触发子元素带命名空间事件, 那么父元素带相同命名空间的事件也会被触发

7. 事件委托delegate()

就是找一个在入口函数执行完毕之前,就存在的元素来监听后来动态添加元素的某些事件

ul>li*3
<button>新增一个li</button>

$("#btn").click(function(){ 
  $("ul").append("<li>我是新增的li标签</li>")  // 动态添加的、新增的li不能响应点击事件
})
$("ul>li").click(function(){ console.log*($(this).html());})

// $("ul>li").click(function(){console.log*($(this).html())}) 此时可以隐藏这个li的点击事件
// 动态添加的元素也可以响应事件  把li的点击事件委托给ul监听
$("ul").delegate("li", "click", function(){
  console.log($(this).html());
})

8. 常用事件

mouseenter事件和mouseleave事件

和mouseover+mouseout事件的区别:

mouseover事件在鼠标移动到选取的元素及其子元素上时都会触发;
mouseenter事件只有在鼠标移动到选取的元素上时才触发。--推荐使用

十一、ajax相关

1.get和post异同

1. 可以通过form标签的method属性 指定发送请求的类型
2. 如果是get请求会将提交的数据拼接到url后面?username=Inj$password=123456
3. 如果是post请求会将提交的数据放到请求头中
4. get请求和post请求的异同:
  4.1 相同点: 都是将数据提交到远程服务器
  4.2 不同点:
    4.2.1 提交数据存储的位置不同:
      get请求会将数据放到url后面,post请求会将数据放到请求头中
    4.2.2 提交数据大小限制不同
      get请求对数据有大小限制2000个字符以内,post请求对数据没有大小限制
5. get、post请求应用场景
  get请求用于提交非敏感数据和小数据
  post请求用于提交敏感数据和大数据

2.post文件上传

注意:
1. 上传文件一般使用post提交
2. 上传文件form标签必须设置enctype="multipart/form-data"
3. 上传的文件在php中可以通过$_FILES获取
4. php中文件默认会上传到一个临时目录,接收完毕后会自动删除

默认情况下web服务器对上传文件的大小是有限制的,如果想修改上传文件的限制需要修改php.ini文件:
D:\wamp\bin\apache\Apache2.2.21\bin

file_uploads = On; 是否允许上传文件On/Off 默认是On
upload_max_filesize = 2048M;  文件上传的最大限制
post_max_size = 2048M;  通过post提交的最多数据
max_execution_time = 30000;  脚本最长的执行时间 单位为秒
max_input_time = 30000; 接收提交的数据的实践限制 单位为秒
memory_limit = 2048M;  最大的内存消耗

post-upload-file.html

<form action="02-post-upload-file.php" method="post" enctype="multipart/form-data">
  <!-- 想要提交谁,就给谁添加name属性 -->
  <input type="file" name="upfile"><br> 
  <input type="submit" value="上传">
</form>

3.ajax 5步骤

ajax是与服务器交换数据并更新部分网页的技术,在不重新加载整个页面的情况下

var xhr; // 1. 创建一个异步对象,解决ie中的兼容性问题
if (window.XMLHttpRequest){
  xhr = new XMLHttpRequest();
}else {  // code for IE6, IE5
  xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("POST","test1.php",true);  // 2. 设置请求方式和请求地址
xhr.send();  // 3. 发送请求
// 4. 监听状态的变化
xhr.onreadystatechange=function(){
  if (xhr.readyState==4 && xhr.status==200){
    // 5. 处理返回的结果
    console.log("接收到服务器返回的数据:"+ xhr.responseText);
  }else{
    console.log("未接收到服务器返回的数据~~");    
  }
}
其它ajax异步请求相关:
1. 设置超时处理
  1.1 在调用ajax函数时,传入超时时间.
  1.2 ajax封装函数判断是否有传入超时时间,若有启动相关时间的定时器,定时器中设置中断请求xhr.abort()

2. 请求地址url是不可以出现中文的,如果有中文需要进行转码处理,转码成服务器需要的格式
encodeURIComponent("张三")

4.get请求

在ie浏览器中,如果通过ajax发送get请求,那么ie浏览器会认为同一个url只有一个结果,
为保证每次都能获取最新的数据,建议在请求地址后面添加时间戳,例:
xhr.open("GET", "ajax-get.txt?t="+(new Date().getTime()), true);

ajax.js get请求封装

// get请求参数对象的函数封装
function objToStr(obj){
  obj.t = new Date().getTime();  // obj对象添加时间戳
  var res = [];
  for(var key in obj){
    res.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
  }
  return res.join("&"); // 数组的join()拼接成字符串
}
function ajax(url, obj, timeout, success, error){
  var str = objToStr(obj); // 0. 将参数对象转换成字符串
  var xhr,timer; // 1. 创建一个异步对象,解决ie中的兼容性问题
  if (window.XMLHttpRequest){
    xhr = new XMLHttpRequest();
  }else {
    xhr=new ActiveXObject("Microsoft.XMLHTTP");
  }
  xhr.open("GET",url+"?"+str,true);  // 2. 设置请求方式和请求地址
  xhr.send();  // 3. 发送请求
  // 4. 监听状态的变化
  xhr.onreadystatechange=function(){
    if (xhr.readyState==4 && xhr.status==200){
      clearInterval(timer);
      success(xhr);  // 5. 处理返回的结果
    }else{
      error(xhr);   
  }} 
  // 判断外界是否传入了超时时间
  if(timeout){
    timer = setInterval(function(){
      console.log("中断请求");
      xhr.abort(); // 终止请求
      clearInterval(timer);  
    },timeout)
  }
}

ajax-get.html 调用ajax()

<script src="./ajax.js"></script>
<script>
btn.onclick=function(){
  ajax("ajax-get.php", {"username": "Inj","password": "123456"}, 3000,
function(){ alert(xhr.responseText);}, function(){ alert("请求失败~~")})}
</script>

5.post请求

// 与get请求不同的是: 在xhr.send()之前调用xhr.setRequestHeader()
xhr.open("POST","test2.php",true);  // 2. 设置请求方式和请求地址
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send("fname=Bill&lname=Gates");  // 3. 发送请求时的请求参数在这里添加

ajax.js 根据判断type的不同,发送对应的请求

// 请求参数对象的函数封装
function objToStr(obj){
  obj.t = new Date().getTime();  // obj对象添加时间戳
  var res = [];
  for(var key in obj){
    res.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
  }
  return res.join("&"); // 数组的join()拼接成字符串
}
function ajax(type, url, obj, timeout, success, error){
  var str = objToStr(obj); // 0. 将参数对象转换成字符串
  var xhr,timer; 
  if (window.XMLHttpRequest){
    xhr = new XMLHttpRequest();
  }else {
    xhr=new ActiveXObject("Microsoft.XMLHTTP");
  }
  if(type==="GET"){
    xhr.open("GET", url+"?"+str, true);  // 2. 设置请求方式和请求地址
    xhr.send();  // 3. 发送请求
  }else{
    xhr.open("POST","test2.php",true);  // 2. 设置请求方式和请求地址
    xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xhr.send(str);  // 3. 发送请求时的请求参数在这里添加
  }
  
  // 4. 监听状态的变化
  xhr.onreadystatechange=function(){
    if (xhr.readyState==4 && xhr.status==200){
      clearInterval(timer);
      success(xhr);  // 5. 处理返回的结果
    }else{
      error(xhr);   
  }} 
  // 判断外界是否传入了超时时间
  if(timeout){
    timer = setInterval(function(){
      console.log("中断请求");
      xhr.abort(); // 终止请求
      clearInterval(timer);  
    },timeout)
  }
}

6. jquery的$.ajax()

特点:请求时的相关信息都封装在对象中,不用考虑传参顺序的问题