繼續DOM的研究工做,咱們擴展對dom api的學習!javascript
1.介紹針對低級瀏覽器,能力的監測處理:css
2.針對移動端,touch事件的介紹:html
3.最後作幾個網頁實例!html5
4.ajax的介紹:ajax輸出json格式文件 jsonp的介紹 xhr2的介紹
java
http://www.w3school.com.cn/ajax/ajax_xmlhttprequest_create.asp node
5.cookie的介紹:設置cookie和刪除cookieweb
6.html5 存儲的介紹:web客戶端存儲(localStorage sessionsStorage) 緩存( cache manifest 文件)ajax
7.html5中新元素如canvas,video、audio的api簡單介紹json
http://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp canvas
http://www.w3school.com.cn/tags/html_ref_canvas.asp
8.html設備支持的接口介紹:webaudio
9.其餘dom接口相關介紹:
1、dom能力監測處理
對於ie,咱們是十分痛恨的,佈局的時候,爲了兼容低級ie或者特殊瀏覽器佈局咱們要作hack處理,
一樣,js也是如此,咱們介紹的都是知足w3c的dom api,針對低級ie還有特殊瀏覽咱們要作兼容處理,由於運用標準的api是不支持的,好在不支持的都有替代api,咱們就能夠作兼容處理了!
事件中事件對象 event 的處理
html
<div id="fu">123</div>
js
window.onload=function(){ var fu=document.getElementById("fu"); fu.onclick=function(event){ alert(event.type); }; };
在高級瀏覽器,點擊彈出 click
經過ie6打開發現毫無反應:針對event對象,低級ie把event最爲window的event屬性返回去調用
兼容處理代碼
var event=event||window.event; 高級瀏覽器最後獲得event對象,低級瀏覽器不支持此調用,採用或後面的代碼
js的或處理,採用真假判斷機制,若是或前面爲真,有內容,被採用,後面被忽略:
測試代碼:
window.onload=function(){ var aa=null; var bb=123; var cc=aa||bb; alert(cc); var aa2=222; var bb2=333; var cc2=aa2||bb2; alert(cc2); };
第一次alert出123,由於aa爲空,採用後面,第二次輸出222,由於aa2爲真,有內容,後面被忽略
var event=event||window.event;
加入event能力檢測代碼實現:
window.onload=function(){ var fu=document.getElementById("fu"); fu.onclick=function(event){ var event=event||window.event; alert(event.type); }; };
完美輸出,針對低級ie,咱們此次不輸出 event的type,而是去輸出event.target去試一試
這這屬性將返回觸發事件的最小元素,咱們輸出他的innerHTML測試
window.onload=function(){ var fu=document.getElementById("fu"); fu.onclick=function(event){ var event=event||window.event; alert(event.target.innerHTML); }; };
我只是作了最簡單測試,就一個元素,彈出的固然就是裏面的123,咱們低級ie測試無翻譯,看來
event.target不被支持了,
2.事件中事件對象 event.target 的處理
對於低級ie已經無奈,咱們看對他的處理辦法
var target=event.target||event.srcElement
測試代碼:
window.onload=function(){ var fu=document.getElementById("fu"); fu.onclick=function(event){ var event=event||window.event; var target=event.target||event.srcElement alert(target.innerHTML); }; };
ok了,繼續工做,咱們不以直接添加事件的方式處理,經過監聽事件方法:
js代碼修改
window.onload=function(){ var fu=document.getElementById("fu"); fu.addEventListener("click",function(event){ var event=event||window.event; var target=event.target||event.srcElement; alert(target.innerHTML); },false); };
高級瀏覽器,監聽事件仍是沒問題的,測試低級ie,大哥仍是失靈
還要兼容,低級ie的事件監聽方法是:
object.attachEvent(on+type,function);
w3c是:
object.addEventListener(type,function,useCapture);
此次用||在處理一次,好吧,哭着也不行了,咱們經過函數的封裝來一次兼容處理
window.onload=function(){ var fu=document.getElementById("fu"); objeventadd(fu,"click",function(){ var event=event||window.event; var target=event.target||event.srcElement; alert(target.innerHTML); }); function objeventadd(obj,ev,fn){ if(obj.addEventListener){ obj.addEventListener(ev,fn,false); }else if(obj.attachEvent){ obj.attachEvent("on"+ev,fn); }; }; };
一個封裝函數,加上if處理,咱們也發現那個貨處理其實所有經過if也能夠的,不過能用||就用這個,代碼簡潔重要,總結處理代碼:
function objeventadd(obj,ev,fn){
if(obj.addEventListener){
obj.addEventListener(ev,fn,false);
}else if(obj.attachEvent){
obj.attachEvent("on"+ev,fn);
};
};
最重要的兼容算是解決了,咱們看其餘兼容問題:下面的我就直接列舉了
3.事件對象相對頁面座標位置兼容:
var evx=event.pageX||event.x
var evy=event.pageY||event.y
獲取事件對象,相對頁面的左側座標和頂部座標
event.clientX ,event.clientY 沒有兼容問題
除了相對頁面的座標,還能夠獲取相對添加事件元素的座標
event.layerX 事件對象相對元素的座標
event.layerY
4.事件對象阻止冒泡和默認行爲兼容:
組織冒泡
event.stopPropagation(); w3c
event.cancelBubble = true; 低級ie
阻止默認
event.preventDefault(); w3c
event.returnValue = false; 低級ie
5.滾輪事件onmousewheel兼容:
obj.onmousewheel = function(event) {
var event=event||window.event;
}; 除了火狐覺得
obj.addEventListener("DOMMouseScroll", function(event) {
var event=event||window.event;
}); 火狐
鼠標滾輪就是中間輪的事件
大部分的兼容處理都已經介紹完了,爲了下面的手機touch事件,咱們提早作一個組合事件的封裝處理:
依據鼠標按下,移動,擡起,咱們組合判斷鼠標是向那個方向移動了!
原理:三個事件均可以獲取相對頁面的惡座標,咱們把擡起是的座標與按下座標比較,就能夠得出鼠標一次組合行爲的方向,一次行爲,仍是要用到爲0和爲1的判斷,與前面例子的拖拽登陸框相似:
鼠標按下擡起放下判斷實例:
js:
window.onload=function(){ var pape=document.documentElement; var isd=0; var downx=null; var downy=null; pape.onmousedown=function(event){ isd=1; downx=event.clientX; downy=event.clientY; }; pape.onmousemove=function(event){ if(isd==1){isd=1; }else{}; }; pape.onmouseup=function(event){ if(isd==1){ var X = event.clientX - downx; var Y = event.clientY - downy; if ( Math.abs(X) > Math.abs(Y) && X > 0 ) { alert("右"); } else if ( Math.abs(X) > Math.abs(Y) && X < 0 ) { alert("左"); } else if ( Math.abs(Y) > Math.abs(X) && Y > 0) { alert("下"); } else if ( Math.abs(Y) > Math.abs(X) && Y < 0 ) { alert("上"); } else{ alert("原位"); }; isd=0; }else{}; }; };
相關:Math.abs(num) 獲取絕對值,參數是數字
咱們執行js,能夠判斷鼠標在頁面的從按下到擡起的方向!
2、移動端Touch事件
基本touch事件:
touchstart 觸摸開始,按下
touchmove 觸摸移動
touchend 觸摸離開
觸摸事件與咱們mouse三事件正好吻合,一樣,手機上沒有over這些特殊事件,咱們經常使用的也就是這三個,咱們看事件監聽方式:
1.直接添加;
obj.ontouchstart =function(event){}
obj.ontouchmove =function(event){}
obj.ontouchend =function(event){}
2.方法添加,即監聽添加,應爲移動端都是高級瀏覽器,webkit內核,不用考慮低級ie的兼容問題
obj.addEventListener("touchstart ", function(event) { });
obj.addEventListener("touchmove ", function(event) { });
obj.addEventListener("touchend ", function(event) { });
和咱們之前寫法同樣的,不過是此次用移動事件的名字而已
咱們要注意的是,觸摸事件的event對象所附有的一些屬性已經不一樣於pc事件,咱們列舉出來:
touch事件的新屬性 已有對應的正常屬性
event.targetTouches 獲得出發事件的手指集合(最小元素) event 獲得觸發事件的對象
event.targetTouches[0] .pageX 一個手指相對頁面的位置 event.pageX 事件相對頁面的位置
event.touches 獲取全部touch事件觸發對象,touch不一樣於click這些事件,鼠標事件只能有一個,touch會有多個,一個屏幕能夠放幾個手指
event.Touches[0] .pageX
咱們知道,手指放在手機上,回不經意出發不少默認行爲,咱們爲了js好的執行,須要調用時,阻止默認行爲:
event.preventDefault(); 和正常相同
咱們修改上面案例代碼也就能夠檢測觸摸方向了!
3、實戰開發
學了這麼多dom的接口,咱們須要作一些例子了
1.全屏漂浮廣告: (屬性處理)
改變廣告標籤的left和top樣式
須要接口:
setInterval() clearInterval() 間隔處理,不斷修改left和top實現移動
ele.offsetLeft ele.offsetTop 獲取當前位置的eeft和top
ele.style.left ele.style.top 對left和top作修改賦值
if(){}else{} 邊界判斷,不能超出屏幕
function name(){} 配合間隔函數的函數定義
document.documentElement.clientHeight document.documentElement.clientWidth 獲取頁面寬高,作衡量值
html:
<div id="fu" style="position:absolute; left:0px;top:0px; background:#ffa;width:200px;height:200px; ">123</div> <p style="height:1500px;"></p>
js:
window.onload=function(){ var fu=document.getElementById("fu"); var hengw=document.documentElement.clientWidth-200; var hengh=document.documentElement.clientHeight-200; var zx=1; var zy=1; var dong=setInterval(function(){ var eley=fu.offsetTop; var elex=fu.offsetLeft; eley=eley+zx*1; elex=elex+zy*1; if(eley>hengh){zx=-1;}; if(eley<0){zx=1;}; if(elex>hengw){zy=-1;}; if(elex<0){zy=1;}; fu.style.top=eley+"px"; fu.style.left=elex+"px"; },10); fu.onmouseover=function(){ clearInterval(dong); }; fu.onmouseout=function(){ dong=setInterval(function(){ var eley=fu.offsetTop; var elex=fu.offsetLeft; eley=eley+zx*1; elex=elex+zy*1; if(eley>hengh){zx=-1;}; if(eley<0){zx=1;}; if(elex>hengw){zy=-1;}; if(elex<0){zy=1;}; fu.style.top=eley+"px"; fu.style.left=elex+"px"; },10); }; }
廣告自動移動,鼠標放中止,離開繼續移動,
eley=eley+zx*1;
咱們爲何要這樣處理,咱們知道在達到邊界作出的處理就是元素的屬性由+變成-變化值;
主要原理:a+b 和a-b 互相轉化,a是基礎值, b的變化值,咱們作出a+(c)b;z=一、z=-1;用可變化的c作處理
2.下拉框左右選項移動: (節點操做)
原理:咱們是把一側selsect下選中的option插入到另外一側select下,選中的option具備selected屬性,判斷是否有這個屬性,有的咱們就插入到另外一側,select設置multiple屬性,可多選,插入有可能插入多個,每次都要從頭遍歷一次去判斷哪一個要被插入;
須要接口:
id獲取selset
tagname獲取下面的惡optoon
for(){}遍歷處理
if(){}else{}判斷處理
ele.selected 檢測元素的selected屬性
ele.appendChild() 插入子節點
html:
<select id="left" style="width:100px;" size="5" multiple> <option>11111</option> <option>22222</option> <option>333333</option> <option>4444444</option> <option>5555555</option> </select> <span id="movel">右移動</span> <span id="mover">左移動</span> <select id="right" style="width:100px;" size="5" multiple> </select>
js:
window.onload=function(){ var left=document.getElementById("left"); var right=document.getElementById("right"); var leftoptions=left.getElementsByTagName("option") var rightoptions=right.getElementsByTagName("option") var movel=document.getElementById("movel"); var mover=document.getElementById("mover"); movel.onclick=function(){ var arrl=[]; for(var i=0;i<leftoptions.length;i++){ if(leftoptions[i].selected){ arrl.push(leftoptions[i]); }; }; for(var i=0;i<arrl.length;i++){ right.appendChild(arrl[i]); }; }; mover.onclick=function(){ var arrr=[]; for(var i=0;i<rightoptions.length;i++){ if(rightoptions[i].selected){ arrr.push(rightoptions[i]); }; }; for(var i=0;i<arrr.length;i++){ left.appendChild(arrr[i]); }; }; }
相關知識:arr.push(node) 數組的插入方法,官方叫進棧,就是把node插入到一個數組中,保存
按住ctrl+點擊選項,可移動多個
3.封裝處理 (dom優化)
經過類名查找的封裝
每次都要給標籤添加id去查找,這很不符合咱們的習慣,有人多能夠用querySelectorAll(),這個不就能夠了,和jq的選擇器差很少了,主要是不兼容低級ie
咱們打算找到指定類名,去處理它,就像這樣:selectclassname返回節點,好了咱們就用這個名字去封裝這個方法
一個html頁面會有不少的標籤:div span a等,還會各類件套,一樣不少不同的標籤會有一樣的類名
咱們羅列出相關的api:
document.getElementsByTagName("*") 能夠返回全部的標籤
node.className 能夠獲取標籤的類名
這好像能夠了,咱們想象一下,封裝一個函數,以查找的類名作參數,內部對全部標籤進行遍歷,加上對類名的判斷是否等於參數的值,建立一個數組,把等於參數值得標籤插入進去,最後返回!
相關接口:
for(){}
if(){}
arr.push() 插入到數組中
return obj 返回一個值
封裝好的函數:
function selectclassname(classname){
var allnode=document.getElementsByTagName("*");
var classnode=[];
for(var i=0;i<allnode.length;i++){
if(allnode[i].className==classname){
classnode.push(allnode[i]);
};
};
return classnode;
};
咱們既然寫了,就得作點東西演示一下,
html:
div class="aa">1</div> <div class="aa">1</div> <div class="bb">1</div> <div class="aa">1</div>
js:
window.onload=function(){ function selectclassname(classname){ var allnode=document.getElementsByTagName("*"); var classnode=[]; for(var i=0;i<allnode.length;i++){ if(allnode[i].className==classname){ classnode.push(allnode[i]); }; }; return classnode; }; var aa=selectclassname("aa"); for(var i=0;i<aa.length;i++){ aa[i].innerHTML="woshi"+i; }; }
還行,實現了每一個賦值
自身刪除的封裝
removeChild() 刪除字節點 node. removeChild(selnode)
刪除的操做是找到一個元素,在肯定他下面一個子元素,而後刪除,如今咱們找一一個元素,把自身刪除
咱們能夠經過parentnode獲得當前元素父元素,而後在調用刪除方法,這時候參數就是本元素了,
方法名就是remove()
function remove(node){
node.parentNode.removeChild(node);
};
html:
<div id="aa">1</div>
js:
window.onload=function(){ function remove(node){ node.parentNode.removeChild(node); }; var aa=document.getElementById("aa"); remove(aa); }
4.全選,取消全選
全選操做是對複選框的處理,其實就是對input的chenked屬性的設置和取消
html:
<br> <input type="checkbox" id="all"> 全選 <br><br> <div style="width:200px; border:1px solid #000;" id="box"> <input type="checkbox"> 1<br><br> <input type="checkbox"> 2<br><br> <input type="checkbox"> 3<br><br> <input type="checkbox"> 4<br><br> <input type="checkbox"> 5<br><br> <input type="checkbox"> 6<br><br> <input type="checkbox"> 7<br><br> </div>
js:
window.onload=function(){ var all=document.getElementById("all"); var box=document.getElementById("box"); var boxlists=document.getElementsByTagName("input"); all.onchange=function(){ //alert(all.checked) if(all.checked){ for(var i=0;i<boxlists.length;i++){ boxlists[i].checked=true; }; }else{ for(var i=0;i<boxlists.length;i++){ boxlists[i].checked=false; }; }; }; }
5.焦點圖實例
由於有不少的css樣式,我就粘貼整部分代碼了
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>愛</title> <style type="text/css"> *{ padding:0; margin:0} html,body{ height: 100%; width: 100%;} #box{ width: 228px; height: 229px; overflow: hidden;} #box a{display: none;} #box a.b{display:block;} .ddd{ position: relative;width: 228px; height: 229px;} #an{ position: absolute; bottom: 0px; left: 0; background-color: #daa;} #an span{ padding: 0 5px; cursor: pointer;} #an span.se{color:#fff;} #newc{height: 30px;line-height: 30px;width: 228px;overflow: hidden;} #newc span{display: none;height: 30px;} #newc span.c{display:block;} </style> </head> <body> <div class="ddd"> <div id="box"> <a href="" class="b">第1個圖</a> <a href="" >第2個圖</a> <a href="" >第3個圖</a> <a href="" >第4個圖</a> <a href="" >第5個圖</a> </div> <div id="an"> <span class="se">1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> </div> <div id="newc"> <span class="c">111111111111</span> <span>22222222222</span> <span>33333333333333</span> <span>44444444444444</span> <span>5555555555555</span> </div> </div> </body> <script type="text/javascript"> window.onload=function(){ //動畫自動播放 var oImg=document.getElementById('box').getElementsByTagName('a'); var i=0; var j=0; var k=0; var dong=setInterval(dongc,1500); function dongc(){ k++ if(k>=oImg.length) {k=-1;} else{for(j=0;j<oImg.length;j++) {if(oImg[j]==oImg[k]) {oImg[j].className="b" oSpan[j].className="se" newc[j].className="c" } else{oImg[j].className="" oSpan[j].className="" newc[j].className=""}}}} //鼠標放在數字上面 var oSpan=document.getElementById('an').getElementsByTagName('span'); var newc=document.getElementById('newc').getElementsByTagName('span'); for(i=0;i<oSpan.length;i++) {oSpan[i].onmouseover=function(){ clearInterval(dong); for(i=0;i<oSpan.length;i++) {if(oSpan[i]==this) {oImg[i].className="b" oSpan[i].className="se" newc[i].className="c" return i} else{oImg[i].className="" oSpan[i].className="" newc[i].className=""}}} oSpan[i].onmouseout=function(){ oSpan[i].className="" newc[i].className="c" k=i; dong=setInterval(dongc,1500);}} //結束了 } </script> </html>
6.隔行換色
主要是對tabel的處理,就是基數的tr一個顏色,偶數的一個顏色很是簡單的處理代碼
html:
<table id="tab"> <tr><td>111</td></tr> <tr><td>222</td></tr> <tr><td>333</td></tr> <tr><td>444</td></tr> <tr><td>555</td></tr> </table>
js:
window.onload=function(){ var tab=document.getElementById("tab"); var tr=tab.getElementsByTagName("tr"); for(var i=0;i<tr.length;i++){ if(i%2==0){ tr[i].style.background="#ffa"; }else{ tr[i].style.background="#ccc"; }; }; }
相關知識: 10%2 獲取 10除以2的餘數,餘數是0,商是5
總結:
到了最後,咱們發現例子都很是簡單,一是爲了學dom,二就是咱們尚未進入js的核心就是是語法es的學習,
咱們不能借用太多js語法作複雜處理東西,js語法es的相關使用:
var xx 建立變量
array 數組的使用,還有push() 插入數據
alert() 方法
function 的使用
for 循環
if 判斷
間隔函數 setInterval
Math對象 數學工具對象的abs()方法,返回絕對值
邏輯處理 或 ||
求餘數 %
布爾類型 true 和false
這一部分就到這裏了,目錄擴展的1,2,3就結束了,之後的內容會在後面介紹到
開源實例,你們能夠多多瞭解js 的處理: