DOM2和DOM3

一,DOM变化
var supportDom2Core = document.implementation.hasFeature("Core","2.0");
var supportDOM3Core = document.implementation.hasFeature("Core","3.0");
var supportDOM2HTML = document.implementation.hasFeature("HTML","2.0");
var supportDOM2Views = document.implementation.hasFeature("Views","2.0");
var supportDOM2XML = document.implementation.hasFeature("XML","2.0");
1,针对XML命名空间的变化
  HTML不支持XML的命名空间,
  1)node类型中的变化
  DOM2级,node类型包含下列特定于命名空间的属性
  localName:不带命名空间前缀的节点名称
  namespaceURI:命名空间前缀的节点名称,不存在时为null
  prefix:命名空间前缀,不存在时为null
  使用了命名空间前缀时,nodeName = prefix + ":" + localName
  <s:svg xmlns:s="http://www.w3.org/2000/svg"></s:svg>
  s为prefix,namespaceURI为http://www.w3.org/2000/svg,localName为svg
  DOM3在此基础上添加了新的方法
  isDefaultNamespace(namespaceURI),在指定的namespaceURI是当前节点的默认命名空间的情况下返回true
  lookupNamespaceURI(prefix),返回给定的prefix的命名空间
  lookupPrefix(namespaceURI),返回给定命名空间namespaceURI的前缀prefix
  2)Document类型的变化
  DOM2级中document类型包含下列与命名空间相关的方法
  var SVG = document.createElementNS(namespaceURI,tagname),用给定的tagName元素名创建属于命名空间namespaceURI的新元素
  var att = document.createAttributeNS(namespaceURI,attributeName),用给定的特性名,创建属于命名空间namespaceURI的新特性
  var elems = document.getElementsByTagName(namespaceURI,tagName),返回属于namespaceURI命名空间的所有tagName元素
  只有文档中包含两个文档时,这些命名空间相关的方法才必须的
  3)Element类型的变化
  getAttributeNS(namespaceURI,localName),取得属于namespaceURI命名空间,且名为localName的属性
  getAttributeNodeNS(namespaceURI,localName),取得属于namespaceURI命名空间,名为localName的属性节点
  getElementsByTagName(namespaceURI,tagName),取得命名空间,tagName元素的NodeList节点
  hasAttributeNS(namespaeURI,localname),确定当前元素在当前的命名空间中是否有localName的特性
  removeAttributeNS(namespaceURI,localName),移除namespaceURI命名空间的localName特性
  setAttributeNS(namespaceURI,qualifiedName,value),设置命名空间namespaceURI中的名为qualifiedName的特性的值为value
  setAttributeNodeNS(attribute),设置命名空间namespaceURI中的特性节点
  4)NamedNode类型的变化
  getNamedItemNS(namaspaceURI,localName),取得属于命名空间namespaceURI且名为localName的特性的项
  removeNamedItemNS(namespaceURI,localName),移除属于命名空间namespaceURI且名为localName的特性项
  setNamedItemNS(node),添加node,这个节点已经事先指定了命名信息
2,其他方面的变化
  1)DocumentType的变化
  新增三个属性,publicId,systemId,internalSubset
  前两个表示文档声明中的两个信息段
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  document.doctype.publicId = "-//W3C//DTD HTML 4.01//EN"
  document.doctype.systemId = "http://www.w3.org/TR/html4/strict.dtd"
  internalSubset用于访问文档声明中额外定义
  2)Document类型的变化
  importNode(),从一个文档中取得一个节点,放到另一个文档中,成为另一个文档结构的一部分
  接收两个参数,另一个文档中的目标节点,和一个是否复制其子节点的布尔值
  var newNode = document.importNode(antherNode,true);
  document.body.appendChild(newNode);
  defaultView属性,指向拥有给定文档的窗口,IE中等价的属性为parentWindow
  确定文档的归属窗口,var parentWindow = document.defaultView || document.parentWindow;
  DOM2核心,为document.implementation对象添加了两个新方法,
  createDocumentType(),用于创建新的documenType节点,接收三个参数,文档类型名称,publicId,systemId
  var doctype = document.implementation.createDocumentType("html","-//W3C//DTD HTML                     4.01//EN","http://www.w3.org/TR/html4/strict.dtd");
  createDocument(),用于创建新的文档,接收三个参数,针对文档中元素namespaceURI,文档元素的标签名,新文档的文档类型
  var doc = document.implementation.createDocument("","root",null);
  DOM2级html也为document.implementation对象添加了新方法
  createHTMLDocument(),用于创建一个完整的HTML文档,包括<html>,<head>,<title>,<body>元素
  只接收一个参数,即创建文档的标题title元素中的字符串,返回新的html文档
  var htmlloc = document.implementation.creatHTMLDocument("my doc");
  3)Node类型的变化
  isSupported(),用于确定当前节点拥有什么能力,接收两个参数,版本名和版本号
  DOM3级引入两个辅助比较节点的方法isSameNOde(),isEqualNode(),都接收一个参数,在传人节点和引用节点相同和相等时返回true
  setUserData(),将数据指定给节点,接收三个参数(设置的键,实际的数据,和处理函数)
  处理函数接收5个参数,表示操作类型的值(1表示复制,2表示导入,3表示删除,4表示从命名),数据键,数据值,源节点,和目标节点
  通过getUserData(),传人相同的键获取设置的值

  var div = document.createElement("div");
  div.setUserData("name","Nicholas",function(operation,key,value,src,dest){
    if(operation == 1){
      dest.setUserData(key,value,function(){});
    }
  });
  var newDIv = div.cloneNode(true);
  alert(newDIv.getUserData);

  4)框架的变化
  框架HTMLFrameElement和内联框架HTMLIFrameElement
  属性contentDocument属性包含一个指针,指定表示框架内容的文档对象
  IE中等价的属性为contentWindow属性
  var iframe = iframe.contentDocument || iframe.contentWindow.document
二,样式
var supportsDOM2CSS = document.implementation.hasFeature("CSS","2.0");
var supportsDOM2CSS2 = document.implementation.hasFeature("CSS2","2,0");
1,访问元素的样式
  css中的样式与javascript的样式名一一对应
  1)DOM样式属性和方法
  DOM2级样式规范给style对象定义了属性和方法
  cssText:通过它能访问到style特性中的css代码
  length:给定元素的css属性的数量
  parentRule:css信息的cssRule对象
  getPropertyCSSValue(propertyName):返回包含给定属性值的cssRule对象
  getPropertyPriority(propertyName):如果给定属性使用了!improtant设置,返回"important",否则返回空字符串
  getPropertyValue(propertyName):返回给定属性的字符串
  item(index):返回给定位置的css属性的名称,通过length一一获取,可以使用[]方法
  removeProperty(propertyName):移除给定属性
  setProperty(propertyName,value,priority):将给定属性设置为相应的值,并加上优先权标志(improtant)
  使用getPropertyCSSValue(propertyname),返回一个CSSValue对象,包含两个属性cssText和cssValueType
  cssText属性的值与getPropertyvalue()返回值相同,属性值的字符串值,cssValueType属性是一个数值常量(0表示继承的值,1表示基本的值,2表示值列     表,3表示自定义的值)
  2)计算的样式
  style对象只能获取style属性的样式信息,不能获取从其他样式表折叠而来的样式信息
  DOM2级增强了document.defaultView,提供了getComputedStyle()方法,接收两个参数,要取得计算样式的元素和一个伪元素字符串(如:after),不需要设     为null
  返回一个CSSStyleDelaration对象,包含当前元素的所有计算的样式
  var computedStyle = document.defauleView.getComputedStyle("div1",null);如此就可以获取div1元素的所有外部计算样式
  IE中等价的属性currentStyle 是CSSStyleDeclaration的实例
  var computedStyle = document.currentStyle;
  所有的计算的样式都是只读的,不能修改计算后样式对象中的CSS属性
2,操作样式表
  CSSStyleSheet类型表示样式表,
  var supportsDOM2StyleSheets = document.implementation.hasFeature("StyleSheets","2.0");
  CSSStyleSheet继承自StyleSheet,StyleSheet可以作为一个基础接口来定义非CSS样式表,从StyleSheet接口继承而来的属性如下
  disabled:表示样式表是否被禁用的布尔值,是可读写的,可以禁用设为true
  href:如果样式表通过link添加的,则值为样式表的URL,否则为null
  media:当前样式支持的所有媒体类型的集合,也有一个length属性,通过item或[]获取每一项,如果集合为空,适用于所有媒体,IE中media反映link和style   标签media特殊值的字符串
  ownerNode:指向拥有当前样式表的节点的指针,样式表可以通过link或style添加,如果是其他样式通过@import导入的,为null,IE不支持
  parentStyleSheet:当前样式通过@import导入时,这个属性是一个指向导入它的样式表的指针
  title:ownerNode中title属性的值
  type:表示样式表类型的字符串,对应css样式来说,为text/css
  cssRules:样式表中包含的样式规则的集合
  ownerRule(index):如果样式通过@import导入,包含一个指针,指向导入的规则,否则为null,IE不支持
  deleteRule(index):删除cssRules集合中指定位置的规则,IE中等价的方法removeRule()方法
  insertRule(rule,index):向cssRules集合中指定的位置插入rule字符串,IE中等价的方法addRule()方法
  应用与文档的所有样式表是通过document.styleSheets集合来表示的,通过length属性来获知文档中样式表的数量通过[]和item()获取每一项
  直接通过link或style元素取得CSSStyleSheet对象,DOM规定了sheet属性,IE中等价的styleSheet属性
  function getStyleSheet(element){return element.sheet || element.styleSheet;}
  var sheet = getStyleSheet(document.getElementsByTagName("link")[0]);
  1)CSS规则
  CSSRule是一个供其他类型继承的基类,最常见的就是CSSStyleSheet类型,表示样式信息,包括下列属性
  cssText:返回整条规则对应的文本,IE不支持,各浏览器支持情况不同
  parentRule:如果当前规则是导入的规则,此属性引用导入规则,否则这个值为null
  parentStyleSheet:当前规则所属的样式表,IE不支持此属性
  selectorText:返回当前规则的选择符文本
  style:一个CSSStyleDeclaration对象,通过它设置和获取特性的样式表
  type:表示规则类型的常用类型
  2)创建规则
  insertRule(),添加新规则,接受两个参数,规则文本和表示插入规则的索引
  sheet.insertRule("body{}",0);
  IE中等价的方法addRule()
  sheet.addRule("body","background-color:silver",0);
  实现兼容

  function insertRule(sheet,selectorText,cssText,position){
    if(sheet.insertRule){
      sheet.insertRule(selectorText,"{" + cssText + "}",position);
    }else if(sheet.addRule){
      sheet.addRule(selectorText,cssText,position);
    }
  }

  3)删除规则

  deleteRule(),接收一个参数,要删除的规划的位置
  IE中等价的方法,removeRule(),使用方法相同
  function deleteRule(sheet,index){
    if(sheet.deleteRule){
      sheet.deleteRule(index);
    }else if(sheet.removeRule){
      sheet.removeRule(index);
    }
  }

3,元素大小
  1)偏移量
  offsetHeight:元素在垂直方向上占用的空间大小,包括元素的高度,水平滚动条的高度,上下边框的高度
  offsetWidth:元素在水平方向上占用的空间大小,包括元素的宽度,垂直滚动条的宽度,左右边框的高度
  offsetLeft:元素左外边框至包含元素的左内边框之间的像素距离
  offsetTop:元素上外边框至包含元素的上内边框之间的像素距离
  offsetParent:包含元素的引用

  function getElementLeft(element){
    var actualLeft = element.offsetLeft;
    var current = element.offsetParent;
    while(current != null){
      actualLeft += current.offsetLeft;
      current = current.offsetParent;
    }
    return actualLeft;
  }
  function getElementTop(element){
    var actualTop = element.offsetTop;
    var current = element.offsetParent;
    while(current != null){
      actualTop += current.offsetTop;
      current = current.offsetParent;
    }
    return actualTop;
  }

  2)客户区大小
  是指元素内容及其内边距所占据的空间大小
  clientWidth:元素内容的宽度和左右内边距宽度
  clientHeight:元素内容的高度和上下内边距宽度
  确定浏览器视口的大小

function getViewport(){
  if(document.compatMode == "BackCompat"){
    return {
      document.body.clientWidth;
      height:document.body.clienHeight;
    };
  }else{
    return{
      document.documentElement.clientWidth;
      height:document.documentELement.clientHeight;
    };
  }
}

  3)滚动大小
  包含滚动内容的元素的大小,四个相关的特性
  scrollHeight:在没有滚动的情况下,元素内容的总高度
  scrollWidth:在没有滚动的情况下,元素内容的总宽度
  scrollLeft:被隐藏在内容区域左侧的像素数,通过设置这个属性可以改变元素的滚动位置
  scrollTop:被隐藏在内容区域上方的像素数,通过设置这个属性可以改变元素的滚动位置
  混杂模式下的IE,要document.body代替document.documentElement
  将scrollLeft和scrollTop设置为0,可以重置滚动位置

  function scrollTOTOP(element){
    if(element.scrollTop != 0){
      element.scrollTop = 0;
    }
  }

  4)确定元素大小
  每个元素都提供了getBoundingClientRect()方法,返回一个矩形对象有四个属性,left top right bottom,给出了元素在页面中相对于视口的位置

  function getBoundingClientRect(element){
    var scrollTop = document.documentElement.scrollTop;
    var scrollleft = document.documentElement.scrollLeft;
    if(element.getBoundingClientRect){
      if(typeof argument.callee.offset != 'number'){
        var temp = document.createElement("div");
        temp.style.cssText = "position:absolute;left:0;top:0";
        document.body.appendChild(temp);
        argument.callee.offset = -temp.getBoundingClientRect().top - scrollTop;
        document.body.removeChild(temp);
        temp = null;
      }
      var rect = element.getBoundingClientRect();
      var offset = argument.callee.offset;
      return{
        left:rect.left + offset;
        right:rect.right + offset;
        top:rect.top + offset;
        bottom:rect.bottom + offset;
      };
    }else{
      var actualLeft = getElementLeft(element);
      var actualTop = getElementTop(element);
      return{
        left:actualLeft - scrollLeft;
        right:actualLeft + element.offsetWidth -scrollLeft;
        top:actualTop - scrollTop;
        bottom:actualTop + element.offsetHeight - scrollTop; 
        };
    }
  } 

三,遍历
var supportsTraversals = document.implementation.hasFeature("Traversal","2.0");
var supportsNodeIterator = (typeof document.createNodeIterator == 'function');
var supportsTreeWalker = (typeof document.createTreeWalker == 'function');
1,NodeIterator
  1)document.createNodeIterator()方法创建它的新实例,接收四个参数
  root:作为搜索起点的树中的节点
  whatToShow:表示要访问哪些节点的数字代码
  filter:是个NodeFilter对象,是否接受某种特定节点的函数
  entityReferenceExpansion:布尔值,表示是否要扩展实体引用
  2)whatToShow是一个位掩码,以常量形式在NodeFilter类型中定义
    NodeFilter.SHOW_ALL:显示所有节点
    NodeFilter.SHOW_ELEMENT:显示元素节点
    NodeFilter.SHOW_ATTRIBUTE:显示属性节点
    NodeFilter.SHOW_TEXT:显示文本节点
    NodeFilter.SHOW_CDATA_SECTION:显示CDATA节点
    NodeFilter.SHOW_ENTITY_REFERENCE:显示实体引用节点
    NodeFilter.SHOW_ENTITY:显示实体节点
    NodeFilter.SHOW_PROCESSING_INSTRUCTION:显示处理指令节点
    NodeFilter.SHOW_COMMENT:显示注释节点
    NodeFilter.SHOW_DOCUMENT:显示文档节点
    NodeFilter.SHOW_DOCUMENT_TYPE:显示文档类型节点
    NodeFilter.SHOW_DOCUMENT_FRAMENT:显示文档片段节点
    NodeFilter.SHOW_NOTATION:显示符号节点
  3)通过createNodeIterator()方法的filter参数来自定义NodeFilter对象,只有一个acceptNode()方法
    应该访问给定的节点,返回NodeFilter_FILTER_ACCEPT,否则返回NodeFilter_FILTER_SKIP
    NodeFilter是一个抽象的类型,不能直接创建它的实例,只要创建一个包含acceptNode()方法的对象,将这个对象传给createNodeIterator()即可

  var filter = {
    acceptNode:function(node){
      return node.tagName.toLowerCase() == "p"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIT;
    }
  };

  var iterator = document.createNodeiterator(root,NodeFilter.SHOW_ELEMENT,filter,false);
  第三个参数可以与acceptNode函数相同

  var filter = function(node){
    return node.tagName.toLowerCase() == "p"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIT;
  };
  var iterator = document.createNodeiterator(root,NodeFilter.SHOW_ELEMENT,filter,false);
  var iterator = document.createNodeiterator(root,NodeFilter.SHOW_ELEMENT,null,false);可以访问所有类型节点

  4)nextNode() 和 previousNode()方法,返回div中所有li元素

    var div = document.getElementById("div");
    var filter = function(node){
      return node.tagName.toLowerCase() == "li"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;
    };
    var iterator = document.createNodeIterator(div,NodeFilter.SHOW_ELEMNT,filter,false);
    var node = iterator.nextNode();
    while(node != null){
      alert(node.tagName);
      node = iterator.nextNode();
    }

2,TreeWalker
  1)不同方向上遍历DOM结构的方法
  parentNode():遍历当前节点的父节点
  firstChild():遍历到当前节点的第一个子节点
  lastChild():遍历到当前节点的最后一个子节点
  nextSibiling():遍历到当前节点的下一个节点
  previousSibiling():遍历到当前节点的上一个子节点
  2)创建TreeWalker对象要使用document.createTreeWalker()方法,参数同上
  fitler对象返回值不同,还有NodeFilter_FILTER_REJECT,会跳过相应节点和该节点的子树
  3)不定义过滤器

  var div = document.getElementById("div");
  var walker = createTreeWalker(div,NodeFilter.SHOW_ELEMENT,null,false);
  walker.firstChild();
  walker.newSibiling();
  var node = walker,firstChild();
  while(node != null){
    alert(node.tagName);
    node.nextSibiling();
  }

  4)currentNode属性,表示任何遍历方法在上一次遍历中返回的节点
四,范围
1,DOM中的范围
  document类型中定义了createRange()方法
  var supportsRange = document.implementation.hadFeature("Range","2.0");
  var alsoSupportsRange = (typeof document.createRange == 'function');
  var range = document.createRange();创建的实例提供了属性和方法如下
  startContainer:包含起点的节点(即第一个子节点的父节点)
  startOffset:范围在startContainer中起点的偏移量,第一个子节点的索引值
  endContainer:包含终点的节点
  endOffset:范围在endContainer中终点的偏移量,最后一个子节点的索引值
  commonAncestorContainer:startContainer和endContainer共同祖先节点在文档树中位置最深的一个
  1)用DOM范围实现简单的选择
  selectNode():接收一个DOM节点参数,选择整个节点包括子节点
  selectNodeContents():接收一个DOM节点参数,只选择节点的子节点

  var range1 = document.createRange();
  var range2 = document.createRange();
  var p1 = document.getElementsByTagName("p")[0];
  range1.selectNode(p1);
  range2.selectNodeContents(p1);

  setStartBefore(refNode):将范围的起点设置在refNode之前,refNode是范围选区的第一个子节点,startContainer=refNode.parentNode
  setStartAfter(refNode):将范围的起设置在refNode之后,refNode的下一个同辈节点为范围的起点,startContainer=refNode.parentNode;
  setEndBefore(refNode):将范围的终点设置在refNode之前,refNode的前一个同辈节点为范围的终点,endContainer=refNode.parentNode
  setEndAfter(refNode):将范围的终点设置在热饭Node之后,refNode是范围选区的最后一个子节点,endContainer=refNode.parentNode
  2)用DOM范围实现复杂的选择
  使用setStar(参照节点startContainer,偏移量startOffset)
  使用setEnd(参照节点endContainer,偏移量endOffset)

  var range1 = document.createRange();
  var range2 = document.createRange();
  var p1 = document.getElementById("p1");
  var p1index = -1;var i;var len;
  for(i=0,len=p1.parentNode.childNodes.length;i<len;i++){
    if(p1.parentNode.childNode[i] == p1){
      p1index = i;
      break;
    }
  }
  range1.setStart(p1.parentNode,p1index);
  range1.setEnd(p1.parentNode,p1index+1);
  range2.setStart(p1,0);
  range2.seEnd(p1,p1.childNodes.length);

  3)操作DOM范围中的内容
  创建的范围,内部为这个范围创建一个文档片段
  第一个办法使用deleteContents()方法,从文档中删除选区包含的内容
    <p id="p1"><b>hello</b> world</p>
    var p1 = document.getElementById("p1");
    var hello = p1.firstChild.firstChild;
    var world = p1.lastChild;
    var range = document.createRange();
    range.setStart(hello,2);
    range.setEnd(world,3);
    range.deleteContents();
    页面显示代码如下<p><b>he</b>rld!</p>
  第二个方法extractContents(),会返回范围的文档片段,利用这个值将范围片段插入到文档中
    <p id="p1"><b>hello</b> world</p>
    var p1 = document.getElementById("p1");
    var hello = p1.firstChild.firstChild;
    var world = p1.lastChild;
    var range = document.createRange();
    range.setStart(hello,2);
    range.setEnd(world,3);
    var fragment = range.extractContents();
    p1.parentNode.appendChild(fragment);
    页面显示<p><b>he</b>rld!</p>
        <b>llo</b> wo
  第三个方法使用cloneContents()创建范围对象的副本,在文档其他地方插入
    <p id="p1"><b>hello</b> world</p>
    var p1 = document.getElementById("p1");
    var hello = p1.firstChild.firstChild;
    var world = p1.lastChild;
    var range = document.createRange();
    range.setStart(hello,2);
    range.setEnd(world,3);
    var fragment = range.cloneContents();
    p1.parentNode.appendChild(fragment);
    页面显示<p><b>hello</b>world</p>
        <b>llo</b> wo
  4)插入DOM范围中的内容
    insertNode(),可以向范围选区的开始插入一个节点
    surroundContents(),环绕范围插入内容,接收一个参数,环绕范围内容的节点
  5)折叠DOM范围
    使用折叠范围时,位置会落在完档中两个部分之间,可能是选区开始,或结束
    collapse(),接收一个参数,布尔值,表示折叠到那一端,true表示到起点,false表示到终点
    通过检查collapse属性,判断是否完成折叠,通过是否处于折叠状态,判断范围中的两个节点是否紧密相邻
  6)比较DOM范围
    compareBoundarypoints()方法,确定多个范围时是否有公共的边界,接收两个参数,表示方式的常量值,比较的范围
    常量值如下
      Range_START_TO_START(0) :第一个范围和第二个范围的起点
      Range_START_TO_END(1):第一个范围的起点和第二个范围的终点
      Range_END_TO_END(2):第一个范围和第二个范围的终点
      Range_END_TO_START(3):第一个范围的终点和第二个范围的起点
    返回值为-1(前在后之前,正常顺序)0(前后相等)1(前在后之后,逆序)
  7)复制DOM范围
    var newRange = range.cloneRange();
  8)清理DOM范围
    range.detach();
    range = null;
2,IE8及更早版本中的范围
  IE只支持文本范围,var range = document.body.createTextRange();
  1)用IE范围实现简单的选择
    findText(),找到第一次出现的给定的文本,并将范围移过来环绕该文本,没有返回false
    var found = range.findText("text");传人第二个参数表示方向,1为向前搜索,-1为向后搜索
    moveToElementText(),接收一个DOM元素,选择该元素的所有文本
    htmlText属性取得范围的全部范围
    parentElement()与DOM中commonAncestorContainer()等价
  2)使用IE范围实现发杂的选择
    以特定的增量向四周移动范围,move(),moveStart(),moveEnd(),expand(),接收两个参数,移动单位和移动数量
    character:逐个字符,word:逐个单词,sentent:逐个句子,textedit:移动到当前范围选区开始或结束位置
    moveStart是移动范围起点,moveEnd是移动范围终点,expand(),将范围规范化,将选择部分文本的部分全部选中
    move会首先折叠当前范围,调用之后要使用movestar,moveEnd创建新的额选区
  3)操作IE范围中的内容
    text属性,range.text = ''
    pasteHTML()方法 range.paeteHTML("<em></em>")
  4)折叠IE范围
    collapse(),参数true折叠到起点,false折叠到终点
    collapse不能用来判断是否发生折叠
    boundingWidth属性,如果为0证明发生折叠
  5)比较IE范围
    compareEndPoints()方法,用法同compareBoundaryPoints(),接收两个参数,比较类型和比较范围
    比较类型的取值范围:StartToStart,StartToEnd,EndToEnd,EndToStart
    返回值,第一个范围的边界位于第二个范围的边前面返回-1,相等返回0,否则返回1
    isEqual(),用于确定两个范围是否相等
    isRange(),用于判断一个范围是否包含另一个范围,调用者包含参数返回true
  6)复制IE范围
    var newRange = range.duplicate();

原文地址:https://www.cnblogs.com/b0xiaoli/p/3639317.html