《Head First Ajax》读书笔记

  1. 告诉浏览器一旦加载页面就运行初始化js函数initPage,则

     window.onload=initPage;
    
  2. Ajax应用必须要求JavaScript。

  3. 对字符串进行转码,使之成为合法的url。使用

     escape(url);
    

    即可完成转码,例如

     escape("calculate 1+2*3/4 & 5^5>1");
    

    输出

     calculate%201+2*3/4%20%26%205%5E5%3E1
    
  4. 得到一个请求对象(兼容所有浏览器)

     function createRequest(){
         try{
             request=new XMLHttpRequest();   //在Safari、Firefox、Opera中可以,但不支持IE
         }catch(tryMS){  //若是IE,则上述代码异常
             try{
                 request=new ActiveXObject("Msxml12.XMLHTTP");
             }catch(otherMS){
                 try{
                     request=new ActiveXObject("Microsoft.XMLHTTP");
                 }catch(failed){ //若都没有,则返回空
                     request=null;
                 }
             }
         }
         return request;
     }
    
  5. 注意,上述工具函数中,定义的request是没有var修饰的。JavaScript规定,如果在函数中没有var修饰的变量则成为全局变量,当该函数至少运行一次后,你可以在全局范围内找到一个叫做request的变量。另一方面,考察下面代码

     function get(){
         a={name:"Tom"}
         return a;
      } 
      var b=get();
      var c=get();
      console.log(b===a); //false
      console.log(c===a); //true
    

    但是

     function get(){
         a={name:"Tom"}
         return a;
      } 
      var b=get();
      var c=get();
      var d=get();
      console.log(b===a); //false
      console.log(c===a); //false
      console.log(d===a); //true
    

    这似乎说明了,如果函数中声明一个全局对象并返回,则最后一个调用该函数的变量得到该全局对象的引用,而其他调用该函数的变量则得到副本

  6. 一个通常的请求流程:GET

     request=createRequest();
     var url="http://....?"+escape("A=a&B=b"); //编码数据
     request.open("GET",url,true);   //true代表是异步过程
     request.onreadystatechange=callback; //设置回调函数(直接写函数名即可)
     request.send(null);
    

    如果是一个POST方法,则

     request=createRequest();
     var url="http://....";  //不需要编码数据,不需要?问号
     request.open("POST,url,true);   //true代表是异步过程
     request.onreadystatechange=callback; //设置回调函数(直接写函数名即可)
     data=escape("A=a&B=b"); //数据放这里
     request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");   //非常重要,设置首部,表示数据是"key1=value1&key2=value2"形式。
     request.send(data); //发送数据
    
  7. 注意上面的onreadystatechanged的属性,它是用来设置回调函数。每次服务器响应,就会改变请求对象request的readyState属性,触发回调函数,这就是说,此处的回调函数可能不止调用一次。我们希望当服务器处理完全后再执行回调逻辑,那么就要在回调函数中判断readyState的值,只有当它等于4时才表示服务器处理完全。

    回调函数看起来像是这样

         function callback(){
             if(request.readyState==4&&request.status==200){
                 .....
             }
         }
    

    上述中,readyState属性等于4代表服务器处理完全,status属性200代表OK,服务器认为一切正常。

    • readyState=1 请求准备好可以发送(初始)
    • readyState=2 服务器正在处理
    • readyState=3 部分数据已下载到请求对象中,但是还没有完全弄好还不能使用
    • readyState=4 请求处理完毕,响应数据可以开始使用
  8. 服务器返回的数据都存储在request.responseText中,同时,如果服务器发回的是XML的数据,则request.responseXML中会存储一个XML的DOM(当然在request.responseText也有XML的朴素文本)

  9. 使用CSS控制页面的变化,即用JavaScrip来动态改变元素的class,使得CSS选择器可以匹配并更改元素的显示

     document.getElementById('element').className="CSS_Class_Name";
    
  10. 禁用按钮

     document.getElementById('button').disabled=true;
    
  11. 获取输入焦点

     document.getElementById('button').select();
     document.getElementById('button').focus();
    
  12. 元素设置title属性,则当鼠标移动该元素上面的时候就会弹出悬浮框提示。

  13. 函数的this指向问题(仅在非IE时)。在下面的例子中,this指向不同的元素

     
     
     ....
     
    

    那么,点击两个按钮后,分别在控制台输出“b1”、“b2”字样。这是因为该函数被赋给不同的元素,那么他们的this指针也就指向相应元素的实体。

    但是,如果是(注意里myOnClick有括号,而上面的例子中没有括号),那么输出结果就不一定了,this此时不是指向该元素本身,我们会在下面看到。

  14. 在上一条中,因为document.getElementById('b1').onclick=myOnClick;,我们说b1这个元素是myOcClick函数的拥有者,所以其内的this指向b1元素。但是在如下语句中

     
    

    myOnClick内的指针将不再指向b1元素,因为此时它是调用者而不是拥有者。你可以看到很大的不同:myOnClick后面有括号。这就是说,其调用时,会把onclick这个字符串送入eval中计算直接执行,而不是调用click()本身。

  15. 函数的this指向问题(在IE时)。在IE中,哪怕下面的代码:

     
     
     ....
     
    

    其中myOnClick的this都不会指向具体某个元素,而是指向IE事件框架。为了能够获取点击的是哪一个元素,我们可以使用attachEvent、addEventListener提供的一个参数来取得。具体见后。

  16. 给元素指定多个触发函数(如oncick),则以最后一个为准。

  17. 在支持DOM LEVEL 2(如Mozilla的浏览器)的JavaScript中,可以给元素设置addEventListener,使得对于一个触发事件可以触发多个回调函数。

     document.getElementById("button1").addEventListener("click",callback,isCapture);
     document.getElementById("button1").addEventListener("mouseover",callback,isCapture);
    

注意第一个参数,事件没有on前缀关于这个函数的第三个说明,可以点击此文章来查看。

**注意!** 注册的事件的调用是随机的。你可能认为会按照addEventListener定义的顺序来执行的事件,有时候实验结果也确实是这样,但是这是不对的。它的顺序是不被保证的。
  1. 但是IE不支持DOM LEVEL 2,因此addEventListener不会在IE上生效。但是,IE提供了attachEvent方法

     document.getElementById("button1").attachEvent("onclick",callback);
    

    注意!第一个参数,事件名有on前缀

    其效果与下面等价

     document.getElementById("button1").addEventListener("click",callback,true);
    

    因此你可以看到,IE只支持事件冒泡(请查看此文章)。

  2. 由于IE的事件函数内部不支持this(它指向IE事件框架而不是被触发元素本身)。attachEvent、addEventListener提供了一个参数——一个Event类型参数,它有两个最重要的属性:

    • type 被触发的事件名,如“mouseover”、“click”
    • target 即被触发的对象本身

    但是,IE7传入的Event对象用srcElement来表示target。而更早版本的IE则使用window.srcElement来代替这个Event对象的srcElement。

    编写一个事件处理函数,最好避开this

    我们可以用下面的工具函数来综合上面的方法

         /*事件处理程序callback得到一个Event对象,使用这个
         工具函数来获得对应的被激发对象*/
         function getActivatedObject(e){
             var obj;
             if(!e){
                 //表示是早期的IE,它不传入e,而是用window
                 obj=window.event.srcElement;
             }else if(e.srcElement){
                 //IE7及之后的版本
                 obj=e.srcElement;
             }else{
                 //DOM LEVEL 2
                 obj=e.target;
             }
             return obj;
         }
    
  3. 每个节点都有一个parentNode节点,可以得到它的父节点,但它是只读的。appendChild(newNode)作用在父节点上,用以向父节点插入一个子节点,但是它是插到最后一个子节点之后。并且插入的子节点自动获得该父节点。

    • 使用parentNode可以读取父节点
    • 父节点使用childNodes可以获得子节点数组;
    • 子节点使用nextSibling或者previousSibling获得兄弟元素
  4. 在html页面上,所有内容都有相应的结点,包括空格。文本结点有nodeName属性,其值是#text,文本内容储存在nodeValue中;图片结点有nodeName属性,其值是img,等等。因此,想要的得到第一个结点,使用firstNode时要判断是不是文本结点,如果是判断是不是空白结点,如果是则使用nextSibling检测下一个。

  5. Math.floor(Math.random()*2000);获得0~1999之间的随机数。

  6. 创建一个属性:

     var attr=document.createAttribute("name","value");
    

    插入属性

     document.getElementById("...").setAttributeNode(attr);
    

    或者直接给结点设置属性:

     document.getElementById("...").setAttribute("name","value");
    
  7. 假设一个字串jsonString,它里面是JSON格式数据,那么可以使用如下JavaScript语句解析:

     var json=eval("("+jsonString+")");
    

    注意!必须用括号括起来,否则无法正确解析

    但是,使用eval存在安全隐患,则可以使用json网站提供json2.js的

     var json=JSON.parse(jsonString);
    
  8. 如下函数可以用来判断是不是数组

     function isArray(arr){
         if(typeof arr=='object'){
             var isArray=arr.constructor.toString().match(/array/i);
             return isArray!=null;
         }
         return false;
     }

你可能感兴趣的:(《Head First Ajax》读书笔记)