常用的JS-DOM操作与jQuery的对比
jQuery用多了,还是需要来熟练熟练原生JS的操作,不然写JS都快离不开jQuery了
目录
1. 获取DOM
2. 创建DOM
3. 添加DOM
4. 删除DOM
5. 添加class
6. 是否存在class
7. 删除class
8. 实现 JQ 的toggleClass
9. 获取DOM的css样式
10. 给DOM设置css样式
11. 删除DOM的css样样式
12. DOM的查找(遍历),例如查找父级,子级,兄弟等节点
13. 获取DOM的属性
14. 给DOM设置,添加和删除属性
15. 修改元素的文本值
16. 原生ajax和JQ的ajax
获取DOM
- jq:
//通过id:
$("#box");
//通过class名:
$('.box');
//通过标签名:
$('img');
- js:
// 通过id:
document.getElementById('box');
document.querySelector("#box");
// 通过class名:
document.getElementsByClassName('box');
document.querySelector(".box");
document.querySelectorAll('.box');
// 通过标签名:
document.getElementsByTagName('img');
// 通过元素的name属性:例:获取input的name属性值为passWd的元素,得到的也是一个元素集合
// 也可以通过非表单元素的name属性来获取该DOM
document.getElementsByName('passWd')
说明:
(1)querySelector(".box")
是返回第一个类名为box的元素。
(2)querySelectorAll('.box')
是返回文档中所有class为 "box" 的div元素。
(3) 这两个方法接收的参数和CSS选择器完全一致,也就是可以使用jq选择器的那种样式来操作,例如:querySelector('.box>p')
返回box中第一个p元素,querySelectorAll('.box>ul li')
返回 box 的子元素 ul 里的所有 li。
(4) 一定要注意getElementsByClassName
返回的是动态的节点元素集合,意思就是当文档加载完,js添加了某个节点,再去获取该节点的长度,就是添加后的长度。而且不支持ie8及以下,不支持ie8及以下,不支持ie8及以下。
(5)querySelector
,querySelectorAll
返回的是静态的节点元素集合,意思就是当文档加载完后,节点有几个就是几个长度的元素集合,不管js是否添加了节点,都是刚加载完时节点的长度。而且不支持ie7及以下,不支持ie7及以下,不支持ie7及以下。
(6) 性能上来说,我个人觉得如果只要一次查找就能找到元素的话,推荐getElementsByClassName
,如果需要多级查找就选querySelector
或者querySelectorAll
。
(7) 那怎样解决document.getElementsByName
和querySelector
,querySelectorAll
的兼容问题呢?可以参考司徒正美的这篇文章或者搜索Sizzle
选择器引擎看看jquery是怎样实现的,或者看看这篇文章。
创建DOM
- jq:
var jq_obj=$("<div class='box'>123</div>");
- js:
var box_obj=document.createElement('div');//创建div元素
var box_txt=document.createTextNode('456');//创建文本节点
box_obj.appendChild(box_txt);//向div中添加文本节点
// 或者是:box_obj.innerText='456';可以替换上面两步
// 或者是:box_obj.innerHTML='<h4>123</h4>';
box_obj.setAttribute('class','box');//设置class名
添加DOM
- jq:
var jq_obj=$('.box');
var str='<span>我是ppppp</span>';//需要添加的内容
jq_obj.append(str);//添加指定内容到所有的jq_obj里面的末尾
$(str).appendTo(jq_obj);//向所有的jq_obj元素里面的末尾添加指定内容
jq_obj.prepend(str);//添加指定内容到所有的jq_obj里面的前面
jq_obj.after(str);//在所有的同级的jq_obj之后插入指定内容
jq_obj.before(str);//在所有的同级的jq_obj之前插入指定内容
$(str).insertAfter(jq_obj);//在所有的同级的jq_obj之后插入指定内容
$(str).insertBefore(jq_obj);//在所有的同级的jq_obj之前插入指定内容
- js:
//第一种方式
var obj=document.getElementsByClassName('box');
var node=document.createElement('span');
node.innerHTML='<h4>123</h4>';
// 或者 node.innerText='打工是不可能打工的'
obj[0].appendChild(node);//将节点node添加到obj里面的结尾。
obj[0].parentNode.insertBefore(node,obj[0]);//将node节点添加到同级的obj之前
// 第二种方式,例:在class名为test的div中添加下面的内容:
var txt='<div>123123</div>';
document.getElementsByClassName('test')[0].innerHTML=txt;
// 当然,这种以字符串添加的方式,只能用innerHTML,不能用innerText。
// 相当于是把里面的内容重新赋值,所以最好添加的时候确保test里面没有内容否则会被覆盖
// 要想不覆盖,也可以先获取原来的内容,然后再累加需要添加的内容即 innerHTML += txt
// 下面的例子1:容易错误的点:请看第8条说明
for(var i=0;i<2;i++){
obj[0].appendChild(node);
// obj[0].parentNode.insertBefore(node,obj[0]);
}
// 例子2,全部节点都添加指定内容
for(var i=0;i<2;i++){
var node2=document.createElement('span');
node2.innerHTML='<h4>22222</h4>';
obj[0].appendChild(node2);
// obj[0].parentNode.insertBefore(node2,obj[0]);
}
说明:
(1)insertBefore
在 JS 和 JQ 中都有这个方法,但是使用的方式不一样:
(2) JQ 常用的文档操作 看这里。
(3) 在 JS 中,insertBefore
的语法是:node.insertBefore(newnode,existingnode)
。
(4)node
表示插入内容的父级。
(5)newnode
表示需要插入的内容。
(6)existingnode
表示在其之前插入新节点的子节点。
(7) 如果第二个参数设置为null
,那么会导致insertBefore
方法会在node
的末尾插入newnode
。如果不设置则会报错。
(8) 如果在for循环里面appendChild
或者insertBefore
,那么会导致只有在最后一个元素的里面的结尾才能添加指定的内容。为什么呢,可以把它理解为一个萝卜只占一个坑的意思。要添加的内容就是一个萝卜,而坑即例子中的obj则有几个,因此只能放在一个坑里面。如果要想把坑填满即全部元素都添加指定的内容,那么,createElement
创建元素就必须放在for循环里面。例子2就能实现。
删除DOM
- jq:
$(".div1").remove();
$(".div1").empty();
$('.div1').detach();
// detach与remove的不同:
var del=$('.div1').detach();//这里div1已经被删掉了,但是,还可以通过赋值来达到其它的操作目的
$('body').append(del);
说明:
(1)remove
方法是删除被选元素及其子元素
。也可以在remove
方法里面添加一个参数,表示对被删元素进行过滤,例如只删除ul
里面的包含class
名为active
的li
元素,则是:$("ul li").remove('.active')
。这个参数可以是任何 jQuery 选择器的语法。
(2)empty
方法是删除被选元素的子元素
。
(3)detach
方法是删除被选元素及其子元素
。看似和remove
一样,但是这个方法在删除被选元素之后,还能操作被选元素。这是与remove
的不同之处
- js:
// 第一种,
parent.removeChild(child);
// 第二种
child.parentNode.removeChild(child);
说明:
(1)parent
是要删除元素的父元素。
(2)child
是需要删除的元素。
(3) 很明显,第一种种删除方式不太科学,还要去寻找删除元素的父元素,所以推荐第二种删除方式。
(4)child.parentNode
表示要删除元素的父元素,不用再getElementById()
等方式去获取父元素了
添加class
- jq:
$('.box').addClass('active');//添加一个
$('.box').addClass('box2 box3');//添加多个
- js:
// 第一种,这种的缺点是只能设置一个class,并且会覆盖原来的class
document.getElementsByClassName('box')[0].setAttribute('class','box');
// 第二种,可以连续添加多个,但是兼容性不太好,可以看看这个兼容性列表 https://caniuse.com/#search=classList
// classList有5个方法,具体的用途可自行查找
document.getElementsByClassName('box')[0].classList.add('act1','act2');//添加多个的写法要加逗号
// 第三种,这种的缺点和第一种一样
document.getElementsByClassName('box')[0].className='box2';
// 第三种累加版,注意加入的类名前面有空格,有空格,有空格,不然会导致加入的类名和原来的类名连接在一起
// 这种的缺点是并不会判断本身有没有当前加入的类名。即原来有box2,再次加入box2时,整个class就是 box2 box2了。
document.getElementsByClassName('box')[0].className +=' box2'+' box3';//注意单引号与class名之间的空格
// 第三种进阶版,这种的缺点是当添加多个class时,也不能判断是否存在相同.只能一次添加一个
// 例:假如原本有box3,执行addClass(eleObj,'box3 box4')之后box的class名变成了box3 box3 box4
var eleObj=document.getElementsByClassName('box')[0];
addClass(eleObj,'box3')
function addClass(ele,cls){
var reg=new RegExp('(^|\\s)'+cls+'(\\s|$)');
var e_statu=reg.test(ele.className);//返回的是布尔值
// 或者是直接用下面match的方法
// var e_statu=ele.className.match(RegExp('(^|\\s)'+cls+'(\\s|$)'));//返回的是一个数组,并不是布尔值
if(!e_statu){
ele.className+=' '+cls;
}else{
alert('有相同的class');
}
}
说明:
(1) 在正则表达式new RegExp('(^|\\s)'+cls+'(\\s|$)')
中\\s
原本是\s
,表示匹配空白字符,但是\
会在实例的引号中转义,导致\s
最终变成s
,所以要多加一个斜杠经过转义之后才是\s
,所以是\\s
。
(2) 管道符|
表示将符号两边的匹配条件进行逻辑“或”(or)运算,所以这里的意思是cls
的前面有或者没有空白符,后面有或者没有空白符。而且(^|\\s)
这种两边的括号不能少。
(3) ^ 表示匹配开始。
(4) $ 表示匹配结束。
(5)var reg=/\d+/
,这种是用字面量方式创建正则。匹配带有\
符号的正则时就不用再多加斜杠。
(6)new RegExp('(^|\\s)')
,这种是用实例创建正则。由于引号的影响,需要多加一个斜杠转义成正确的正则。
是否存在class
- jq
$('.box').hasClass('active');
- js
var eleObj=document.getElementsByClassName('box')[0];
HasClass(eleObj,'box3');
function HasClass(ele,cls){
var regs=new RegExp('(^|\\s)'+cls+'(\\s|$)');
var e_statu=regs.test(ele.className);
if(e_statu){
alert('存在这个class');
}else{
alert('没有这个class')
}
}
删除class
- jq
$('.box').removeClass('active');
- js
// 第一种方法,类似添加class,把class名全部覆盖掉就能达到效果。
// 这种的缺点也是不能把所需的删掉
document.getElementsByClassName('box')[0].setAttribute('class','');
// 第二种方法,使用classList的remove方法,还是兼容性的问题
document.getElementsByClassName('box')[0].classList.remove('box3');
document.getElementsByClassName('box')[0].classList.remove('box3','box4');//也可以同时删多个
// 第三种方法:和添加一个道理
var eleObj=document.getElementsByClassName('box')[0];
delClass(eleObj,'box3');
function delClass(ele,cls){
var regs=new RegExp('(^|\\s)'+cls+'(\\s|$)');
var e_statu=regs.test(ele.className);
if(e_statu){
ele.className = ele.className.replace(regs,' ');//用空格来替换之后再重新赋值
}else{
alert('没有这个class')
}
}
实现 JQ 的toggleClass
var eleObj=document.getElementsByClassName('ul')[0];
eleObj.onclick=function(){
TogClass(this,'active');
}
// toggleClass函数
function TogClass(element,_class){
if(HasClass(element,_class)){
DelClass(element,_class);
}else{
AddClass(element,_class);
}
}
//是否存在该class
function HasClass(ele,cls){
var regs=new RegExp('(^|\\s)'+cls+'(\\s|$)');
var e_statu=regs.test(ele.className);
if(e_statu){
//alert('存在这个class');
return true;
}else{
//alert('不存在这个class');
return false;
}
}
// 添加class
function AddClass(ele,cls){
if(!HasClass(ele,cls)){
ele.className+=' '+cls;
}
}
// 删除class
function DelClass(ele,cls){
var regs=new RegExp('(^|\\s)'+cls+'(\\s|$)');
if(HasClass(ele,cls)){
ele.className = ele.className.replace(regs,' ');
}
}
获取DOM的css样式
- jq
$('.box').css('color');
$('.box').width();
$('.box').height();
- js
var obj=document.getElementsByClassName('box')[0];
var _color=obj.style.color;//这种获取的方式 只能 获取到元素的行内样式,行内样式,行内样式
var hei=obj.currentStyle.height;//这是 IE 专属获取非行内样式的方法。
var wid=window.getComputedStyle(obj,null/伪类).width;//这是获取元素所有样式的方法。第二个参数为可选
var wid=window.getComputedStyle(obj,null/伪类)['width'];//这种写法也可以,不用驼峰写法,直接原来的css名称
var txt=window.getComputedStyle(obj,':before').content;//这是伪类的获取方式
var txt=window.getComputedStyle(obj,':before')['content'];
// 如果要获取obj本身的样式,后面的参数就是null,如果是obj的伪类,则第二个参数就是伪类
// getPropertyValue的用法
var wid=window.getComputedStyle(obj,null/伪类).getPropertyValue('width');
var wid=obj.style.getPropertyValue('width');// 只要是通过style获取的都是行内样式
// 在ie9以下:
var idObj=document.getElementById('test');
var bg=idObj.currentStyle.getAttribute('backgroundColor');
说明:
(1) 如果用style获取类似background-color
这种属性,需要写成驼峰的形式,比如:style.backgroundColor
。
(2) 还有就是background-color
不是行内样式也能通过style获取,我不知道原因。
(3)getComputedStyle
获取到的值都是绝对单位
,即写css时有些有单位的,获取出来也有单位。比如:获取border,得到的结果是2px solid rgb(255, 0, 0)
。获取到的颜色也是rgb格式的。
(4)getComputedStyle
返回的是只读属性列表对象,意思是不能通过这个方法设置样式属性。不兼容ie8及以下,不兼容ie8及以下,不兼容ie8及以下。有些古老的浏览器需要第二个参数,或者不能获取伪元素的样式,具体兼容性可看这里
(5)currentStyle
在获取border属性的时候currentStyle.border
或者currentStyle['border']
或者currentStyle['border-width']
返回的都是undefined
,这里也是需要通过驼峰的方式currentStyle.borderWidth
获取border的宽度。还有许多其他的差异。。。
(6)getPropertyValue
只支持ie9及以上,而且不支持驼峰写法,获取到的值,也是绝对单位
。
(7)getAttribute
中的样式名应该需要驼峰的写法,ie8我测背景颜色的时候返回的是null。
(8) 还有一个获取样式的方式,不过比较麻烦,需要获取页面所有的样式表,再去找。有兴趣的可以搜搜document.styleSheets
。
给DOM设置css样式
- jq
$('.box').css({
'height':100, //jq设置css样式是可以不用加单位的,会自动给你加上。
'width':100
})
- js
// 第一种,直接设置单个样式
// 使用querySelector和getElementsByClassName来设置
var obj=document.getElementsByClassName('box')[0];
var obj2=document.querySelector('.box>p');
obj.style.width='100px';
obj2.style.height="200px";
// 都可以通过 DOM.style.property="值"来设置,
// property有哪些属性可以查看 http://www.w3school.com.cn/htmldom/dom_obj_style.asp了解
// 第二种,设置style的cssText,可以像行内样式一样连着写
obj.style.cssText='width:100px;background:red;font-size:18px';
// 但是这个也有缺点,一个是DOM.style.cssText,只能获取行内样式,只能获取行内样式,只能获取行内样式
// 还有就是会覆盖原来已经有的行内样式,例:<div style="display:none"></div>
// 当给该div设置cssText='color:red;font-size:14px;'等属性之后,原来的display就没有了。。而且ie6,7,8会出现一些坑:
// 1. 属性名全部都是大写,属性值没变还是小写。
// 2. 最后一个样式末尾无分号。
// 3. 复合属性名会被拆分,比如border会被拆分成border-top,border-left等等。。。
// 解决覆盖的办法是:先获取原来的样式,再把需要添加的样式累加上去。例:
var obj=document.getElementById('box');
var oldCss=obj.style.cssText;
var newCss='color:skyblue;font-size=14px;';//记住添加的css样式末尾要加入“;”号,
obj.style.cssText=newCss + oldCss ;//newCss加在原样式前就不用担心末尾无分号导致累加的样式出问题。
说明:在js的cssText操作中:
(1) 如原来是"color:skyblue;font-size=14px;"
,在ie8及以下
时,在原属性后面添加了"background:red;"
,整个行内css
会变成"COLOR:skyblue;FONT-SIZE=14pxBACKGROUND:red;"
,14px后面分号就没了,导致整个连在一起。因此在原属性前面添加css就不怕存在这种问题.
(2) 但是假如当原来的css属性"width:100px;background:red;"
,新添加的css样式是"font-size:14px;"
这种字体的样式时,就算把新样式添加到原样式前面,显示出来的还是在原样式后面,在ie8及以下最终的样式为:"WIDTH: 100px;BACKGROUND: red;FONT-SIZE:14px"
,虽然没有错,但是感觉怪怪的。。。
删除DOM的css样式
- jq
$('.box').css('width','');//这是把指定的一个属性置为空,就实现删除的功能了。
$('.box').removeAttr('style');//这个方法是把所有的 行内样式 全部删除
- js
var obj=document.getElementById('box');
obj.style.width='';//注意,这只能删除 行内样式
obj.style.cssText='';//同上
obj.style.removeProperty('color');//同上
obj.removeAttribute('style');//删除所有 行内样式
说明:
(1) 那么怎样删除非行内样式,比如内嵌的style
里的属性或者link引入的css属性呢???抱歉,我也不知道。。。不要告诉我可以用document.styleSheets
来修改,在n多行代码里找索引值,太笨的想法。。。
(2) 或许也可以换种思路,通过class的添加和删除来实现样式的添加和删除
DOM的查找(遍历),例如查找父级,子级,兄弟等节点
- jq
// 下面的selector都是是匹配元素的选择器表达式
// 查找父级节点,而且只查到父级。selector可以不设置
$('.box').parent(selector);
// 查找祖先节点,查找到是哪个祖先节点是根据selector
// 如果不设置selector则最终会查找到HTML
$('.box').parents(selector);
// 查找兄弟节点,查找到哪个兄弟节点是根据selector
// 如果不设置selector则是全部兄弟节点
$('.box').siblings(selector);
// 查找同级节点紧邻的前一个节点。注意,是紧邻的,而且只查找这一个
// selector可以不设置。
$('.box').prev(selector);
// 查找被选元素之前的所有同级元素,selector可以不设置
$('.box').prevAll(selector);
// 查找被选元素的后一个同级元素。注意,是紧邻的,而且只查找这一个
// selector可以不设置。
$('.box').next(selector);
// 查找被选元素之后的所有同级元素,selector可以不设置
$('.box').nextAll(selector);
// 查找被选元素的后代元素。通过selector来筛选查找哪些
$('.box').find(selector);
// 查找被选元素的第一个元素
$('.box').first(selector);
// 例:$(".box p").first(); 查找第一个class为box下面的第一个p标签
// 查找带有被选元素的指定索引号的元素
$(".box").eq(number);
// 例:$(".box").eq(1); 选取class名为box并且索引值为1的节点
// 查找被选元素的所有儿子元素。selector用于筛选是哪些儿子元素。注意只是儿子节点。只是儿子节点。只是儿子节点
// 要查子孙节点或其他后代可考虑用find
$('.box').children(selector);
- js
var obj=document.getElementById('box');
// 查找被选元素的全部子节点
var a = obj.childNodes;//返回obj对象所有的子元素,包括子孙节点或其他后代
// 查找被选元素的全部子节点,对滴,js中也有children的用法。
var a = obj.children;//返回obj对象所有的子元素,不包括,不包括,不包括子孙节点或其他后代
// 查找被选元素的父节点,只是父节点,不能查祖先元素,如果没有父节点,则返回null
var b = obj.parentNode;
// 查找被选元素紧邻的下一个兄弟节点
var c = obj.nextSibling;
// 查找被选元素紧邻的上一个兄弟节点
var d = obj.previousSibling;
// 查找被选元素的第一个子节点
var _e = obj.firstChild;
// 查找被选元素的最后一个子节点
var f = obj.lastChild;
说明:
(1) 由于在js中,文本也算节点,而空格是文本,所以有时候在查询时会导致结果不准确,排查一下是否有空格。例如使用childNodes
查询后代的时候,它返回的是NodeList
,即节点列表集合(包含元素,也包含节点)
,所以如果在后代中有空格,那么这个空格也会被加入到NodeList
,并且在节点列表中自动以#text
来表示,这样就会导致获取的后代节点长度不正确。
(2) 而使用children
获取子元素,浏览器中返回的虽然是HTMLCollection
(元素集合),但是它还是属于NodeList
对象,不过只包含Element对象
即只含元素,因此不会包含空格。children
并非标准属性,但是能在所有的浏览器中运行。
(3) 还有就是注释节点Comments
,文本节点text
不包含children
。
获取DOM的属性
- jq
$('.box').attr('data-id');
- js
var obj=document.getElementById('box');
// getAttribute(属性名)
obj.getAttribute('data-id');//获取data-id的属性值
// getAttributeNode(属性名)
obj.getAttributeNode('data-id').value;//获取data-id这个属性节点的值
说明:
(1)getAttribute
与getAttributeNode
看似是一样的,实际上完全不同。
(2)getAttribute
返回的是属性名的属性值。
(3) 而getAttributeNode
返回的是指定的属性节点,还需要通过.value
来获取到属性值。
给DOM设置,添加和删除属性
- jq
// attr(属性名,属性值),添加属性
$('.box').attr('data-id','1');//添加data-id属性
// removeAttr(属性名),删除属性
$('.box').removeAttr('data-id');//删除data-id属性
- js
var obj=document.getElementById('box');
// setAttribute(属性名,属性值),添加或修改属性。将属性值设置为undfined也相当于删除该属性
obj.setAttribute('data-id','1');
// 不能通过setAttribute直接设置css样式,必须通过style属性来设置:
// 例:obj.setAttribute('style','background: skyblue;color: white;');
// 也可以一次性删除css样式,也必须通过style属性:obj.setAttribute('style','')
// removeAttribute(属性名)。删除属性。
obj.removeAttribute('data-id');
// setAttributeNode(属性名)添加属性节点。假设我定义了一个class为active的样式 .active{background:skyblue;}
var atr=document.createAttribute('class');//创建一个class节点
atr.nodeValue='active';//节点的值是刚才创建的 active名
obj.setAttributeNode(atr);//向obj对象添加该class
// removeAttributeNode(属性名),删除指定的属性节点,ie不支持,ie不支持,ie不支持。
var nodeAttr=obj.getAttributeNode('data-id');
obj.removeAttributeNode(nodeAttr);
说明:
(1)attributes
是返回元素的所有属性集合,比如id,行内的css属性,class,自定义属性等等。
(2) 而setAttribute
是用来设置属性的。
(3) 还有getAttribute
是用来获取属性的。
(4) 我感觉也可以用setAttributeNode
来实现 JQaddClass
的用法。
(5) 每个节点有nodeType
,nodeName
,nodeValue
三个属性,分别返回节点属性类型,节点属性名称,节点属性值
修改,获取元素的文本值
- jq
// 非表单元素 text(内容),html(内容),如果内容为空,表示获取,如果内容是 "" 表示清空内容
$('.box').text('修改了');
$('.box').html('<span>又修改了</span>');
// 表单元素 val(内容)
$('#name').val('123')
- js
var obj=document.getElementById('box');
// 获取
console.log(obj.innerHTML);//非表单
console.log(obj.innerText)
console.log(obj.value);//表单元素
console.log(obj.firstChild.nodeValue);//通过节点来获取节点的值
console.log(obj.childNodes[0].nodeValue);//通过父节点来获取节点的值
// 设置
obj.innerHTML='<span>修改了</span>';
obj.innerText='又修改了哦';
obj.value='123';//这是input等表单元素的修改方式
说明:
(1) 元素节点的nodeValue
是 undefined 或 null
(2) 文本节点的nodeValue
是文本本身
(3) 属性节点的nodeValue
是属性值
(4)firstChild
属性可用于访问元素的文本
原生ajax和JQ的ajax
- jq
$.ajax({
type:"get",//
url:"...",
async:false,//表示设置为同步请求,默认true
success:function(){
...
},
error:function(){
...
}
})
- js
// 创建XMLHttpRequest对象
var xmlhttp=new XMLHttpRequest();//IE6及以下使用 ActiveX 对象:new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState===4 && xmlhttp.status===200){
...
}
}
xmlhttp.open(method,url,async);//三个属性的具体值下面会提及
xmlhttp.send();
// document.getElementById("box").innerText=xmlhttp.responseText;//open第三个参数为false时,可省略掉onreadystatechange函数
// 来一个封装好的ajax例子
function getAjax(method,url,isAsync,backFn){
var xhr=null;
if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}else if(window.ActiveXObject){
xhr=new ActiveXObject("Microsoft.XMLHTTP");//兼容ie6及以下
}
xhr.open(method,url,isAsync);
xhr.send();
if(isAsync){
xhr.onreadystatechange=function(){
if(xhr.readyState===4&&xhr.status===200){
backFn(xhr.responseText)
//xhr.status;状态数值
//xhr.statusText;状态数值说明
//xhr.responseText;返回的内容,是字符串
}
}
}else{
backFn(xhr.responseText)
}
}
// 调用的时候
getAjax(method,url,isAsync,function(data){
console.log(JSON.parse(data));//JSON.parse,JSON.stringify不支持IE7及以下,不支持IE7及以下,不支持IE7及以下
})
说明:
(1)XMLHttpRequest
是 AJAX的基础,所有现代浏览器均支持XMLHttpRequest
对象(IE6及以下需使用ActiveXObject
)。
(2)method
是GET
还是POST
方法。
(3)url
是请求的地址。
(4)async
是异步还是同步,true为异步,false为同步。
(5)send(string)
这个方法还有个参数string,仅用于POST请求,比如传递后台需要的值send("name=fff&age=18")
。
(6) 当open
方法的async
设置为true
时,需要规定onreadystatechange
事件,而如果设置为false
的话就不用规定。
(7)onreadystatechange
事件被触发 5 次(0 - 4),对应着readyState
的每个变化。
(8) jq的ajax详细的属性说明,可看这里。
(9) 要想ie7及以下也能把字符串转json,可考虑用json2