JS原生系列-DOM篇(扩展)

自闭症网瘾萝莉.ら 提交于 2019-12-06 21:21:32

继续DOM的研究工作,我们扩展对dom api的学习!


1.介绍针对低级浏览器,能力的监测处理:

2.针对移动端,touch事件的介绍:

3.最后做几个网页实例!


4.ajax的介绍:ajax输出json格式文件 jsonp的介绍 xhr2的介绍

     http://www.w3school.com.cn/ajax/ajax_xmlhttprequest_create.asp 

5.cookie的介绍:设置cookie和删除cookie

6.html5 存储的介绍:web客户端存储(localStorage sessionsStorage) 缓存( cache manifest 文件)

7.html5中新元素如canvas,video、audio的api简单介绍

     http://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp

     http://www.w3school.com.cn/tags/html_ref_canvas.asp 

8.html设备支持的接口介绍:webaudio 

9.其他dom接口相关介绍:



一、dom能力监测处理

对于ie,我们是十分痛恨的,布局的时候,为了兼容低级ie或者特殊浏览器布局我们要做hack处理,

同样,js也是如此,我们介绍的都是满足w3c的dom api,针对低级ie还有特殊浏览我们要做兼容处理,因为运用标准的api是不支持的,好在不支持的都有替代api,我们就可以做兼容处理了!

  1. 事件中事件对象 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,可以判断鼠标在页面的从按下到抬起的方向!

二、移动端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();          和正常相同

我们修改上面案例代码也就可以检测触摸方向了!

三、实战开发

学了这么多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=1、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 的处理:

http://www.oschina.net/code/snippet_2352644_49815 

http://www.oschina.net/code/snippet_2352644_49974 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!