笔试题
HTML:超文本标记语言,专门编写网页内容的语言
XHTML:严格的HTML标准
DHTML:动态HTML技术,是HTML+CSS+JS的统称
XML:可扩展的编辑语言,标签名和属性名可自定义--!---json
<student>
     <name id="fbb"></name>
     <math></math>
</student>

JSON:javaScritpt Object Notation
     {"name":范冰冰,"math":91}

BOM和DOM
window对象:2个角色
1、代替了ES标准中的GLobal,充当全局对象
2、封装当前浏览器窗口的功能和属性--BOM


BOM:Browser Object Model--专门操作浏览器窗口的API
   包括:浏览器窗口的属性和功能
   缺点:没标准---兼容性差

DOM:Document Object Model--专门操作网页内容的APi
    包括:html网页中编写的一切内容和属性
    优点:有国际标准,所有浏览器几乎100%兼容
    Document其实不仅指网页,而是指一切自描述的结构化文档


DOM API 2大类
   1、核心DOM:通用API,既可以操作HTML文档,也可以操作XML文档
    优点:可以对文档内容做任何操作
    缺点:API操作繁琐

   2、HTML DOM:DOM Level2,提供了专门操作网页内容的简化版API
       但仅对复杂HTML元素进行简化
           优点:API简单
       缺点:不能完成所有操作,都需要和谐DOM补充

       开发:有限使用HTML DOM,再用核心DOM API补充

DOM tree
    网页的加载过程:
       Browser                            Server
    1、浏览器send request:=====>查找请求的.html页面
    2、创建Document对象<----.html<----返回response
    3、读取HTml内容在 document对象下搭建搭建DOM Tree
        JQuery

    4、请求外部css文件:-->查找请求的.css文件
                        <--.css<--返回response

    5、将样式设置到DOM Tree
        的节点对象上   
    *同时,计算对象间的大小和位置:layout(reflow)*
    生产Render Tree---加载完样式后的树
    6、浏览器绘制页面
       window.onload

根节点:document对象
Node类型:所有节点对象的父类型
  三大通用属性:
    1、nodeType:当前节点的类型-返回的是数字
          DOCUMENT_NODE:9;
      ELEMENT_NODE:1;
      ATTRIBUTE_NODE:2;
      TEXT_NODE:3;
    何时使用:判断获得的节点的类型时
    2、nodeName:节点名称
           document:"#document"
       ELEMENT:"全大写标签名"
       ATTRIBUTE:"属性名"
       TEXT:"#text"
       何时使用:判断获得的元素节点的标签名时
         if(obj.nodeName=="INPUT")
    3、nodeValue:节点值--对元素节点无效
          ATTRIBUTE:"属性值"
      TEXT:"文本内容"


DOM Tree 节点间关系
  1、父子关系:parentNode childNodes firstChild lastChild
  2、兄弟关系:previousSibling nextSibling
  问题1:除了parentNode外,其余都会受到看不见的空字符的影响
        空字符也是文本节点
  问题2:childNodes:返回NodeList类型的类数组对象
          包含了父节点下的所有直接子节点对象
      ***动态集合***仅包含节点对象的引用,不包含实际属性值!
      每次访问结合的属性时,都要重新查询DOM树

   遍历childNodes:
        效率低:for(var i=0;i<obj.childNodes.length;i++)
         后果:每循环一次,都要重新查询length的个数

        解决:for循环的第一部分缓存length的值
       for(var i=0,len=obj.childNodes.length;i<len;i++)


***递归遍历节点树
    递归调用:函数内部又调用了自己
    何时使用递归:遍历不确定层级深度的上下级机构时
    原理:在函数内部,调用任何函数,都会为新的函数调用创建
          新的EC,可实现一个函数,反复执行多项任务。

    深度优先遍历:优先遍历下级节点

    arguments.callee引用的是当前调用的函数对象
    何时使用:递归内部必须用callee属性调用当前函数
               不能直接用函数名。


    节点树:由所有节点组成的树结构
    元素树:仅由元素节点组成的树结构

             节点树               元素树
父节点:     parentNode        parentElementNode
子节点集合:     childNodes        children
第一个孩子:     firstChild        firstElementChild
最后一个孩子:     lastChild        lastElementChild
前一个兄弟:     previousSibling    previousElementSibling
后一个兄弟:     nextSibling        nextElementSlibling
  children  :IE8+
  其余:IE9+


  遍历API:2个
        NodeIterator:安装深度优先的原则向上或向下遍历节点
              每次只引用一个节点对象
    如何使用:2步
     1、创建迭代器对象:
      var iterator =document.createNodeIterator(
            开始的节点对象,
            遍历节点的类型//NodeFilter.SHOW_ALL
                     //NodeFilter.SHOW_ELEMENT
            null,false

                   }
     2、跳到下一个节点对象:var next=iterator.nextNode();
          如果没有下一个节点,就返回null
        
        退一步,返回上一个节点:
        var pre =iterator.previousNode();
        获得正在站的节点:iterator.refereceNode


    TreeWalker:自有遍历:保证基本深度优先功能的基础上
                  添加了向任意方向跳转的额外方法
    如何使用:和NodeIterator基本功能完全一样
    额外方法:parentNode(),firstChild(),lastChild()
              nextSibling(),previousSibling()

查找:2大类
   1、getXXX:4个
        按id查找1个元素对象
         var elem=document.getElementById("id值")
       
         按标签名查找多个子元素对象
            var nodeList=parent.getElementsByTagName("标签名")
           何时使用:获取某个父对象下指定子元素时使用    
                 屏蔽空文本的干扰
    
    
       按name属性查找多个子元素对象
         var nodeList=parent.getElementsByName("name属性名")
    
       按类名查找多个子元素对象:HTML5新增  IE9+
          var nodeList=parent.getElemntsByClassName("样式类名");

       何时使用:只查找一次时

    当前元素.innerHTML:获得当前对象的值

   2、Selector API  用CSS选择器选择元素---Jquery的核心
     2个:
     如果使用document调用Selector API,选择器作用范围是整个页面
     如果使用父元素对象调用selector API,选择器作用范围是父元素
          下所有子节点

        仅选择第一个符合条件的元素:
       var elem=parent.querySelector("选择器");
    
    选择所要符合条件的元素
       var elems=parent.querySelectorAll("选择器")
   
       强调:elems非动态集合:包含了完整Dom对象和属性

       何时使用:通过多级查找才能获得想要的元素时

笔试题
    getXXX vs  Selector API
    返回值:getXXX返回动态集合
           Selector API返回非动态集合
    效率:getXXX效率高
          Selector API效率低



修改元素的内容:3个
      1、innerHTML:获取或设置元素开始标签到结束
                   标签之间的HTML内容
      
      何时使用:只要获取或设置元素的内容时
      固定套路:2个
           1、清空子元素:parent.innerHTML="";
       2、批量替换子元素:


      和单独删除元素对象的效率差异:
           DOM Tree--->Render Tree
                      ↑
               layout(reflow)最耗时
            尽量少触发layout:增加和删除元素节点

      课堂练习中:option元素,selected属性表示是否被选中
                          可当做bool类型用

          遍历过程中可能减少元素个数时,都要从后向前遍历


    回顾:var arr=[1,2,3];
           var deleted=arr.splice(1.1);
                deleted数组,包含被删除的元素
            deleted[0]获得被删除的元素
    
    textContent:获取或设置开始标签到结束标签之间的文本内容
                 剔除了子标签,自动转换特殊符号为原文
          IE8:innerText

修改属性:
   核心DOM:凡是来自不带HTML开头的父类型中的属性和方法
   HTML DOM:凡是仅继承HTML开头的父类型中的属性和方法

   body--->HTMLBodyElement
        -->HTMLElement
***********↑HTML DOM***
*******↓核心DOM********
      ---->Element
        -->Node

    
获得元素属性值:3种---所有属性的值都是字符串
    1、var strValue=elem.getAttribute("属性名");
        何时使用:只要获取元素的指定属性的值

    2、var strValue=elem.attributes[i/"属性名"].value
                        // 属性集合    属性节点  属性值
      何时使用:遍历一个元素的所有属性时
    
    3、var StrValue=elem.getAttributeNode("属性名").value
                              //属性节点对象        属性值

    修改元素属性值:2种--所有属性的值都是字符串
    elem.setAttribute("属性名","属性值")
    elem.setAttributeNode(属性节点对象)
    

    移除元素的属性 2种
     1、elem.removeAttribute("属性名");
     2、elem.removeAttributeNode(属性节点对象);

    判断是否包含指定属性
    1、elem.hasAttribute("属性名")--->true,有;false ,没有


        5个词:attributes get/set/remove/hasAttribute
   
HTML DOM
  获取/修改属性:elem.属性名
  删除属性:elem.属性名=""
  判断:if(elem.属性名)


  ***Property vs Attribute
    Attribute是出现在html元素开始标签中的特性
             只能通过get/setAttriburte访问
     比如:a.getAttribute("href")

    Property是内存中对象的属性,专门通过.访问
    a.href


HTML标准属性:即是HTML元素的特性,同时又是内存中元素对象
              的属性

     自定义属性:html也可自定义属性
       li.setAttribute("age","25")===><li age="25"></li>
           只能用getAttribute("age");--->25
      
      
       li.age=25;==>仅存储在内存中,无法出现页面元素上
            只能用.获取
        elem.dataset.自定义属性名

    自定义属性,核心DOM和HTML DOM不通用
 


HTML5中自定义属性标准:
      1、所有自定义属性都要加data-前缀
      2、elem.dataset.自定义属性名//获取
                      //不用加data-


修改元素的样式:2处可改
   1、内联样式:都定义在元素的style属性中
    elem.style-->CSSStyleDeclaration类型的对象

       获取/设置元素的内联样式属性
      elem.style.属性名

      属性名:将css属性名去横线变驼峰

       问题:获取:只能获得内联样式中的属性,无法获取样式
       表中级联或继承来到外部属性
       
       修改样式:放在内联样式中的属性,优先级最高
                  覆盖所有外部的

       何时使用style:修改一个元素的样式时。
   
   
   2、样式表中的样式:
      1、获取计算后的样式:最终层叠应用到一个元素上的所有
          样式列表
      var style=getComputedStyle(elem)
      IE8:var style = elem.currentStyle
      
      if(elem.currentStyle){
         var style = elem.currentStyle
       }else{
          var style=getComputedStyle(elem)

       }
          何时使用:只要获取一个元素的属性时都要获取计算后的
                 样式
修改样式表中的样式
   1、样式表对象:<style></style>
          <link rel="stylesheet".../>

    获得样式表对象
         var sheet=document.styleSheets[i]
        sheet是CSSStyleSheet类型的对象
   2、css规则对象
         var rule=sheet.cssRules[i]
     rule是CSSStyleRule类型的对象
     rule对下还可继续包含cssRules集合
    
   3、获取/设置规则中的属性
          rule.style.属性名="属性值"


HTML DOM的Form元素
  找到表单对象:var form = document.forms[i/name]
  找到表单中的元素:var elem = form.elements[i/name]
             如果找到name属性的元素可简写为:form.name

 form对象的onsubmit事件,在提交之前自动触发,多用于验证所有
 form对象都有submit()方法:专用于手动提交表单



创建和删除节点
HTML DOM常用对象:Table Select Form


创建和删除节点:----核心DOM
  1、创建单个节点:3步
    1、创建指定名称的空节点对象
         var newElem=document.createElement("标签名")
    比如:var a = document.createElement("a");
            <a></a>

    2、设置新对象的关键属性
         比如:a.innerHTML="go to tmoooc";
           a.href="http://tmooc.cn";

      <a a.href="http://tmooc.cn">go to tmoooc</a>
    3、将a加入指定父元素下:3种方式
         1、追加:parent.appendChild(newElem)
     2、在之前插入:parent.insertBefore(newElem,已有元素)
     3、替换:parent.replaceChild(newElem,被替换的元素)


性能问题:单个创建或删除节点都会导致重新layout
解决:如果同时创建父元素和子元素,都要先创建父元素,再将所有
      子元素加入父元素中。最后将父元素整体加入页面
       
       如果父元素已经在页面上,就要将创建的平级元素加入到
       文档片段对象中


       创建多个平级节点:3步
         1、先创建文档片段对象
          文档片段:内存中临时存储多个子元素的存储空间
                     充当临时虚拟的父元素
               var frag=document.createDocumentFragment("XXX");

     2、创建多个子元素对象,暂时先加入到文档片段中
         var child1=document.createElement("XXX");
            frag.appendChild(child1);

         var child2=document.createElement("XXX");
             frag.appendChild(child2);

      3、将文档片段整体加入页面父元素中
           parent.appendChild(frag);

         强调:frag不会出现在页面。
     尽量少的使用layout 3种:display:none  批量操作、文档片段


       删除节点:var deletedNode=parent.removeChild(子节点)
                 只有父元素才有权删除子节点

         子节点删除自己:child.parentNode.removeChild(child);

 
HTML DOM常用对象: Table Select  Form

select:

    事件:onchange:选中项(值)改变时触发
    属性:select.selectedIndex:获得当前选中项的位置
          select.options:获得select下所有option对象
         将select.options.length=0,等效于清空所有的option


    方法:select.add(option)
          select.remove(index)

    Option:创建option,同时设置内容和value属性值
          var opt=new Option(innerHTML,value);
     固定套路:向select中增加一个option
          select.add(new Option(innerHTML[,value]));


     可以new的目前只学到,Option和img


     课堂练习:
         问题:html绑定事件 vs js动态绑定事件
     1、html绑定的其实是字符串:
          <select onchange="createSelct()"></select>
          function createSelct(){
                   this-->select
          }

          select.change=function(){
                
        eval("绑定字符串");=>createSelect();
            
 

          }

         html绑定this只能通过在html中显示传入
     如果不写,处理函数内部的this--》window

         2、js中动态绑定
         select.onchange=createSelect;
         执行select.onchange();
         处理函数内的this就指当前触发事件的元素对象本身。



Table对象
 属性:table.rows:获得所有tr对象
 方法:
      table.insertRow([index]);
      index不省略,会再index位置插入一行
      省略index,在table结尾追加一个新行
      
      table.deleteRow(index);删除index位置的行
      强调:删除行只能用行下标

TableRow对象
   属性:tr.cells获取当前行中所有td
   方法:
       var td = tr.insertCell(index);
       tr.deleteCell(index);
          删除格,必须用下标
      
Tablecell对象
   属性:td.cellIndex:获得td在当前行中的位置下标。



Form
    找到Form:var form=document.forms[i/name];
    找到元素 var elem=form.elements[i/name]
                      form.name

    
   方法:form.submit() form reset()
   事件;onsubmit:提交表单前都会自动触发
                 主要用于验证或取消提交(2个return)

   表单中的元素:elem.focus()使用代码让元素获得焦点
                 elem.blur()


   课堂练习:闭包的问题:
      1、在绑定事件处理函数的内部,尽量不要使用外部的变量
        一旦使用,就会形成闭包,后果被闭包保护的DOM对象无法
    从内存中真正删除---内存泄漏

    解决:在事件处理函数内部随找随用,用完自动释放

BOM:操作浏览器窗口的API
window对象:2个角色
  1、替代ECMAScript中的Global对象,充当全局对象
  2、封装浏览器软件/窗口的属性和功能-----BOM

 1、打开新链接的方式:4种
    1、在当前窗口打开,可后退
        html:<a href="url">xxx</a>
    js:[window.]open("url","窗口名"[,"窗口配置"]);
        open("url","_self")

    2、在当前窗口打开,不可后退
    js:javascript:location.replace("新URL")
    替换history中当前url,不新增history记录;

    3、在新窗口打开,可打开多个
        html:<a href="url" target="_blank">xxx</a>

    js: open("url","_blank")
       
    4、在新窗口打开,只能打开一个
        html:<a href="url" target="自定义窗口名">xxx</a>
                        window.name
         浏览器规定:内存中同名窗口对象只能出现一次
                 后出现的同名窗口会覆盖前一个
    js:open("url","自定义窗口名")

窗口大小和窗口的位置:
1、窗口大小:不带单位
       window.width/height窗口的宽和高
       window.innerWidth/innerHeight文档显示区的宽高

       修改窗口大小:2个方法:
        window.resizeTo(width,height);
    window.resizeBy(width的增量,height的增量);
 
2、窗口位置:窗口左上角距离显示器左上角的位置top和left
    移动窗口的位置:2个方法
      window.moveTo(left ,top)
      window.moveBy(left的增量,top的增量);

3、打开窗口时,设定新窗口的大小和位置
    窗口左上角距显示器左上角的位置top和left
    窗口宽度和高度width和height


定时器:按指定时间间隔反复执行同一任务
何时使用:只要按时间间隔反复执行任务

2种
  周期性定时器:按指定时间间隔反复执行同一任务
  如何定义定时器:3步
  1***每一次要执行的任务函数对象:
     任务函数的结尾,一般都要考虑临界条件和停止定时器
  2、启动定时器:timer=setInterval(taskFun,interval);
     强调:只要有可能定制定时器是,必须在启动时就保存定时器序号
  3、停止定时器:clearInterval(timer);timer=null;

call apply:调用时临时修改原函数的this,不创建新函数,且调用后this
            回复为window

bind:基于现有函数,复制一个新函数的副本,提前为新函数永久绑定this
       引用的对象


文本框 textarea中style属性resize:none表示页面的文本框不能拖动改变


navigator:保存浏览器软件属性和配置的对象
   判断cookie:cookieEnabled启用了,返回true;否则返回false
   cookie:在客户端硬盘持久存储某个网站当前用户个人信息的文件
   访问网站时,由网站或客户端浏览器创建,都保存在客户端硬盘
   请求该网站时,随request一起自动发到服务器
            服务器接到cookie,取出其中的值进行验证

   一个网站创建的cookie,只能访问自己网站时使用
   优点:持久存储个人数据,提高用户体验
   缺点:泄漏个人信息。

判断或查找插件:plugins,返回所有插件对象的集合
           判断是否包含:遍历插件集合,判断每个插件的name属性

   userAgent:获得浏览器基本信息(名字、版本)的字符串


BOM常用对象:history location
  history:当前窗口的历史记录栈
          保存了当前窗口本次打开后的url记录

 一个方法:history.go(n)
    history.go(-1):后退
    history.go(1):前进
    history.go(0):刷新
    history.go(-2):后退两步

location:当前窗口正在访问的url地址对象
  修改当前窗口的url地址:只要修改,立刻跳转
  location="url";
  location.href="url";
  location.assign("url");

  location.reload(ture/false);重新加载页面;
       true:无论页面请求后是否被更改,都重
              新向服务器请求新页面
       false:只有页面请求后被修改过,才重新
             请求服务器,如果未改变,就直接从缓存
         中获取
***事件:浏览器自动触发的或用户手动触发的元素状态的改变
  DOM Level2 Event标准:
  IE8自成体系
 
  事件处理函数:当事件发生时,自动调用的函数
       事件处理函数其实是对象的一个特殊属性,只能引用函数对象
   其实:on事件名

  如何绑定事件处理函数:3种
  1、在html元素开始标签中绑定:
     <elem on事件名="js语句"...

     比如:html: <button onclick="fun(this)"...

         其实:button.onclick=function(){
        eval("fun(this)");--->fun()
          }
       js:fun(btn){btn-->button}

     当事件发生时:button.onclick();

扩展:所有回调函数:事件处理函数和定时器都可以传入字符串的js
      语句作为参数

   但是强烈建议:自己使用匿名函数封装要执行的js语句

 2、js中动态绑定事件处理函数:2种做法
    1、一个事件处理函数只能绑定一个函数对象
        elem.on事件名=function(){this-->elem


    }
    事件触发时:elem.on事件名()

    问题:2个
    1、一个事件处理函数,只能绑定一个函数对象
    2、无法修改事件的触发顺序

***事件周期:从事件触发到各级时间执行完的全过程
DOM标准:3个阶段
    1、事件捕获:从window开始,由内向外,到目标元素结束
       记录每层元素的时间处理函数
    2、目标触发:触发目标元素的事件处理函数
    3、冒泡触发:由内向外,从目标元素的上级开始,到window结束
IE:2个阶段
  1、目标触发
  2、冒泡触发
  其中:目标元素:最初实际触发事件的元素


  2、js动态绑定,可为一个事件处理函数绑定多个函数对象
           还可控制事件触发的顺序

  DOM标准:
    elem.addEventListener("事件名",函数对象,true/false);
    其中:1、事件名不带on
        2、壳反复为统一事件绑定多个函数对象
    3、最后一个参数表示:是否在捕获阶段就提前触发
           默认为false,不会提前触发
           改为true,在捕获阶段提前触发
  IE8:elem.attachEvent("on事件名",函数对象)
 
  获取事件对象:
    什么是事件对象:事件触发时自动创建,封装了事件发生的元素
      和属性信息

      1、html中绑定的事件处理函数
          html中<elem on事件名="fun(event)"

      2、js中动态绑定事件时:
       DOM标准:事件对象会自动作为处理函数的第一个参数
       默认传入
       js中:elem.onclick=function(){
             arguments[0]-->event
         }


       事件触发时:elem.onclick()
       IE:event属性保存在window全局下
       事件触发时:全局window下的even属性自动获得事件对象


       兼容写法:var e=window.event || arguments[0];
                         //ie 8          DOM


      强调:不支持以html绑定的事件处理函数
      何时获得:只要希望获取事件的属性和触发事件的元素时,都要
      先获得事件对象,再从事件对象中读取需要的属性

  取消和利用冒泡:
     取消冒泡:
       DOM标准:e.stopPropagation();
       IE8:e.cancelBubble=true;
       兼容:if(e.stopPropagation){//DOM
                  e.stopPropagation();
          }else{//Ie8
             e.cancelBubble=true;
          }
     利用冒泡:
  ***优化:如果多个子元素定义了相同的事件处理函数
           建议仅在父元素定义一次事件处理函数,所有子元素共用

      为什么:每个事件绑定,在底层都是一个事件的链接对象
            绑定事件越多,链接对象消耗资源越大
        所以,尽量减少事件绑定的次数

      如何利用冒泡:核心:获取目标对象
        this的问题:随冒泡不断变化!事件在那个对象上触发 this
    就指代哪个对象

    解决:获取目标对象,始终指代最初触发事件的目标对象
          不随冒泡而改变

    如何获得目标对象:
       DOM标准:e.target
       IE8:e.srcElement
       兼容:var target=e.srcElement||e.target;
取消事件:
  1、在html中绑定事件处理函数:2个return
  2、DOM标准:e.preventDefault()
  IE:e.returnValue=false
 
  兼容 if(e.preventDefault){
        
            e.preventDefault()
    }else{
              e.returnValue=false

    }

建议:尽量使用js动态绑定事件处理函数