组件化网页开发——jQuery
jQuery入门
jQuery是一个快速、小巧其功能丰富的JavaScript库。它使JTML文档的遍历和操作、事件处理、动画和AJAX等操作变得简单,并提供了一个易于使用的API,可以跨多种浏览器工作。jQuery集多功能性和可扩展性于一身,改变了数百万人编写JavaScript的方式。
//通过ID获取一个HTML元素 //JavaScript var obj=document.getElementById('IdValue'); //jQuery var obj=$('IdValue'); //将一个HTML元素隐藏 //JavaScript document.getElementById('IdValue').style.display; //jQuery $('IdValue').hide(); //将一个HTML元素隐藏 //JavaScript document.getElementById('IdValue').style.Width='200px'; //jQuery $('IdValue').css('width','200px') 复制代码
jQuery的作用
HTML元素选取
HTML元素操作
CSS操作
HTML事件函数
JavaScript特效和动画
HTML DOM 遍历和修改
AJAX
Utilities
jQuery的版本
版本分类:jQuery1.x.x/jQuery2.x.x/jQuery3.x.x
注意:Internet Explorer 6/7/8兼容最高版本是jQuery1.9.1
jQuery的优势
轻量级
强大的选择器
出色的DOM操作及其封装
可靠的事件处理机制
完善的AJAX
不污染顶级变量
出色的浏览器兼容性
链式操作方式
隐式迭代
行为层和结构层的分离
丰富的插件支持
jQuery的使用
jQuery的引入
常规引入
使用jQuery只需要在页面的中引入jQuery文件即可
<html> <head> <script src="jQueryPath/jquery.js"></script> <!--先引入jQuery--> ... </head> <body> ... </body> </html> 复制代码
$符号
jQuery把所有功能全部封装在一个全局变量jQuery中,而$也是一个合法的变量名,它是变量jQuery的别名。
jQuery = function jQuery(agr) { alert(agr); } $ = window.jQuery = jQuery; //以下两句等价 $(agr); jQuery(agr); $===jQuery //true typeof($) //function 复制代码
绝大多数时候,我们直接用,若,若,若变量已被占用,且不能改, 就只能使用jQuery这个变量
jQuery的书写格式
jQuery的宗旨是用什么选什么
$; //jQuery(selector,context) jQuery; //jQuery(selector,context) //example $('div').addClass('div'); //给div添加class名,名为div jQuery('div').addClass('div'); //与上一句等价 复制代码
原始格式
$(document).ready(function() { $('div').addClass('div'); }); //ready意为准备就绪,加载完成就运行函数体里面的代码 //原本浏览器读取完jQuery时并没有读取到div这个元素,从而会报错 //但用ready()方法就会在读取完所有元素后才去执行函数体中的代码,这时就不会出错 复制代码
缩写格式
$().ready(function() { $('div').addClass('div'); }); //document可以不写 $(function() { $('div').addClass('div'); }); //ready也可以不写 //相当于原生格式 window.onload=function(){ ... } 复制代码
注意:不建议用缩写格式
jQuery选择器
选择器是jQuery的核心,一个选择器写出来类似$('#dom-id')
返回的对象是jQuery对象,类似数组,每个元素都是一个引用了DOM节点的对象。
不会返回undefined或者null,而会返回一个空数组,因此不必在下一行判断if(div===undefined)
基本选择器
#id
根据给定的id匹配一个元素(唯一、精确、效率快)
$(document).ready(function() { var first = $('#first'); console.log(first); var second = $('#second'); console.log(second); var third = $('#third'); console.log(third); }); 复制代码
element
根据给定的元素标签名匹配所有元素
$(document).ready(function() { var div = $('div'); console.log(div); }); 复制代码
.class
根据给定的css类名匹配元素
$(document).ready(function() { var div = $('.div'); console.log(div); var first = $('.first'); console.log(first); var second = $('.second'); console.log(second); var third = $('.third'); console.log(third); }); 复制代码
*
匹配所有元素(慎用)
$(document).ready(function() { var all = $('*'); console.log(all); }); 复制代码
多项选择器
将每一个选择器匹配到的元素合并后一起返回,可以指定任意多个选择器,并将匹配到的元素合并到一个结果内
$('selactor1,selector2,selectorN'); 多项选择器用逗号分隔
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>多项选择器</title> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/script.js"></script> </head> <body> <section id="first" class="div first">First div element.</section> <div>First after and Second before.</div> <section id="second" class="div second">Second div element.</section> <div>Second after and Third before.</div> <section id="third" class="div third">Third div element.</section> </body> </html> 复制代码
$(document).ready(function() { var firstAndThird = $('#first, .third'); console.log(firstAndThird); var objs = $('#first, div, .third'); console.log(objs); var objs = $('#first, div, .second'); console.log(objs); }); 复制代码
说明
多项选择器匹配到的多个元素排列顺序同元素在html中的顺序是一致的
会把匹配到的所有元素去掉重复项拼接在一起
层级选择器
祖先后代选择器 $('ancestor descendant')
在给定的祖先元素下匹配所有的后代元素
$(document).ready(function() { var summaries = $('aside summary'); //祖先元素aside 子孙元素summary console.log(summaries); }); 复制代码
注意:后代选择器会选中所有后代,效率比较低
直接后代选择器 $('parent > child')
在给定的父元素下匹配所有的子元素
$(document).ready(function() { var details = $('aside > details'); console.log(details); }); 复制代码
相邻选择器 $('prev + next')
匹配所有紧接在prev元素后的next元素
$(document).ready(function() { var uls = $('summary + ul'); console.log(uls); var details = $('summary + details'); //紧跟summary的details才会被选中,并且要是同一级别的 console.log(details); }); 复制代码
$('prev ~ siblings')
匹配prev元素之后的所有sibling元素
$(document).ready(function() { var uls = $('summary ~ ul'); console.log(uls); var details = $('summary ~ details'); //summary后面所有details都会被选中,并且要是同一级别的 console.log(details); }); 复制代码
属性选择器
属性名选择器 [attribute]
属性值选择器 [attribute=value]
非属性值选择器 [attribute!=value]
属性值开头选择器 [attribute^=value]
属性值结尾选择器 [attribute$=value]
属性值包含选择器 [attribute*=value]
多属性选择器 [attribute1][attribute2]
$(document).ready(function() { var all = $('[class]'); //属性名是class console.log(all); var tool = $('[class=tool]'); //属性名是class并且值是tool console.log(tool); var notool = $('[class!=tool]'); //属性名是class并且值不是tool console.log(notool); var tools = $('[class^=tool_]'); //属性值以tool_开头 console.log(tools); var vs = $('[class$=vs]'); //属性值以vs结尾 console.log(vs); var vses = $('[class*=vs]'); //属性值包含vs console.log(vses); var scripts = $('[type][src]'); //多个条件同时满足 console.log(scripts); var jq = $('[class][class*=lang][class$=y]'); console.log(jq); }); 复制代码
过滤器
child系列
第一个孩子 :first-child
最后一个孩子 :last-child
第X个孩子 :nth-child(n | even | odd | formula)
倒数第X个孩子 :nth-last-child(n | even | odd | formula)
独生子 :only-child
$(document).ready(function() { var first = $('details > p:first-child'); //details的第一个子标签要是p console.log(first); var last = $('details > p:last-child'); //details的最后一个子标签要是p console.log(last); var nthF = $('details > p:nth-child(2)'); //details的第二个子标签要是p console.log(nthF); var nthL = $('details > p:nth-last-child(2)'); //details的倒数第二个子标签要是p console.log(nthL); var only = $('details > p:only-child'); //details唯一的子标签要是p console.log(only); }); 复制代码
type系列
第一个某类型 :first-type
最后一个某类型 :last-type
第X个某类型 :nth-type(n | even | odd | formula)
倒数第X个某类型 :nth-last-type(n | even | odd | formula)
唯一的某类型 :only-type
$(document).ready(function() { var first = $('details > p:first-of-type'); //强调类型,找到details下的第一个p标签 console.log(first); var last = $('details > p:last-of-type'); //强调类型,找到details下的最后一个p标签 console.log(last); var nthF = $('details > p:nth-of-type(2)'); //强调类型,找到details下的第二个p标签 console.log(nthF); var nthL = $('details > p:nth-last-of-type(2)'); //强调类型,找到details下的倒数第二个p标签 console.log(nthL); var only = $('details > p:only-of-type'); //强调类型,找到details下的唯一一个p标签 console.log(only); }); 复制代码
过滤器参数
n 匹配子元素序号。必须为整数,从1开始
even 匹配所有偶数元素
odd 匹配所有奇数元素
formula 使用特殊公式如(an+b)进行选择
$(document).ready(function() { var ps = $('p:nth-of-type(3n)'); //找到所有是父元素的第3n个子元素的p标签(先满足3n再满足p) console.log(ps); }); //3n:3,6,9…… //2n+1:3,5,7,9…… 复制代码
表单相关
表单元素
:input
可以选择<select>,<button>
:text
所有的单行文本框,和input[type='text']一样
其它input的type
:password/:radio:/checkbox/:image/:reset/:button/:file
表单状态
:enabled、:disaled
:enabled匹配所有可用元素,:disabled匹配所有不可用元素
:checked
匹配所有选中的被选中元素(复选框、单选框等,select中的option)
:selected
匹配所有选中的option 元素(更语义化)
$(document).ready(function() { var inputs = $(':input'); console.log(inputs); var texts = $(':text'); console.log(texts); var enabled = $(':enabled'); console.log(enabled); var disabled = $(':disabled'); console.log(disabled); var checked = $(':checked'); console.log(checked); var selected = $(':selected'); console.log(selected); }); 复制代码
查找和过滤
find(expr | object | element)
搜索所有与指定表达式匹配的元素
children([expr])
取得一个包含匹配的元素集合中每一个元素的所有子元素的元素集合(只匹配孩子不匹配孙子)
parent([expr])
取得一个包含所有匹配元素的唯一父元素的元素集合(找父元素)
$(document).ready(function() { var js = $('aside').find('.javascript'); console.log(js); var details = $('aside').children('details'); console.log(details); var js_parent = js.parent(); console.log(js_parent); }); 复制代码
next([expr])、prev([expr])
取得一个包含匹配元素集合中每一个元素紧邻的后面(前面)同辈元素的元素集合
$(document).ready(function() { var less = $('.less'); console.log(less); var sass = less.next(); console.log(sass); var css = less.prev(); console.log(css); }); 复制代码
eq(index | -index)
获取当前链式操作中第N个jQuery对象(正数正数第N个,负数倒数第N个)
$(document).ready(function() { var li = $('li').eq(8); console.log(li); }); 复制代码
siblings([expr])
取得一个包含匹配的元素集合中每一个元素的所有唯一同辈元素的元素集合
$(document).ready(function() { var php = $('.php'); //找到除了自己以外,所有兄弟节点 console.log(php); var lis = php.siblings(); console.log(lis); }); 复制代码
filter(expr | object | element | fn)
筛选出与指定表达式匹配的元素集合
$(document).ready(function() { var allLis = $('li'); console.log(allLis); var python = allLis.filter('.python'); console.log(python); }); 复制代码
参数
expr:字符串值,包含供匹配当前元素集合的选择器表达式
object:现有的jQuery对象,以匹配当前的元素
element:一个用于匹配元素的DOM元素
fn:一个函数用来作为测试元素的集合
$(document).ready(function() { var obj = allLis.filter(function(index) { console.log(index); }); }); 复制代码
jQuery事件
事件类型
鼠标事件
click([data],fn)、dbclick([data],fn)
click:鼠标单击时触发
dbclick:鼠标双击时触发
$(document).ready(function() { $('a').click(function() { $('img').eq($(this).index()).css({ 'opacity': '1' }).siblings().css({ 'opacity': '0' }); }); $('a').dblclick(function() { $('img').eq($(this).index()).css({ 'opacity': '1' }).siblings().css({ 'opacity': '0' }); }); 复制代码
注意:一般触发双击事件都会同时触发单击事件,因此最好把单击事件和双击事件写在不同的地方
mousedown、mouseup(鼠标左键)
mousedown:鼠标按下时触发
mouseup:按下的鼠标放松时触发
$(document).ready(function() { $('a').mousedown(function() { $('img').eq($(this).index()).css({ 'opacity': '1' }).siblings().css({ 'opacity': '0' }); }); $('a').mouseup(function() { $('img').eq($(this).index()).css({ 'opacity': '1' }).siblings().css({ 'opacity': '0' }); }); }); 复制代码
mouseenter、mouseleave
鼠标进入(移出)时触发
$(document).ready(function() { $('a').mouseenter(function() { index = $(this).index(); swiper(); }); $('a').mouseleave(function() { $('img').eq($(this).index()).css({ 'opacity': '1' }).siblings().css({ 'opacity': '0' }); }); }); 复制代码
hover([over],out)
鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave(多用于鼠标进入时变化,移出时还原)
$(document).ready(function() { $('a').hover(function() { $('img').eq($(this).index()).css({ 'opacity': '1' }).siblings().css({ 'opacity': '0' }); }, function() { $('img').eq($(this).index()).css({ 'opacity': '0' }).siblings().css({ 'opacity': '1' }); }); }); 复制代码
mouseover、mouseout
鼠标进入(移出)指定元素及其子元素时触发
$(document).ready(function() { $('nav').mouseover(function() { console.log($(this)); }); $('nav').mouseout(function() { console.log($(this)); }); }); 复制代码
mousemove([[data],fn])
在DOM内部移动时,会发生mousemove事件(非常消耗资源)
$(document).ready(function() { $('nav').mousemove(function() { console.log($(this)); }); }); 复制代码
scroll([[data],fn])
当滚动指定的元素时,会发生scroll事件(滚动条和鼠标滚轮都可以触发,同样用键盘控制滚动条也会触发)
$(document).ready(function() { $('div').scroll(function() { console.log($(this)); }); }); 复制代码
键盘事件
keydown([[data],fn])
当键盘或按钮被按下时,发生keydown事件
$(document).ready(function() { $(document).keydown(function(event) { //event对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。 if (event.keyCode == 37) { //keyCode是ASCII码 index = index > 0 ? -- index : $('a').length - 1; } else if (event.keyCode == 39) { index = index < $('a').length - 1 ? ++ index : 0; } else { return false; } swiper(); }); }); 复制代码
注意:键盘事件与光标的位置有关
keyup([[data],fn])
当按钮被松开时,发生keyup事件。它发生在当前获得焦点的元素上
$(document).ready(function() { $(document).keyup(function() { console.log($(this)); }); }); 复制代码
keypress([[data],fn])
当键盘或按钮被按下时,发生keypress事件
注意:keypress仅仅是输入时按下该按键时被触发,有shift、ctrl等按键或者输入法干扰时并不会触发
$(document).ready(function() { $(document).keypress(function(event) { console.log(event); }); }); 复制代码
其它事件
ready(fn)
当DOM载入就绪可以查询及操纵时绑定一个要执行的函数。
注意:必须在页面加载完成后才能查询到DOM中的元素
resize([[data],fn])
当调整浏览器窗口的大小时,发生resize事件
注意:触发该事件的对象必须是window而不是document
$(document).ready(function() { $(window).resize(function() { console.log($(this)); }); }); 复制代码
focus([[data],fn])、blur([[data],fn])
当元素获得(失去)焦点时触发focus(blur)事件(blur事件常用于表单项做校验)
$(document).ready(function() { $('.formElement').focus(function() { console.log('我获得焦点啦!O(∩_∩)O'); }); $('.formElement').blur(function() { console.log('我失去焦点啦!5555555……'); }); }); 复制代码
change([[data],fn])
当元素的值(value)发生改变时,会发生change事件
$(document).ready(function() { $('.formElement').change(function() { console.log('我正在发生改变!O(∩_∩)O'); }); }); 复制代码
注意:
如果input的类型是number,那么点击【增加减少按钮】连续不断改变number数值时,会隔一段时间执行一次函数体内的代码,不会每改变一次就执行一次。但如果是逐次改变number数值,就会逐次执行函数体内的代码。
如果数值是用键盘输入的,不管一次性输入多少都不会触发change事件,但只要点击【增加减少按钮】或者按下回车,就会触发change事件。
也就是说只有检测到input的值发生改变才会触发change事件,而input在输入时不会检测值的改变,只有用外界方式刺激后才会检测。
select([[data],fn])
当textarea或文本类型的input元素中的文本(文本框中可选中可编辑的文本)被选择时,发生select事件(文本内容用鼠标光标或者键盘选中)
$(document).ready(function() { $('.formElement').select(function() { console.log('我被选中了!O(∩_∩)O'); }); }); 复制代码
submit([[data],fn])
当提交表单时,会发生submit事件
三种用途
提交表单
阻止表单提交
提交表单时进行一些操作(如验证)
$(document).ready(function() { //提交表单 $('input[type=button]').click(function() { //点击提交按钮触发提交表单事件 $('form').submit(); }); //阻止表单提交 $('form').submit(function() { // ...... return false; //回调函数返回false都不会提交 }); // 提交表单时做一些我们所需要做的事情(多用于表单验证) $('form').submit(function() { var inputValue = $('input[type=text]').val(); if (inputValue !== 'www.imooc.com') { return false; } }); }); 复制代码
注意:在firefox、chrome、Safari、Opera下,标签包含在表单中默认是submit类型,能够自动提交。
事件参数
event
有些事件,如mousemove和keypress,我们需要获取鼠标位置和按键的值,否则监听这些事件就没什么意义了。
所有事件都会传入event对象作为参数,可以从event对象上获取到更多的信息。
事件绑定与取消
on(events,[selector],[data],fn)
selector:选择器
data:传入事件的值
fn:执行函数
在选择元素上绑定一个或多个事件的事件处理函数
说明:在jQuery1.7前,没有办法找到通过JavaScript动态生成的元素来对其进行事件绑定,它只能找到HTML文件中已经写好的元素,只能通过live来绑定事件,但是live非常消耗性能,所以在jQuery1.7后就删去bind、delegate和live三种方法,改用on方法代替。
$(document).ready(function() { $(document).on('mouseenter', 'a', function(event) { //这里的a可以是动态生成的 event.stopPropagation(); //防止事件冒泡 index = $(this).index(); swiper(); }); $(document).on('keydown', function(event) { event.stopPropagation(); //防止事件冒泡 if (event.keyCode == 37) { //键盘← index = index > 0 ? --index : $('a').length - 1; //index=0时,-1跳转到末尾 } else if (event.keyCode == 39) { //键盘→ index = index < $('a').length - 1 ? ++index : 0; //index=length-1时,+1跳转到开头 } else { return false; } swiper(); }); // bind、delegate、live var index = 0; var mouseEvent = function(event) { event.stopPropagation(); index = $(this).index(); swiper(); }; var keyEvent = function(event) { event.stopPropagation(); if (event.keyCode == 37) { index = index > 0 ? --index : $('a').length - 1; } else if (event.keyCode == 39) { index = index < $('a').length - 1 ? ++index : 0; } else { return true; //这里如果返回false会阻止键盘其他按键的功能 } swiper(); } var events = { mouseenter: mouseEvent, keydown: keyEvent }; $('a').add(document).on(events); var swiper = function() { $('img').eq(index).css({ 'opacity': '1' }).siblings().css({ 'opacity': '0' }); } }); 复制代码
off(events,[selector],fn)
在选择元素上移除一个或多个事件的事件处理函数
$(document).ready(function() { // 要绑定的事件 function flash() { $('.button').show().fadeOut('slow'); } // 事件绑定 $('.bind').click(function() { //点击bind,为obj绑定一个click事件,点击obj有flash效果 $(document).on('click', '.obj', flash) .find('.obj').text('点击按钮有效果'); }); // 取消事件绑定 $('.unbind').click(function() { //点击unbind,为obj取消一个click事件,取消的事件名与绑定的事件名要一模一样 $(document).off('click', '.obj', flash) .find('.obj').text('这个按钮点击没有效果'); }); }); 复制代码
one(type,[data],fn)
为每一个匹配元素的特定事件(比如click)绑定一个一次性的事件处理函数
说明:一个一次性的事件处理函数,绑定并执行一次之后,就自动解绑了
$(document).ready(function() { // 绑定一次事件 $('.one').click(function() { $(document).one('click', '.obj', flash) .find('.obj').text('这个按钮可以点击一次'); }); }); 复制代码
jQuery扩展
动画原理
我们只需要以固定的时间间隔(例如,0.1秒),每次DOM元素的CSS样式修改一点(例如,高宽各增加10%),看起来就像动画了
自定义动画
animate()
可以实现任意动画效果,需要传递的参数是DOM元素最终的CSS状态和时间
var div=$('#test-animate'); div.animate({opacity:0.25, width:'256px', height:'256px'},3000); //3000ms=3s,动画持续时间 复制代码
注意:为了防止图片切换时,由于动画本身播放的时间尚未结束而引起延迟,需要用stop()在播放下一个动画时结束前一个动画
$(document).ready(function() { var index = 0; var mouseEvent = function(event) { event.stopPropagation(); index = $(this).index(); swiper(); }; var keyEvent = function(event) { event.stopPropagation(); if (event.keyCode == 37) { index = index > 0 ? --index : $('a').length - 1; } else if (event.keyCode == 39) { index = index < $('a').length - 1 ? ++index : 0; } else { return true; } swiper(); } var events = { mouseenter: mouseEvent, keydown: keyEvent }; $('a').add(document).on(events); var swiper = function() { $('img').eq(index).css({ 'opacity': '1' }).siblings().css({ 'opacity': '0' }); } //用stop()结束动画 var swiper = function() { $('img').eq(index).stop().animate({ 'opacity': '1' }, 1000).siblings().stop().animate({ 'opacity': '0' }, 1000); } }); 复制代码
注意:css的值都是字符串,记得用引号括起来
delay()
delay()方法可以实现动画暂停
$(document).ready(function() { var swiper = function() { $('div').stop() .animate({'width': '0%'}, 1000) //1s播放 .delay(1000) //1s暂停 .animate({'width': '100%'}, 1000); //1s播放 } }); 复制代码
动画函数
show/hide
直接以无参形式调用show()和hide(),会显示和隐藏DOM元素,但是只要传递一个时间参数(具体时间或者fast、slow)进去,就变成了动画。
var div=$('#test-show-hide'); div.hide(3000); //在3秒钟内逐渐消失 $(document).ready(function() { var swiper = function() { $('img').eq(index) .stop().show() //当前元素show,其他元素hide .siblings() .stop().hide(); } var swiper = function() { $('img').eq(index) .stop().show('slow') //slow≈600ms .siblings() .stop().hide('slow'); }); 复制代码
toggle()
根据当前状态决定是show()和hide(),如果原本限时价流隐藏,如果原本隐藏就显示 。
$(document).ready(function() { var swiper = function() { $('div').stop().toggle('slow'); //从左上角收起/展现来回切换 } }); 复制代码
注意:toggle()只在左上角切换显示/隐藏状态
fadeIn/fadeOut
这两个方法是动画淡入淡出,也就是通过不断地设置DOM元素的opacity属性来实现
$(document).ready(function() { var swiper = function() { $('img').eq(index) .stop().fadeIn('slow') //当前元素淡出,其他元素淡入 .siblings() .stop().fadeOut('slow'); } }); 复制代码
fadeToggle()
fadeToggle()犯法则根据元素是否可见来决定下一步动作
$(document).ready(function() { var swiper = function() { $('div').stop().fadeToggle('slow'); //淡入淡出显示/隐藏来回切换 } }); 复制代码
slideUp/slideDown
在垂直方向主键展开或收缩
$(document).ready(function() { var swiper = function() { $('img').eq(index) .stop().slideDown('slow') //当前元素展开,其他元素隐藏 .siblings() .stop().slideUp('slow'); } }); 复制代码
slideToggle()
slideToggle()根据元素是否可见来进行下一步动作
$(document).ready(function() { var swiper = function() { $('div').stop().slideToggle('slow'); //展开/隐藏来回切换 } }); 复制代码
计时器
setTimeout
设置过多长时间执行函数
setInterval
设置每隔多长时间执行函数
注意:原生的setTimeout和setInterval效率要比jQuery中封装的好很多,所以不推荐使用jQuery中的这两个方法。
JSON与AJAX基础
什么是Ajax?
Ajax的全称是Asynchronous JavaScript and XML(即异步的JavaScript和XML),它并不是一种新的编程语言,而是几种原有技术的结合体
Ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术
Ajax的优点
通过异步模式,提升了用户体验
优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少带宽占用
Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,而减少了大用户量下的服务器负载
说明:JavaScript是单线程的,意味着所有任务需要排队执行,前一个任务执行完才能执行后一个,如果前一个任务执行很久,后一个任务就需要一直等待。所有任务又分成同步任务和异步任务,同步任务在主线程上安排,必须排队等待,而Ajax恰恰使用异步模式与服务器进行通讯,这样一来就不会打断用户的操作,具有更加迅速的响应能力。
Ajax的缺点
不支持浏览器back按钮(ajax是在页面内部与服务器进行通讯的)
安全问题Ajax暴露了与服务器交互的细节
对搜索引擎的支持比较弱
XMLHttpRequest对象
什么是XMLHttpRequest
是一种支持异步请求的技术,它是Ajax的核心
XMLHttpRequest的作用
可以向服务器提出其你去并处理响应,而不阻塞用户
可以在页面加载以后进行页面的局部更新
如何使用Ajax
要完成实现一个Ajax异步调用和局部刷新,通常需要以下几个步骤
创建XMLHttpRequest对象,也就是创建一个异步调用对象
创建一个新的HTTP其你去,并指定该HTTP请求的方法、URL
设置响应HTTP请求状态变化的函数
创建XMLHttpRequest对象
先将网页部署到服务器上(这里用的wampServer3.0.6,将网页放到根目录下,即面板中的www directory)
下面是一个兼容各种浏览器的创建XMLHttpRequest对象的函数
完整版
<!DOCTYPE html> <html> <head> <title>ajax</title> </head> <body> <script type="text/javascript"> //封装通用的xhr对象,兼容各个版本的浏览器 function createXHR(){ //判断浏览器是否将xhr作为本地对象实现,针对IE7,firefox、Opera等(如果不是undefined就说明作为本地对象实现了) if(typeof XMLHttpRequest !="undefined"){ return new XMLHttpRequest(); //如果不是undefined,就要返回它的一个实例,去创建一个xhr对象 }else if(typeof ActiveXObject !="undefined"){ //这是IE浏览器的判断方法 //将所有可能出现的ActiveXObject版本放到数组内 var xhrArr=['Microsoft.XMLHTTP','MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP.2.0']; //判断支持的是哪个版本,需要遍历创建xhr var len=xhrArr.length,xhr; for (var i = 0; i < len; i++) { //判断能否执行,而不是判断真假 try{ //创建xhr对象 xhr=new ActiveXObject(xhrArr[i]); //找到一个可执行的版本就跳出循环体 break; } catch(ex){ //捕获到异常后干什么 } } return xhr; }else{ throw new Error('No XHR object available!'); } } //xhr对象 var xhr=createXHR(); console.log(xhr); </script> </body> </html> 复制代码
简化版
var xmlhttp; if(window.XMLHttpRequest){ // code for IE7+, firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); }else{ // code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } 复制代码
创建新的HTTP请求
语法:open(method,url,async)
功能:创建HTTP请求,规定请求的类型、URL及是否异步处理请求
参数说明:
method:请求类型,GET或POST(默认是GET)
url:文件在服务器上的位置
async:true(异步)或false(同步)
注意:
open方法不会向服务器发送真正请求,它相当于初始化请求并准备发送,只能向同一个域中使用相同协议和端口的URL发送请求,否则会因为安全原因报错。
url参数是open()方法中唯一一个必须要指定的参数,用来设置服务器上文件的地址,该文件可以是任何类型的文件,如.txt和.xml,或者服务器脚本文件,如.asp和.php(在传回响应之前,能够在服务器上执行任务)
★ GET和POST的区别 ★
与POST相比,GET更简单也更快,并且在大部分情况下都能用,但在以下情况中,必须使用POST请求:
无法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST没有数据量限制)
发送包含未知字符的用户输入时,POST比GET更稳定也更可靠
★ 同步与异步的区别 ★
同步:提交请求→等待服务器处理→处理完毕返回。这个期间客户端浏览器不能干任何事
异步:请求通过事件触发→服务器处理(这时浏览器仍然可以做其他事情)→处理完毕
说明:async是一个布尔值。如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等服务器返回消息后采取执行其他操作。
//创建请求 xhr.open("get","./server/slider.json",true); //open是XMLHttpRequest的方法 复制代码
设置响应HTTP请求状态变化的函数
xhr.onreadystatechange=function(){ //异步调用成功,响应内容解析完成,可以在客户端调用 if(xhr.readyState===4){ //0表示还未初始化,1表示已经调用send方法正在发送请求,2表示send方法执行完成,3表示正在解析响应内容,4表示异步调用成功 //status>=200且<300时表示交易成功,=304表示请求成功过,且请求资源没有被修改,可以使用浏览器的缓存 if((xhr.status>=200&&xhr.status<300)||xhr.status===304){ //向服务器发送请求,获得服务器返回的数据 } } }; 复制代码
在收到响应后相应数据会填充到XHR对象的属性,有四个相关数据会被填充
responseText——从服务器进程返回数据的字符串形式(常用)
responseXML——从服务器进程返回的DOM兼容的文档数据对象
status——从服务器返回的数字代码,如404(未找到)和200(已就绪)
statusText——伴随状态码的字符串信息
发送HTTP请求
语法:send(string)
功能:将请求发送到服务器
参数说明:string仅用于post请求,get请求不需要传入参数
注意事项:仅在POST请求时可以传入参数,不需要则发送null,在调用send方法之后请求被发往服务器
如何添加HTTP头
如果需要像HTML表单那样POST数据,需使用setRequestHeader()来添加HTTP头,然后在send()方法中规定希望发送的数据
语法:xmlhttp.setRequestHeader(header,value)
使用:xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//创建请求 xhr.open("post","./server/slider.json",true); //发送请求 xhr.send(null); //不传参数的情况 复制代码
获取异步调用返回的数据
//向服务器发送请求,获得服务器返回的数据 console.log(xhr.responseText); //以字符串形式获取 //转化成JavaScript可以处理的格式 var data=eval("("+xhr.responseText+")"); //eval()可以将字符串转化成JavaScript可以处理的数据 console.log(data.name); //输出data对象中name属性的值 复制代码
渲染数据到页面中(使用JavaScript和DOM实现局部刷新 )
//xhr.onreadystatechange的匿名函数中 xhr.onreadystatechange=function(){ //异步调用成功,响应内容解析完成,可以在客户端调用 if(xhr.readyState===4){ //0表示还未初始化,1表示已经调用send方法正在发送请求,2表示send方法执行完成,3表示正在解析响应内容,4表示异步调用成功 //status>=200且<300时表示交易成功,=304表示请求成功过,且请求资源没有被修改,可以使用浏览器的缓存 if((xhr.status>=200&&xhr.status<300)||xhr.status===304){ //向服务器发送请求,获得服务器返回的数据 data=JSON.parse(xhr.responseText); //渲染数据到页面中 renderDataToDom(); } } }; //function renderDataToDom中 //渲染数据 function renderDataToDom(){ var info=data; console.log(info); var div=document.getElementById('div'); var a=document.createElement("a"); a.innerHTML=info.name; div.appendChild(a); } 复制代码
JSON
什么是JSON
JSON(JavaScript object notation)全程是JavaScript对象表示法,它是一种数据交换的文本格式,而不是一种编程语言,用于读取结构化数据,2001年由Douglas Crockford提出,目的是取代繁琐笨重的XML格式
JSON的语法规则
简单值
简单值使用与JavaScript相同的语法,可以在JSON中表示字符串、数值、布尔值和null
字符串必须使用双引号表示,不能使用单引号,数值必须以十进制表示,且不能使用NaN和Infinity
说明:JSON不支持JavaScript中的特殊值undefined
对象
对象作为一种复杂数据类型,表示的是一组有序的键值对,而每个键值对中的值可以是简单值,也可以是复杂数据类型的值。
JSON中对象的键名必须放在双引号里面,因为JSON不是JavaScript语句,所以没有末尾的分号
说明:同一个对象中不应该出现两个同名属性
数组
数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值
说明:数组或对象最后一个成员的后面,不能加逗号
JSON对象的两个方法
parse()
语法:JSON.parse()
功能:用于将JSON字符串转化成对象
var data=JSON.parse(xhr.responseText); console.log(data.name); 复制代码
stringify()
语法:JSON.stringify()
功能:用于将一个值转为字符串,该字符串应该符合JSON格式,并且可以被JSON.parse()方法还原
JSON对象总结
JSON之所以流行,是因为可以把JSON数据结构解析为有用的JavaScript对象
JSON对象的stringify()和parse()这两个方法可以分别用于把JavaScript对象序列化为JSON字符串和把JSON字符串解析为原生JavaScript值
JavaScript的eval()类似于JSON.parse()方法,可以将JSON字符串转换为JSON对象,但是eval()可以执行不符合JSON格式的代码,有可能会包含恶意代码,所以尽量少用
jQuery的ajax方法
$.ajax()
这个方法可以取代用原生JavaScript进行创建请求、设置请求状态变化函数、发送请求、获得数据和渲染数据
$.ajax({ url:"./server/slider.json", //请求地址 type:"post", //请求方式,默认是get async:true, //同步异步 dataType:"json", //服务端返回的数据格式 success:function(){ //请求成功后回调的函数 jQrenderDataToDom(); } }) 复制代码
说明:jQuery的渲染可以直接用$.each()进行遍历
$.get()
$.post()
$.getJson()
待补充
跨域
什么是同源策略
所谓同源是指:域名,协议,端口均相同,缺一不可
什么是跨域
跨域是指从一个域名的网页去请求另一个域名的资源,严格一点的定义是:只要协议,域名,端口有任何一个不同,就被当做是跨域
如何解决跨域
跨域资源共享(CORS)
使用JSONP(常用)【原生】
修改document.domain
使用window.name
什么是JSONP
JSONP是JSON Padding(填充式JSON)的简写,是应用JSON的一种新方法,也是一种跨域解决方案
JSONP的组成
JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据
JSONP的原理
直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,JSONP正是利用这个特性来实现的。
jQuery的跨域解决方案
jQuery中的$.ajax()是如何实现跨域的?
jQuery是如何做到在url后加?callback来实现跨域的?
说明:我们在自己的网页中可以访问到其他域名的图片甚至是JavaScript函数库,就是因为允许跨域
作者:hiyoritsai
链接:https://juejin.cn/post/7025874915525918756