JavaScript——DOM

目录

Document Object Model

DOM操作

节点操作

事件高级

DOM对CSS的操作

Document Object Model

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

  • 文档

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

  • 对象

    • 对象指将网页中的每一个节点都转换为对象 转换完对象以后,就可以以一种纯面向对象的形式来操作网页了

  • 模型

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

  • 节点(Node)

    • 节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点

    • 虽然都是节点,但是节点的类型却是不同的

    • 常用的节点

      • 文档节点 (Document),代表整个网页

      • 元素节点(Element),代表网页中的标签

      • 属性节点(Attribute),代表标签中的属性

      • 文本节点(Text),代表网页中的文本内容

DOM操作

console.dir()可以打印我们获取的元素对象。

DOM查询

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

document查询方法:

  • 根据元素的id属性查询一个元素节点对象:

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

  • 根据元素的name属性值查询一组元素节点对象:

    • document.getElementsByName("name属性值");

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

    • document.getElementsByTagName("标签名");

  • 还可以获取某个元素(父元素)内部所有指定标签名的子元素

    • element.getElementsByTagName('标签名');

  • 通过 HTML5 新增的方法获取

    document.getElementsByClassName(‘类名’);// 根据类名返回元素对象集合

    document.querySelector('选择器'); // 根据指定选择器返回第一个元素对象document.querySelectorAll('选择器'); // 根据指定选择器返回

  • 获取特殊元素(body,html)

    document.body // 返回body元素对象

    document.documentElement // 返回html元素对象

元素的属性

  • 读取元素的属性: 语法:元素.属性名 例子:ele.name ele.id ele.value ele.className

  • 修改元素的属性: 语法:元素.属性名 = 属性值

  • innerHTML

    • 使用该属性可以获取或设置元素内部的HTML代码

事件(Event)

事件三要素

        1. 事件源 (谁)
        2. 事件类型 (什么事件)
        3. 事件处理程序 (做啥)
  • 事件指的是用户和浏览器之间的交互行为。比如:点击按钮、关闭窗口、鼠标移动。。。

  • 我们可以为事件来绑定回调函数来响应事件。

  • 绑定事件的方式: 1.可以在标签的事件属性中设置相应的JS代码 例子:按钮 2.可以通过为对象的指定事件属性设置回调函数的形式来处理事件 例子:按钮

    <script> var btn = document.getElementById("btn"); btn.onclick = function(){ }; </script>

事件源.事件类型 = 事件处理程序

文档的加载

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

  • 如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载, 此时将会无法正常获取到DOM对象,导致DOM操作失败。

  • 解决方式一:

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

      <body>按钮

      <script> var btn = document.getElementById("btn"); btn.onclick = function(){ }; </script>

      </body>

  • 解决方式二:

    • 将js代码编写到window.onload = function(){}

    • window.onload 对应的回调函数会在整个页面加载完毕以后才执行, 所以可以确保代码执行时,DOM对象已经加载完毕了

    <script> window.onload = function(){ var btn = document.getElementById("btn"); btn.onclick = function(){ }; </script>

改变元素内容

element.innerText 从起始位置到终止位置的内容, 但它去除 html 标签, 同时空格和换行也会去掉

element.innerHTML 起始位置到终止位置的全部内容,包括 html 标签,同时保留空格和换行

innerHTML 和 innerText

  • 这两个属性并没有在DOM标准定义,但是大部分浏览器都支持这两个属性,两个都是可读写的

  • 两个属性作用类似,都可以获取到标签内部的内容,不同是innerHTML会获取到html标签,而innerText会自动去除标签

  • 如果使用这两个属性来设置标签内部的内容时,没有任何区别的,只能用于普通盒子,不能用于表单元素

src、herf、id、alt、title: element.~~ = new ~~

修改样式属性

element.style 行内样式操作

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

  • 读取内联样式: 语法:元素.style.样式名

    • 例子: 元素.style.width 元素.style.height

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

      • 比如:background-color -->backgroundColor border-width ---> borderWidth

  • 修改内联样式: 语法:元素.style.样式名 = 样式值

    • 通过style修改的样式都是内联样式,由于内联样式的优先级比较高, 所以我们通过JS来修改的样式,往往会立即生效, 但是如果样式中设置了!important,则内联样式将不会生效

element.className 类名样式操作

  1. 如果样式修改较多,可以采取操作类名方式更改元素样式。

  2. class因为是个保留字,因此使用className来操作元素类名属性

  3. className 会直接更改元素的类名,会覆盖原先的类名。

    element.className = 'oldname newname' //保留原先类名

HTML Input属性

type 属性

value属性规定输入字段的初始值,文字内容可以通过value来改变

readonly 属性规定输入字段为只读(不能修改) readonly 属性不需要值。它等同于 readonly="readonly"

disabled 属性规定输入字段是禁用(true)的。被禁用的元素是不可用和不可点击的。被禁用的元素不会被提交。 size 属性规定输入字段的尺寸(以字符计) maxlength 属性规定输入字段允许的最大长度

autocomplete 属性规定表单或输入字段是否应该自动完成。当自动完成开启,浏览器会基于用户之前的输入值自动填写值。 您可以把表单的 autocomplete 设置为 on,同时把特定的输入字段设置为 off,反之亦然。autocomplete 属性适用于 <form> 以及如下 <input> 类型:text、search、url、tel、email、password、datepickers、range 以及 color。 min 和 max 属性规定 <input> 元素的最小值和最大值。

min 和 max 属性适用于如需输入类型:number、range、date、datetime、datetime-local、month、time 以及 week。

排他思想

如果有同一组元素,我们想要某一个元素实现某种样式, 需要用到循环的排他思想算法:

  1. 所有元素全部清除样式(干掉其他人)

  2. 给当前元素设置样式 (留下我自己)

  3. 注意顺序不能颠倒,首先干掉其他人,再设置自己

自定义属性的操作

获取属性值

element.属性 获取属性值。

  • 获取的是元素本身自带的属性

element.getAttribute('属性');

  • 主要获得自定义属性(标准)【程序员自定义的属性】

设置属性值

element.属性 = 值;

  • 设置内置属性值

element.setAttribute('属性','值');

  • 主要设置自定义的属性(标准)

移除属性

elemeny.removeAttribute('属性');

H5自定义属性

自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。 自定义属性获取是通过getAttribute(‘属性’) 获取。 但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。 H5给我们新增了自定义属性:

  1. 设置H5自定义属性 H5规定自定义属性data-开头做为属性名并且赋值。 比如 <div data-index="1"></div> 或者使用 JS 设置 element.setAttribute(‘data-index’, 2)

  2. 获取H5自定义属性 兼容性获取 element.getAttribute(‘data-index’); H5新增 element.dataset.index 或者 element.dataset[‘index’] ie 11才开始支持

节点操作

节点概述(Node)

  • 节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点

  • 虽然都是节点,但是节点的类型却是不同的

  • 常用的节点

    • 文档节点 (Document),代表整个网页

    • 元素节点(Element),代表网页中的标签

    • 属性节点(Attribute),代表标签中的属性

    • 文本节点(Text),代表网页中的文本内容

网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。 HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。

一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

元素节点 nodeType 为 1 属性节点 nodeType 为 2 文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等) 我们在实际开发中,节点操作主要操作的是元素节点

节点层级

利用 DOM 树可以把节点划分为不同的层级关系,常见的是父子兄层级关系。

父级节点

node.parentNode

  • parentNode 属性可返回某节点的父节点,注意是最近的一个父节点

  • 如果指定的节点没有父节点则返回 null

子节点

  1. parentNode.childNodes(标准)

parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合。

  • 注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等。 如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes

var ul = document. querySelector(‘ul’);
for(var i = 0; i < ul.childNodes.length;i++) {
if (ul.childNodes[i].nodeType == 1) {   
    // ul.childNodes[i] 是元素节点
    console.log(ul.childNodes[i]);
    }
}
  1. parentNode.children(非标准)

parentNode.children 是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回 (这个是我们重点掌握的)。

  • 虽然children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用

  1. parentNode.firstChild

firstChild 返回第一个子节点,找不到则返回null。同样,也是包含所有的节点。

  1. parentNode.lastChild

lastChild 返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。

  1. parentNode.firstElementChild

firstElementChild 返回第一个子元素节点,找不到则返回null。

  1. parentNode.lastElementChild

lastElementChild 返回最后一个子元素节点,找不到则返回null。

如果想要第一个子元素节点,可以使用 parentNode.chilren[0] 
如果想要最后一个子元素节点,可以使用parentNode.chilren[parentNode.chilren.length - 1]

兄弟节点

  1. node.nextSibling

nextSibling 返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。

2. node.previousSibling

previousSibling 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。

  1. node.nextElementSibling

nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null。

  1. node.previousElementSibling

previousElementSibling 返回当前元素上一个兄弟节点,找不到则返回null。

自己封装一个兼容性的函数

function getNextElementSibling(element) {
      var el = element;
      while (el = el.nextSibling) {
        if (el.nodeType === 1) {
            return el;
        }
      }
      return null;
    }

创建节点

document.createElement('tagName')

document.createElement() 方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。

document.createTextNode() - 可以根据文本内容创建一个文本节点对象

添加节点

  1. node.appendChild(child)

node.appendChild() 方法将一个节点添加到指定父节点的子节点列表末尾。类似于 CSS 里面的 after 伪元素。

  1. node.insertBefore(child, 指定元素)

node.insertBefore() 方法将一个节点添加到父节点的指定子节点**前面**。类似于 CSS 里面的 before 伪元素

  1. node.replaceChild(新节点,旧节点)

使用一个新的节点去替换旧节点

删除节点

node.removeChild(child)

node.removeChild() 方法从 DOM 中删除一个子节点,返回删除的节点 【node是child(被删除节点)的父节点】

复制节点

node.cloneNode()

node.cloneNode() 方法返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点

1. 如果括号参数为空或者为 false ,则是浅拷  贝,即只克隆复制节点本身,不克隆里面的子    节点。
2. 如果括号参数为 true ,则是深度拷贝,会复  制节点本身以及里面所有的子节点。

三种动态创建元素区别

  • document.write()

  • element.innerHTML

  • document.createElement()

  1. document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘

  2. innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘

  3. innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂

  4. createElement() 创建多个元素效率稍低一点点,但是结构更清晰 总结:不同浏览器下,innerHTML 效率要比 creatElement 高

事件高级

兼容性处理的原则: 首先照顾大多数浏览器,再处理特殊浏览器

addEventListener 事件监听方式

eventTarget.addEventListener(type, listener[, useCapture]) 

eventTarget.addEventListener()方法将指定的监听器注册到 eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。 该方法接收三个参数:

  • type:事件类型字符串,比如 click 、mouseover ,注意这里不要带 on

  • listener:事件处理函数,事件发生时,会调用该监听函数

    例如:div.addEventListener('click',fn); # fn不需要()#

  • useCapture:可选参数,是一个布尔值,默认是 false。学完 DOM 事件流后,我们再进一步学习

attachEvent 事件监听方式

(IE8及早期版本支持)

eventTarget.attachEvent(eventNameWithOn, callback) 

eventTarget.attachEvent()方法将指定的监听器注册到 eventTarget(目标对象) 上,当该对象触发指定的事件时,指定的回调函数就会被执行。 该方法接收两个参数:

  • eventNameWithOn:事件类型字符串,比如 onclick 、onmouseover ,这里要带 on

  • callback: 事件处理函数,当目标触发事件时回调函数被调用 注意:IE8 及早期版本支持

兼容性处理的原则: 首先照顾大多数浏览器,再处理特殊浏览器

 function addEventListener(element, eventName, fn) {
      // 判断当前浏览器是否支持 addEventListener 方法
      if (element.addEventListener) {
        element.addEventListener(eventName, fn);  // 第三个参数 默认是false
      } else if (element.attachEvent) {
        element.attachEvent('on' + eventName, fn);
      } else {
        // 相当于 element.onclick = fn;
        element['on' + eventName] = fn;
 }

删除事件的方式

删除事件兼容性解决方案 

 function removeEventListener(element, eventName, fn) {
      // 判断当前浏览器是否支持 removeEventListener 方法
      if (element.removeEventListener) {
        element.removeEventListener(eventName, fn);  // 第三个参数 默认是false
      } else if (element.detachEvent) {
        element.detachEvent('on' + eventName, fn);
      } else {
        element['on' + eventName] = null;
 } 

DOM 事件流

事件流描述的是从页面中接收事件的顺序。

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即 DOM 事件流。

注意

  1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。

  2. onclick 和 attachEvent 只能得到冒泡阶段。

  3. addEventListener(type, listener[, useCapture])第三个参数如果是 true,表示在事件捕获阶段调用事件处理程序;如果是 false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序。

  4. 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。

  5. 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave

  6. 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件,我们后面讲解。

事件对象

eventTarget.onclick = function(event) {} 
eventTarget.addEventListener('click', function(event) {})
  // 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt 
​

官方解释:event 对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。 简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象 event,它有很多属性和方法。 比如:

  1. 谁绑定了这个事件。

  2. 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。

  3. 键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。

这个 event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去。 当我们注册事件时, event 对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)。

事件对象本身的获取存在兼容问题:

  1. 标准浏览器中是浏览器给方法传递的参数,只需要定义形参 e 就可以获取到。

  2. 在 IE6~8 中,浏览器不会给方法传递参数,如果需要的话,需要到 window.event 中获取查找。 解决: e = e || window.event;

e.target 和 this 的区别:

  1. this 是事件绑定的元素, 这个函数的调用者(返回绑定这个事件的元素)

  2. e.target 是事件触发的元素 点击哪个返回哪个

阻止事件冒泡

标准写法:利用事件对象里面的 stopPropagation()方法

e.stopPropagation()

非标准写法:IE 6-8 利用事件对象 cancelBubble 属性

e.cancelBubble = true;

阻止事件冒泡的兼容性解决方案

if(e && e.stopPropagation){
      e.stopPropagation();
  }else{
      window.event.cancelBubble = true;
  }

事件委托

事件委托也称为事件代理, 在 jQuery 里面称为事件委派

事件委托的原理 不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。使用e.target

作用:我们只操作了一次 DOM ,提高了程序的性能。

常用的鼠标事件

常用的鼠标事件

1.禁止鼠标右键菜单 contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单

document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})

2.禁止鼠标选中(selectstart 开始选中)

document.addEventListener('selectstart', function(e) {
    e.preventDefault();
   })
​

鼠标事件对象

event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象 MouseEvent键盘事件对象 KeyboardEvent

常用的键盘事件

常用的键盘事件

事件除了使用鼠标触发,还可以使用键盘触发

注意:

  1. 如果使用addEventListener 不需要加 on

  2. onkeypress 和前面2个的区别是,它不识别功能键,比如左右箭头,shift 等。

  3. 三个事件的执行顺序是: keydown -- keypress --- keyup

键盘事件对象

注意: onkeydown 和 onkeyup 不区分字母大小写,onkeypress 区分字母大小写。 在我们实际开发中,我们更多的使用keydown和keyup, 它能识别所有的键(包括功能键) Keypress 不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值

DOM对CSS的操作

  • 读取元素的当前样式

    • 正常浏览器

      • 使用getComputedStyle()

      • 这个方法是window对象的方法,可以返回一个对象,这个对象中保存着当前元素生效样式

      • 参数: 1.要获取样式的元素 2.可以传递一个伪元素,一般传null

      • 例子: 获取元素的宽度 getComputedStyle(box , null)["width"];

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

    • IE8

      • 使用currentStyle

      • 语法: 元素.currentStyle.样式名

      • 例子: box.currentStyle["width"]

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

  • 其他的样式相关的属性 注意:以下样式都是只读的

    clientHeight - 元素的可见高度,指元素的内容区和内边距的高度 clientWidth - 元素的可见宽度,指元素的内容区和内边距的宽度 offsetHeight - 整个元素的高度,包括内容区、内边距、边框 offfsetWidth - 整个元素的宽度,包括内容区、内边距、边框 offsetParent - 当前元素的定位父元素 - 离他最近的开启了定位的祖先元素,如果所有的元素都没有开启定位,则返回body offsetLeft offsetTop - 当前元素和定位父元素之间的偏移量 - offsetLeft水平偏移量 offsetTop垂直偏移量

    scrollHeight scrollWidth - 获取元素滚动区域的高度和宽度

    scrollTop scrollLeft - 获取元素垂直和水平滚动条滚动的距离

    判断滚动条是否滚动到底 - 垂直滚动条 scrollHeight - scrollTop = clientHeight

    • 水平滚动 scrollWidth - scrollLeft = clientWidth

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值