《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. 注意上面的<code>onreadystatechanged</code>的属性,它是用来设置回调函数。每次服务器响应,就会改变请求对象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. 服务器返回的数据都存储在<code>request.responseText</code>中,同时,如果服务器发回的是XML的数据,则<code>request.responseXML</code>中会存储一个XML的DOM(当然在<code>request.responseText</code>也有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. 函数的<code>this</code>指向问题(仅在非IE时)。在下面的例子中,this指向不同的元素

     <button type="button" id="b1"> 按钮1 </button>
     <button type="button" id="b2"> 按钮2 </button>
     ....
     <script type="text/javascript">
         function myOnClick(){
             console.log(this.id);
         };
         document.getElementById('b1').onclick=myOnClick;
         document.getElementById('b2').onclick=myOnClick;
     </script>
    

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

    但是,如果是(注意里myOnClick有括号,而上面的例子中没有括号)<code><button type="button" id="b1" </code>onclick="myOnClick()"<code>> 按钮1 </button></code>,那么输出结果就不一定了,this此时不是指向该元素本身,我们会在下面看到。

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

     <button type="button" id="b1" onclick="myOnClick()">按钮</button>
    

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

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

     <button type="button" id="b1"> 按钮1 </button>
     <button type="button" id="b2"> 按钮2 </button>
     ....
     <script type="text/javascript">
         function myOnClick(){
             console.log(this.id);
         };
         document.getElementById('b1').onclick=myOnClick;
         document.getElementById('b2').onclick=myOnClick;
     </script>
    

    其中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前缀关于这个函数的第三个说明,可以点击<a href="http://www.jianshu.com/p/37c50041783b" title="关于JavaScript的addEventListener第三个参数的注记">此文章</a>来查看。

**注意!** 注册的事件的调用是随机的。你可能认为会按照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只支持事件冒泡(请查看<a href="http://www.jianshu.com/p/37c50041783b" title="关于JavaScript的addEventListener第三个参数的注记">此文章</a>)。

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

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

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

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

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

         /*事件处理程序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节点,可以得到它的父节点,但它是只读的。<code>appendChild(newNode)</code>作用在父节点上,用以向父节点插入一个子节点,但是它是插到最后一个子节点之后。并且插入的子节点自动获得该父节点。

    • 使用parentNode可以读取父节点
    • 父节点使用childNodes可以获得子节点数组;
    • 子节点使用nextSibling或者previousSibling获得兄弟元素
  4. 在html页面上,所有内容都有相应的结点,包括空格。文本结点有<code>nodeName</code>属性,其值是<code>#text</code>,文本内容储存在<code>nodeValue</code>中;图片结点有<code>nodeName</code>属性,其值是<code>img</code>,等等。因此,想要的得到第一个结点,使用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;
     }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 个人博客:https://yeaseonzhang.github.io 花了半个多月的时间,终于又把“JS红宝书”...
    Yeaseon阅读 1,720评论 2 23
  • 一、JS前言 (1)认识JS 也许你已经了解HTML标记(也称为结构),知道了CSS样式(也称为表示),会使用HT...
    凛0_0阅读 2,752评论 0 8
  • 1.行级元素有哪些?块级元素有哪些?行级元素如何转换成块级元素? block元素的特点: 1.总在新行开始,2.高...
    我的天气很好啦阅读 1,521评论 2 9
  • 前端开发面试知识点大纲: HTML&CSS: 对Web标准的理解、浏览器内核差异、兼容性、hack、CSS基本功:...
    秀才JaneBook阅读 2,328评论 0 25
  • 知识就是成功和失败的经验!
    太阳_晴阅读 121评论 0 0