常用的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