zoukankan      html  css  js  c++  java
  • DOM拓展

    DOM拓展


    1、选择符API

    所谓选择符API即是根据css选择符选择与某个模式相匹配的DOM元素,jQuery的核心就是通过css选择符查询DOM文档取得元素的引用,从而抛弃了原有繁琐的getELement等等

    querySelector()方法:接受一个css选择符,有则返回该元素,没有则返回null。通过document类型调用其,则在文档元素<html>中查找;通过element类型调用其,则在该元素后代元素范围内查找

    var body=document.querySelector("body")    获得body
    var mydiv=document.querySelector("#div") 获得id为div的元素
    var mydiv=document.querySelector(".div") 获得class为div的元素

     querySelectorAll()方法:跟querySelector差不多,只是返回的是一个NodeList实例,

    var ems=document.getElementById("div").querySelectorAll("em")  获得div中的所有em
    var mydivs=document.querySelectorAll(".div")  获得所有class为div的div

    matchesSelector()方法,为element检测是否存在返回值,是个布尔值,浏览器差异大,不常用

    2、HTML5

    2.1与类相关的扩充

    getElementsByClassName HTML5的原生扩充,其中也是NodeList的实例,同时也增加classList属性操作class,classList是新集合类型DOMTokenList的实例,一些方法操作class

    var allCurrentUsername=document.getElementsByClassName("uesername Current")  返回包含username和Current类的元素
    
    div.classList.remove("user")  移除user
    div.classList.add("user")     添加user
    div.classList.toggle("user")  切换user
    if(div.classList.contains("user")&&!div.classList.contains("username"))  确定元素中是否包含既定的类名

    2.2焦点管理

    提高web应用的无障碍性,document.activeELement始终引用DOM当前获得焦点的元素

    var btn=document.getELementById("btn")
    btn.focus()                             添加焦点
    alert(document.activeELement===btn)     true
    alert(document.hasFocus())              true     判断页面是否获得焦点

    2.3自定义属性

    HTML5规定可以为元素添加非标准的属性,但前面加data-前缀,达到浏览器方便渲染,语义化加强;在DOM基础中有setAttribute("data-age","14")添加自定义,本次详细说一下。通过dataset属性来访问自定义属性的值,其是DOMStringMap的一个实例

    div=document.getElementById("div")
    设置自定义属性
    var  age=div.dataset.age
    var  name=div.dataset.name
    为自定义属性赋值
    div.dataset.age=14
    div.dataset.name="double"

    2.4插入标记

    innerHTML属性:返回与调用元素的所有子节点(包括元素、注释、文本节点)对应的HTML标签。不是所有的元素都支持innerHTML属性

    outerHTML属性:返回调用元素自身及其所有子元素的HTML标签

    insertAdjacentHTML()方法:插入标记,不常用

    内存与性能问题:当使用插入标记的三个属性后,由于原来的元素的所有事件处理程序和js对象属性没有删除导致内存的占用,最好手动删除;使用插入标记会比js操作DOM节点快很多,但是由于创建和销毁HTML解析器导致性能损失,最好这样做:

    var itemHtml=""
    for(var i=0,len=values.length;i<len;i++){
        itemHtml+="<li>"+values[i]+"</li>"
    }
    ul.innerHTML=itemsHtml    只对innerHTML进行一次赋值操作
    
    对比着文档片段来看,有相似之处,还有NodeList也是为了防止浏览器多次重复渲染
    
    var fragment=document.createDocumentFragment()
    for(var i=0;i<5;i++){
         newli=document.createElement("li")
         newli.appendChild(document.createTextNode("item")+(i+1))
         fragment.appendChild(newli)
    }
    document.body.appendChild(fragment)

    3、专有拓展

    3.1文档模式 

    让IE浏览器始终以最新文档模式渲染页面<meta http-equiv="X-UA-Compatible" content="IE=Edge">;同时,document.documentMode来获取给定页面的文档模式

    3.2children属性

    对IE9以下版本的兼容,解决处理文本节点空白符的问题

    3.3插入文本

    3.4滚动

    专用拓展都不常用,看书了解下就可以。

    3、DOM2和DOM3

    DOM2级和DOM3级的目的在于拓展API,以满足XML的所有需求,提供更好的错误处理及特性检测。针对xml命名空间的有些变化,省略

    1样式

    1.1样式变化

    1.1.1访问元素样式

    对于使用短划线的css属性名,必须将其转为驼峰形式才通过js访问,比如background-image转为backgroundImage    font-family转为fontFamily   

    由于float为保留字,所以转换为CSSFloat,IE支持styleFloat

    var div=document.getElementById("div")    通过style来获取行间样式
    div.style.width="200px"
    div.style.height="200px"
    div.style.background="red"

    DOM2级为css做一系列的属性和方法,用来快捷操作

    div.style.cssText={200px;height:200px;background:red;} 设置cssText是为元素应用多项变化最快捷的方式,可以一次性应用所有变化
    var prop,value,i,len;
    for(i=0;len=div.style.length;i<len;i++){
         prop=div.style[i]
         value=div.style.getPropertyValue(prop)                  getPropertyValue()方法来获得属性值     removeProperty()移除某个css属性
         alert(prop+":"+value)
    }

    1.1.2计算的样式

    一般来说,用style获取行间样式,而非行间样式,则采用以下方法

    function getStyle(obj,attr){
         if(obj.currentStyle){                     兼容IE
              obj.currentStyle[attr];
       }
         else{                                     兼容其他浏览器
              getComputedStyle(obj,false)[attr]
       }
    }
    alert(getStyle(div,"width"))                   获得非行间样式

    DOM2级中增强document.defaultView,提供getComputedStyle()方法,接受两个参数,一个为计算样式的元素,一个是伪元素字符串(:after)不需要伪元素则为null/false,IE则是currentStyle,但是,无论在哪个浏览器中,所有要计算的样式都是只读的。

    1.2操作样式表(不常用,先省略)

    1.3元素大小(重点)

    1.3.1偏移量

    元素的可见大小是由其高度和宽度所决定的,包括内边距,滚动条,边框大小(不包括外边距)

    offsetHeight:元素垂直方向所占用的空间;offsetWidth:元素水平方向所占用的空间

    offsetTop:元素的上外边框至包含元素的上内边框的像素距离;offsetLeft:元素的左外边框至包含元素的左内边框的像素距离

    利用offsetParent属性进行回溯,获得基本准确的值
    简单页面中getElementLeft()  getElementTop()返回相同的值
    function getElementLeft(element){
          var actualLeft=element.offsetLeft;
          var current=element.offsetParent;
          while(current!==null){
                actuallLeft+=current.offsetLeft;
                current=current.offsetParent;
        }
          return actualLeft;
    }
    
    function getElementTop(element){
          var actualTop=element.offsetTop
          var current=element.offsetParent;
          while(currrent!==null){
               actualTop+=current.offsetTop
               current=current.offsetParent
        }
          return actualTop
    }

    1.3.2客户区大小

    客户区大小指的是元素内容及内边距占据的空间大小,不包括边框,另个clientWidth和clientHeight

    var clientHeight=document.documentElement.clientHeight||document.body.clientHeight
    
    var clientWidth=document.documentElement.clientWidth||document.body.clientWidth

    1.3.3滚动大小

    指的是包含滚动内容的元素的大小,有些元素(html)能自动添加滚动条,而有些必须通过css的overflow属性设置

    scrollHeight:没有滚动条下为元素内容的总高度;scrollWidth:没有滚动条下为元素内容的总宽度,不包含边框的

    scrollLeft:被隐藏在内容区域左侧的像素位,可以改变元素滚动位置;scrollTop:被隐藏在内容区域上侧的像素位,可以改变元素滚动位置

    通过scrollLeft和scrollTop既可以确定元素当前滚动的状态,又可以设置元素的滚动位置,尚未滚动则为0,设置为0,则重置位置

    由于兼容性问题,最好做下最大值以达到最精准的效果
    
    var clientHeight=document.documentElement.scrollHeight||document.body.scrollHeight
    var clientWidth=document.documentElement.scrollWidht||document.body.scrollWidth
    var docHeight=Math.max(document.documentElement.scrollHeight,document.documentElement.scrollHeight)
    var docWidth=Math.max(document.documentElement.scrollWidth,document.doucmentELement.scrollWidth)
    
    function scrollTop(element){                 回到顶部
         if(element.scrollTop!=0){
            element.scrollTop=0
        }
    }

    1.3.4确定元素大小(不常用,先省略)

    3、遍历

    DOM2定义了两个用于辅助完成顺序遍历DOM的类型:NodeIterator和TreeWaker

    都接受四个参数

    root:搜索起点的树中节点;whatToShow:表示访问哪些节点的数字代码;filter:过滤器,可以null;entityRefereenceExpansion:布尔值false

    NodeIterator类型:两个方法nextnode() ,previousNode()

    var filter={                      定义一个过滤器,只要p节点
      acceptNode:function(node){
      return node.tagName.toLowerCase()=="p"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;
        }
    }
    var iterator=document.createNodeIterator(root,NodeFliter.SHOW_ELEMENT,filter,false)    整个iterator
    
    var div=document.getElementById("div")              遍历div中的所有子节点,没有过滤器,有过滤器就直接的加入
    var iterator=document.createNodeIterator(div,NodeFilter.SHOW_ELEMENT,null,false)
    var node=iterator.nextNode()
    while(node!==null){
        alert(node.tagName)
        node=iterator.nextNode()
    }

    TreeWalker类型:包含nextNode() prevousNode() parentNode() firstChild() lastChild() nextSibling()  nextSibling()几种方法

    var div=document.getElementById("div")
    var filter=function(node){              定义一个过滤器
       return node.tagName.toLowerCase()=="li"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP
    }
    var walker=document.createTreeWalker(div,NodeFilter.SHOW_ELEMENT,filter,false)
    var node=walker.nextNode()
    while(node!==null){
        alert(node.tagName)
        node=walker.nextNode()
    }
    不需要过滤器 
    var walker=document.createTreeWalker(div,NodeFilter.SHOW_ELEMENT,null,false)
    walker.firstChild()
    walker.nextSibling()
    var node=walker.firstChild()
    while(node!==null){
        alert(node.tagName)
        node=walker.nextSibling
    }

    4范围

    DOM中的范围可以选择文档中的一个区域,更加精确的操控文档,每个范围都由一个range类型表示,提供多种属性和方法

    startContainer:包含范围的起点(选区中第一个节点中的父节点);startOffset:范围在startContainer中的偏移量;

    endContainer:包含范围终点的节点(选区中最后一个节点的父节点);endOffset:范围在endContainer中终点的偏移量

    4.1DOM范围实现简单选择

    直接使用selectNode(),selectNodeContents(),

    <p id="p1"><b>hello</b>world</p>
    var range1=document.createRange()
    var range2=document.createRange()
    var p1=document.getElementById("p1")
    range1.selectNode(p1)                这个范围包含p节点
    range2.selectNodeContents(p1)        这个范围为p节点的子节点

    4.2DOM范围实现复杂选择

    <p id="p1"><b>hello</b> world</p>
    var p1=document.getElementById("p1")
        helloNode=p1.firstChild.firstChild
        worldNode=p1.lastChild
    var range=document.createRange()
        range.setStart(helloNode,2)         使用setStart(node,offset)  setEnd(node,offset),获取一段文本范围
        range.setEnd(worldNode,3)
    
    range.deleteContents()                  删除范围对象
    var fragment=range.extractContents()    删除范围对象,并返回删除的范围对象
    p1.parentNode.appendChild(fragment1)     
    var fragment2=range.cloneContents()     复制范围对象
    p1.parentNode.appendChild(fragment2)    

    4.3插入DOM范围中的内容

    <span style="color:red">Inserted text</span>       效果:在范围内插入一个节点insertNode()
    同上面
    var span=document.createElement("span")
    span.style.color="red"
    span.appendChild(document.createTextNode("Inserted text"))
    range.insertNode(span)
                                        突出效果
    range.selectNode(helloNode)         提取范围中的内容
    var span=document.createElement("span")
    span.style.background="yellow"
    range.surroundContents(span)        将文档片段内容添加到给定节点       

    4.4折叠DOM范围

    range.collapse(true)     折叠到起点
    alert(range.collapsed)
    
    var p1=document.getElementById("p1")
    var p2=document.getElementById("p2")
    var range=document.createRange()
    range.setStartAfter(p1)
    range.setEndBefore(p2)
    alert(range.collapsed)    输出true

    4.5比较DOM范围,复制DOM范围,清楚DOM范围

    compareBoundaryPoints()   比较范围
    range.cloneRange()  复制范围
    range.detach()  从文档中分离
    range=null   解除引用

    IE8就不写了,卒!

    基础不牢,地动山摇

     

  • 相关阅读:
    Python处理Excel文件
    WebSocket使用中Stomp Client连接报ERROR CODE 200的解决办法
    深入理解Java虚拟机——读书笔记
    主要排序算法的Java实现
    LeetCode 67 Add Binary
    LeetCode 206 单链表翻转
    POJ 2388
    POJ 1207 3N+1 Problem
    POJ 1008 Maya Calendar
    关于指针的一些基本常识
  • 原文地址:https://www.cnblogs.com/iDouble/p/8296342.html
Copyright © 2011-2022 走看看