Javascript应用开发实践指南

来源:互联网 发布:知乎电子书 kindle 编辑:程序博客网 时间:2024/05/29 15:29

Javascript应用实践开发指南

渐进增强

  • 渐进增强是一种分层设计网页的方式,其焦点是强调内容,用户与易访问性。
  • 将Javascript文件的引用置于页面末尾

Javascript语言的基本功能

  • 修改html文档
  • 与服务器通信
  • 存储数据

创建备用方案

编写可靠的Javascript代码 注意思路

if(typeof window.localStorage is supported){    //use localStorage}else{    //use normal cookies    }

函数

一个循环遍历family数组元素并用alert方法回显其信息的函数

function getFamilyName(){    var family=[    "Ann",    "Jane",    "Mary",    "Tim"    ];    var peopleCount=family.length;    if(peopleCount>0){        for(var i=0;i<peopleCount.length;i++){            var person=family[i];            if(person=="Tim"){             alert(person+',it's me!');        }else{            alert(person);        }    }}}getFamilyName();

匿名函数

匿名函数要比采用通常方式所定义的函数执行效率高,因为他们不需要被引用,可以立刻执行,这种函数只能使用一次,不能反复使用。

(function(){    })    ();

回调函数

如果某个函数被传入另一个函数中作为参数,那么就变成了回调函数,它既可以是用户自定义的函数,也可以是javascript中既有的原生函数。匿名函数也能充当回调函数。

window.addEventListener("load",function(){    alert(0);    },false);

方法

当函数被封装在对象之中,它就是方法。尽管有时那种深层嵌套于对象之中的函数会带来性能隐忧,不过以方法的形式来封装代码,在任何编程语言中都是一种既面向对象又极易维护的代码组织方式。

var getInformation={    "name":function(){        alert('get the name');    },    "checkTim":function(){        alert('check for tim');    }};window.addEventListenner("load",getInformation.names,false);window.addEventListenner("click",getInformation.checkTim,false);

事件

事件机制是用来处理用户反馈的,如果想要在页面中执行Javacsript代码,那么必须先触发某种类型的事件才行。
- onabort 图像加载被中断
- onblur 元素失去焦点
- onchange 用户改变域的内容
- onclick 鼠标点击某个对象
- ondblclick 鼠标双击某个对象
- onerror 当加载文档或图像时发生某个错误
- onfocus 元素获得焦点
- onkeydown 某个键盘的键被按下
- onkeypress 某个键盘的键被按下或按住
- onkeyup 某个键盘的键被松开
- onload 某个页面或图像被完成加载
- onmousedown 某个鼠标按键被按下
- onmousemove 鼠标被移动
- onmouseout 鼠标从某元素移开
- onmouseover 鼠标被移到某元素之上
- onmouseup 某个鼠标按键被松开
- onreset 重置按钮被点击
- onresize 窗口或框架被调整尺寸
- onselect 文本被选定
- onsubmit 提交按钮被点击
- onunload 用户退出页面


操作文档对象模型

  • getElementById
  • getElementsByTagName:该方法返回一种名为NodeList的DOM对象,它是一个节点集合,有了NodeList对象,还需检查其长度,可以确保该值在脚本的有效范围内。从NodeList中获取一个节点有两种方法:item方法和数组下标。
if(document.getElementsByTagName('p').length>0){    document.getElementsByTagName('p').item(0);    document.getElementByTagName('p')[0];}
  • getElementsByClassName
  • querySelector():只返回匹配的第一个元素
  • querySelectorAll():返回的是NodeList
document.querySelectorAll(".dropcap",".huge");

处理属性节点
- getAttribute
- setAttribute
- removeAttribute
- hasAttribute
处理文本节点并修改其内容
- innerHTML
遍历DOM
- parentNode
- previousSibling
- nextSibling
- firstChild
- lastChild
在DOM中动态地添加和移除节点
- createElement
- createTextNode
- appendChild
- removeChild

var p=document.createElement('p');var text=p.createTextNode('Hello World!');targetArea.appendChild(text);targetArea.remove(text);

javascript数据存储

  • 变量
  • 字符串
  • 数值:数值不带引号
  • Boolean
  • 数组:数组下标从0开始,数组可以容纳各种类型的元素,字符串,数值,对象,其他数组,表达式,或布尔值

数组对象的方法使用

  • join
  • slice
  • shift unshift
  • pop
  • concat
  • sort

变量,函数及循环

  • 匿名函数:每个函数内部所定义的变量,都不能在那个函数外面使用。匿名函数有一个优势,若是把某段代码包裹到匿名函数中,则那些原本会落入全局作用域中的变量,现在就全都被局限在该匿名函数内部了。
(function(){    var greeting="Hello Tim";    alert("in scope:"+greeting);    })();    alert("out of scope:"+typeof(greeting));
  • 回调函数:当你用某个函数调用另一函数时,后者就叫回调函数,回调函数与普通函数一样,只不过它是在别的函数中执行。回调函数非常适合用于将某个功能划分为不同的层次,以提升代码的可复用性。
function sayHello(message){    alert(message);    }    (function(){        var greeting="Welcome",        exitStatement="Ok,please leave.";        sayHello(greeting);        sayHello(exitStatement);        })

返回数据

  • 将返回值传给另一个函数
function sayHello(greeting,exitStatement){    var newGreeting=greeting+"!",         newExitStatement=exitStatement+"!";         return [newGreeting,newExitStatement];    }    function start(polite,rude){        var greeting=sayHello(polite,rude)[0],             exit=sayHello(polite,rude)[1];             alert(greeting+"---"+exit);        }        start("thankyou","you thiink");

一个简单的通讯录

var contacts={    "address":[    {        "name":"Mary",        "email":"mary@example.com"    },    {        "name":"Jane",        "email":"jane@example.com"    },    {        "name":"linda",        "email":"linda@example.com"    }    ]};(function(){    var object=contacts.address,         contacts_count=object.length;         target=document.getElementsByTagName('body')[0];         i;         if(contacts_count>0){             for(i=0;i<contacts.length;i++){                 var item=object[i];                 var name=item.name;                 var email=item.email;                 target.innerHTML+=' <p><a href="mailto:'+email+' ">'+name+'</a></p>';                 }             }    }) ();

事件监听器

  • 在IE浏览器中添加事件监听器时所需的备用代码
var btn=document.getElementById("btn");if(btn.addEventListener){    btn.addEventListener("click",function(){        alert("click the button");        },false);}else{    element.attachEvent("click",function(){        alert("click the button");        });        }
  • 解除事件绑定
if(btn.removeEventListener){    btn.removeEventListener("click",alertMessage,false);}else{    btn.detachEvent("click",alertMessage);}
  • click事件
  • focus blur事件:focus事件与提升网站的易访问性有关,以下三种方式都可以激活输入框 1.用鼠标点击它 2.用鼠标点击它旁边的标签 3.通过Tab键切换到它
  • change事件
  • mouseover mouseout事件
  • submit事件
  • keydown keypress keyup事件

目前为止代码总结

(function(){    var contacts={    "address":[    {        "name":"Mary",        "email":"mary@example.com"    },    {        "name":"Jane",        "email":"jane@example.com"    },    {        "name":"linda",        "email":"linda@example.com"    }    ]};var searchForm=document.getElementById('search-form'),     searchField=document.gteElementById('search-form'),     getAllButton=document.getElementById('get-all'),     count=contacts.address.length;     target=document.getElementById('output');var addr={    search:function(event){        var searchValue=searchField.value,              i;              event.preventDefault();              target.innerHTML="";              if(count>0&&searchValue !==""){                  for(i=0;i<count;i++){                      var obj=contacts.address[i],                            isFound=obj.name.indexOf(searchValue);                            if(isFound !==-1){                                target.innerHTML+='<p>'+obj.name+'</p>';                                }                            }                      }                  },                  getAllContacts:function(){                      var i;                      target.innerHTML="";                      if(count>0){                          for(i=0;i<count;i++){                              var obj=contacts.address[i];                              target.innerHTML+='<p>'+obj.name+'</p>';                          }                      }                  },                  getActiveSection:function(){                      this.parentNode.setAttribute("class","active");                  },                  removeActiveSection:function(){                      this.parentNode.removeAttribute("class");                  },                  addHover:function(){                      searchForm.setAttribute("class","hovering");                  },                  removeHover:function(){                      searchForm.removeAttribute("class");                  }                  };serachField.addEventListener("keyup".addr.search,false);searchField.addEventListener("focus",addr.setActiveSetion,false);searchFiled.addEventListener("blur",addr.removeActiveSetion,false);getAllButton.addEventListener("click",addr.getAllContacts,false);searchForm.addEventListener("mouseover",addr.addHover,false);searchForm.addEventListener("mouseout",addr.removeHover,false);searchForm.addEventListener("submit",addr.search,false);              }) ();

触摸及方向变换事件

  • touchstart和touchend
  • touchmove
  • orientationchange

Ajax

  • 创建XMLHttpRequest对象:跨浏览器兼容性问题
if(window.XMLHttpRequest){    xhr=new XMLHttpRequest();}else if(window.ActiveXObject){    xhr=new ActiveXObject("Msxm112.XMLHTTP");}
  • GET与POST的性能对比
    获取信息时就用get,提交信息就用post
    如果要以Ajax调用传输敏感数据,则应通过post方式,若数据不敏感,则最好采用get方式
    但是大多数情况下,get请求的性能都比post好
  • open方法:该方法并不做任何实际的事情,只是收集必要的信息,为待执行的调用语句做准备工作而已。
    3个参数表示传输调用请求所用的方式,带获取的文件或URL,是否以异步方式调用脚本的boolean标志(大多设置为ture,异步调用),此外还有两个可选参数,用户名和密码
  • send方法:在通过open()方法把Ajax调用所需的数据都准备好了,就可以用send()方法送出这些数据和请求,在之后的等待过程中,不断查询readyState属性。
  • 接受服务器传回的数据
    提出请求后,Ajax队对象会开放一个新的readyState属性,同时还会有一个名为readyStatechange的事件与之关联。
  • readyState属性5个值
    0——open方法尚未被调用
    1——open方法已被调用,send方法未被调用
    2——send方法已被调用,请求已送出
    3——开始回传服务器的应答
    4——请求已完成
  • 服务器状态
    404——页面未找到
    304——文档内容自上次发送请求以来并未改变
    500——内部服务器错误
    200——服务器正常
  • 服务器响应
    除了readyState与status之外,Ajax对象也会将调用者所请求的数据作为属性返回。根据开发者在通信时所选择的数据格式,返回的可以是字符串,也可以是XML。先找到Ajax对象,通过responseText和responseXML来获取。
  • 将Ajax调用封装为函数
function getHttpObject(){    var xhr;    if(window.XMLHttpRequest){        xhr=window.XMLHttpRequest();    }else if(window.ActiveXObject){        xhr=new ActiveXObject("Msxm12.XMLHTTP");    }    return xhr;}function ajaxCall(dataUrl,outputElement,callback){    var request=getHTTPObject();    outputElement.innerHTML="Loading";    request.onreadystatechange=function(){        if(request.readystate===4 && request.status===200){                        var contacts=JSON.parse(request.responseText);                        if(typeof callback==="function"){                            callback(contacts);                        }        }    }    request.open("GET",dataUrl,true);    request.send(null);}(function(){    var addr={        search:function(){            var output=document.getElementById("output");            ajax('data/contacts.json',output,function(data){                var searchValue=searchFiled.value,                      addrbook=data.address,                      count=addrbook.length,                      i;                       event.preventDefault();              target.innerHTML="";              if(count>0&&searchValue !==""){                  for(i=0;i<count;i++){                      var obj=addrbook.address[i],                            isFound=obj.name.indexOf(searchValue);                            if(isFound !==-1){                                target.innerHTML+='<p>'+obj.name+'</p>';                                }                            }                      }                  }                  searchForm.addEventListener("submit",addr.search,false);                  }) ();

javascript开发模式-

  • 函数与闭包模式
    该模型利用闭包将所有的内容封装成一个对象,并且在不暴露那个对象其他函数和局部变量的情况下,创建出一整套可以在整个应用程序中使用的公共API
<div id="controls">    <input  id="play" type="button" value="play" />    <input id="stop" type="button" value="stop"/></div>
var controls=function(el){    var audioControls=el,          playButton=document.getElementById("play"),          stopButton=document.gteElementById("stop");          playButton.addEventListener("click",play,false);          stopButton.addEventListener("click",stop,false);          function play(){              audioControls.setAttribute("class","playing");          }          function stop(){              audioControls.setAttribute("class","stoped");          }          return play,stop;  };  (function(){      var element=document.getElementById("controls"),            action=controls(element);            action.play();            action.stop();yg'      })

设置好事件监听器后,就声明了实际的play和stop函数,这两个函数都使用了那个保存了el参数的audioControls变量,此变量定义在函数之外,却在父对象controls内部。这个实例表明,定义在父对象里面的变量,其作用域可以延伸至同一对象中的其他函数内。
- 事件驱动模式:较前者更为直接,只需设置好函数,然后在事件监听器里调用它们即可

function play(){    this.parentNode.setAttribute("class","playing");}function stop(){    this.parentNode.setAttribute("class","stoped");}(function(){    var playButton=document.getElementById("play"),          stopButton=document.getElementById("stop");          playButton.addEventListener("click",play,false);          stopButton.addEventListener("click",stop,false);    }) ();
0 0
原创粉丝点击