js DOM

154 阅读9分钟

DOM

DOM概念

Document Object Model,文档对象模型,通过DOM可以来任意来修改网页中各个内容

  • 文档

    • 文档指的是网页,一个网页就是一个文档
  • 对象

    • 对象指将网页中的每一个节点都转换为对象

      转换完对象以后,就可以以一种纯面向对象的形式来操作网页了

  • 模型

    • 模型用来表示节点和节点之间的关系,方便操作页面

    image.png

    image.png

节点(Node)

概念

  • 节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点
  • 虽然都是节点,但是节点的类型却是不同的
  • 常用的节点
    • 文档节点 (Document),代表整个网页
      1. 文档节点document,代表的是整个HTML文档,网页中的所有节点都是它的子节点。
      2. document对象作为window对象的属性存在的,我们不用获取可以直接使用。
      3. 通过该对象我们可以在整个文档范围内查找节点对象,并可通过该对象创建各种节点对象
    • 元素节点(Element),代表网页中的标签
      1. HTML中的各种标签都是元素节点,这也是我们最常用的一个节点。
      2. 浏览器会将页面中所有的标签都转换为一个元素节点,我们可以通过document的方法来获取元素节点。
      3. 比如:document.getElementById() // 根据id属性值获取一个元素节点对象
    • 属性节点(Attribute),代表标签中的属性
      1. 属性节点表示的是标签中的一个一个的属性,这里要注意的是属性节点并非是元素节点的子节点,而是元素节点的一部分。
      2. 可以通过元素节点来获取指定的属性节点。
      3. 例如:元素节点.getAttributeNode("属性名");
      4. 注意:我们一般不使用属性节点。
    • 文本节点(Text),代表网页中的文本内容
      1. 文本节点表示的是HTML标签以外的文本内容,任意非HTML的文本都是文本节点。

      2. 它包括可以字面解释的纯文本内容。

      3. 文本节点一般是作为元素节点的子节点存在的。

      4. 获取文本节点时,一般先要获取元素节点。在通过元素节点获取文本节点。

      5. 例如:元素节点.firstChild; // 获取元素节点的第一个子节点,一般为文本节点。

    image.png

属性

image.png

image.png

浏览器已经为我们提供 文档节点 对象,这个对象是window属性,可以在页面中直接使用,文档节点代表的是整个网页。

image.png

元素(element)

  • 读取元素的属性:

    语法:元素.属性名

    例子:

    [ele.name](http://ele.name)  
    
    [ele.id](http://ele.id)  
    
    ele.value 
    
    ele.className  //class属性需用className
    
  • 修改元素的属性:

    语法:元素.属性名 = 属性值

  • innerHTML

    • 使用该属性可以获取或设置元素内部的HTML代码
    • 对于自结束标签无意义
  • nodeValue:文本节点可以通过nodeValue属性获取和设置 文本节点的内容

DOM查询

document查询方法

  • 根据元素的id属性查询一个元素节点对象:
    • document.getElementById("id属性值");
  • 根据元素的name属性值查询一组元素节点对象:
    • document.getElementsByName("name属性值");
    • 返回类数组对象,所有查询的元素都会封装到对象中,即使只查询到一个元素
  • 根据标签名来查询一组元素节点对象:
    • document.getElementsByTagName("标签名");
    • 返回类数组对象,所有查询的元素都会封装到对象中,即使只查询到一个元素

通过具体的元素节点来查询

  • 元素.getElementsByTagName()
    • 通过标签名查询当前元素的指定后代元素
  • 元素.childNodes
    • 获取当前元素的所有子节点
    • 会获取到空白的文本子节点
    • 在IE8及以下浏览器中,不会将空白文本当成子节点
  • 元素.children
    • 获取当前元素的所有子元素
  • 元素.firstChild
    • 获取当前元素的第一个子节点(包括空白文本节点)
    • firstElementChild不包括空白文本结点,但是兼容性不好,IE8以下不支持
  • 元素.lastChild
    • 获取当前元素的最后一个子节点(包括空白文本节点)
  • 元素.parentNode
    • 获取当前元素的父元素
  • 元素.previousSibling
    • 获取当前元素的前一个兄弟节点(包括空白文本节点)
    • previousElementSibling不包括空白文本结点,但是兼容性不好,IE8以下不支持
  • 元素.nextSibling
    • 获取当前元素的后一个兄弟节点(包括空白文本节点)

使用CSS选择器进行查询

  • querySelector()

  • querySelectorAll()

  • 这两个方法都是用document对象来调用,两个方法使用相同, 都是传递一个选择器字符串作为参数,方法会自动根据选择器字符串去网页中查找元素。

  • 不同的地方是querySelector()只会返回找到的第一个元素,而querySelectorAll()会返回所有符合条件的元素。

innerHTML和innerText和nodeValue

  • innerHTML和innerText并没有在DOM标准定义,但是大部分浏览器都支持这两个属性
    • innerHTML和innerText作用类似,都可以获取到标签内部的内容,

      不同是innerHTML会获取到html标签,而innerText会自动去除标签

    • 如果使用innerHTML和innerText来设置标签内部的内容时,没有任何区别的

    • innerHTML对于自结束的标签没有意义

  • nodeValue:文本节点可以通过nodeValue属性获取和设置 文本节点的内容
    • 元素.firstChild.nodeValue

document对象的属性和方法

  • document.getElementById("id属性值");

    • 根据元素的id属性查询一个元素节点对象:
  • document.getElementsByName("name属性值");

    • 根据元素的name属性值查询一组元素节点对象:
  • document.getElementsByTagName("标签名");

    • 根据标签名来查询一组元素节点对象:
  • document.all

    • 获取页面中的所有元素,相当于document.getElementsByTagName("*");
  • document.documentElement

    • 获取页面中html根元素
  • document.body

    • 获取页面中的body元素
  • document.getElementsByClassName()

    • 根据元素的class属性值查询一组元素节点对象
    • 这个方法不支持IE8及以下的浏览器
  • document.querySelector()

    • 根据CSS选择器去页面中查询一个元素

    • 如果匹配到的元素有多个,则它会返回查询到的第一个元素

    • 虽然IE8中没有getElementsByClassName(),但是可以使用querySelector()代替。

    image.png

  • document.querySelectorAll()

    • 根据CSS选择器去页面中查询一组元素

    • 会将匹配到所有元素封装到一个数组中返回,即使只匹配到一个

    image.png

DOM修改

image.png

对元素节点的修改

  • document.createElement("标签名")

    • 可以根据标签名创建一个元素节点对象
  • document.createTextNode("文本内容")

    • 可以根据文本内容创建一个文本节点对象
  • 父节点.appendChild(子节点)

    • 向父节点中添加指定的子节点
  • 父节点.insertBefore(新子节点,旧子节点)

    • 将一个新的子节点插入到旧子节点的前边
  • 父节点.replaceChild(新子节点,旧子节点)

    • 使用一个新的节点去替换旧节点
  • 父节点.removeChild(子节点)

    • 删除指定的子节点
    • 推荐方式:子节点.parentNode.removeChild(子节点)
  • 新增加子节点的两种方式:

    • appendChild
    • 修改innerHTML

    image.png

    image.png

对CSS的修改

image.png

  • 读取和修改内联样式

    • 使用style属性来操作元素的内联样式

    • 读取内联样式:

      语法:元素.style.样式名

      • 例子:

        元素.style.width

        元素.style.height

        • 注意:如果样式名中带有-,则需要将样式名修改为驼峰命名法,将-去掉,然后-后的字母改大写

        • 比如:background-color --> backgroundColor

          border-width ---> borderWidth

      通过style读取和设置的都是内联样式,无法读取样式表中的样式

    • 修改内联样式:

      语法:元素.style.样式名 = "样式值"

      例子:元素.style.width="300px"

      通过style修改的样式都是内联样式,由于内联样式的优先级比较高,

      所以我们通过JS来修改的样式,往往会立即生效,
      
      但是如果样式中设置了!important,则内联样式将不会生效。
      
  • 读取元素的当前样式

    • IE8以上浏览器

      • 使用getComputedStyle()

      • 这个方法是window对象的方法,可以返回一个对象,这个对象中保存着当前元素生效样式,如果获取的样式没有设置,则会获取到真实的值,而不是默认值。width不返回默认值auto而是返回实际长度。

      • 参数:

        1.要获取样式的元素

        2.可以传递一个伪元素,一般传null

      • 语法:

        getComputedStyle(元素 , null).样式名

      • 例子:

        获取元素的宽度

        getComputedStyle(box , null)["width"];

      • 通过该方法读取到样式都是只读的不能修改

    • IE

      • 使用currentStyle,它可以用来读取当前元素正在显示的样式,如果当前元素没有设置该样式,则获取它的默认值。background默认值transparent,width默认值auto。

      • 语法:

        元素.currentStyle.样式名

      • 例子:

        box.currentStyle["width"]

      • 通过这个属性读取到的样式是只读的不能修改

      通过currentStyle和getComputedStyle()读取到的样式都是只读的,不能修改,如果要修改必须通过style属性。

    • 同时兼容IE8与其它浏览器

      • 自己写一个**getStyle()**方法

        不需要判断浏览器版本,只需要判断当前浏览器有没有getComputedStyle()方法即可。

        getComputedStyle 不加 window:是变量,需要去作用域寻找。变量没找到,会报错。

        getComputedStyle 加 window,成为window的属性。属性没找到,返回undefined

      image.png

  • 其他的样式相关的属性

    注意:以下样式都是只读的,不带px的,返回都是一个数字,可以直接进行计算。

    • clientHeight

      • 元素的可见高度,指元素的内容区和内边距的高度
    • clientWidth

      • 元素的可见宽度,指元素的内容区和内边距的宽度

    image.png

    • offsetHeight

      • 整个元素的高度,包括内容区、内边距、边框
    • offfsetWidth

      • 整个元素的宽度,包括内容区、内边距、边框

    image.png

    • offsetParent
      • 当前元素的定位父元素

      • 离他最近的开启了定位的祖先元素,如果所有的元素都没有开启定位(position不为static),则返回body

    image.png

    • offsetLeft

    • offsetTop

      • 当前元素和定位父元素之间的偏移量

      • offsetLeft水平偏移量 offsetTop垂直偏移量

    image.png

    • scrollHeight

    • scrollWidth

      • 获取元素滚动区域的高度和宽度

    image.png

    scrollTop

    scrollLeft - 获取元素垂直和水平滚动条滚动的距离(滚动后滚去左边的距离)

    image.png

    • 判断滚动条是否滚动到底
      • 垂直滚动条

        scrollHeight - scrollTop = clientHeight

      • 水平滚动

        scrollWidth - scrollLeft = clientWidth

文档的加载

  • 浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行。

  • 如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载,

    此时将会无法正常获取到DOM对象,导致DOM操作失败。

  • 解决方式一:

    • 可以将js代码编写到body的下边
<body>

  <button id="btn">按钮</button>

  <script>

    var btn = document.getElementById("btn");

    btn.onclick = function(){

    };

  </script>

</body>

image.png

  • 解决方式二:
    • 将js代码编写到window.onload = function(){}中

    • window.onload 对应的回调函数会在整个页面加载完毕以后才执行,

      所以可以确保代码执行时,DOM对象已经加载完毕了

    image.png
<script>

  window.onload = function(){

    var btn = document.getElementById("btn");

    btn.onclick = function(){

    };

  };

</script>  

image.png 参考:blog.csdn.net/weixin_4494…