module3-02-DOM

DOM

一、DOM的概念

  • 文档对象模型,是W3C组织推荐的处理可扩展标记语言的标准变成接口。它是一种与平台和语言无关的应用程序接口(API),它可以动态地访问程序和脚本,更新其内容、结构和www文档的风格(目前,HTML和XML文档是通过说明部分定义的)。文档可以进一步被处理,处理的结果可以加入到当前的页面。DOM是一种基于树的API文档,它要求在处理过程中整个文档都表示在存储器中

    • 内部封装了一整套操作HTML的接口

1.1 DOM 树

  • DOM又称为文档数模型

    • 文档:一个网页可以称为文档

    • 节点:网页中的所有内容都是节点(标签、属性、文本、注释)

    • 元素:网页中的标签

    • 属性:标签的属性

1.2 DOM经常进行的操作

  • 获取元素

  • 对元素进行操作(设置其属性或调用方法)

  • 动态创建元素

  • 事件(什么时机做相应的操作)

二、获取DOM元素的方法

  • 为什么要获取页面元素

  • 要先获取页面上的元素,才可以对其进行显示/隐藏或增加动画,需要先获取到该部分对应的元素才进行后续的操作

2.1 根据id获取元素

  • 调用document对象的getElemenetById

  • 参数:字符串类型的id属性值(区分大小写)

  • 返回值:对应id名的元素对象

    • 如果有多个同id的元素,则返回第一个

  • 检测:

    • 使用tyoeof返回object

    • 使用console.dir()

注意事项

  • 由于id名具有唯一性,部分浏览器支持直接使用id名访问元素,但不是标准方式,不推荐使用

    • 下面这个的para就没有使用document方法获取

    • 如果有多个同名的id那么下面的para代表的是一个伪数组

para.style.bakcground = 'pink // 属性值记得用字符串形式
para[1].style.background = 'green' // 表示id为para的第二个元素的背景色改成green
  • 对代码书写顺序有要求(静态获取),须保证元素已经在浏览器中渲染成功

    • 需要将js代码写在html元素之后(不可以动态添加

2.2 根据标签名获取元素

  • 方法:调用document对象的getElementsByTagName方法

    • 没有getElementByTagName

  • 参数:字符串类型的标签名

  • 返回值:同名的元素对象组成的数组(伪数组)

注意事项

  • ① 操作数据时需要按照操作数组的方法进行

  • ② getElementsByTagName方法内部获取的元素是动态增加

    • 即可以在html结构前就对元素进行获取

2.3 元素对象内部获取元素

  • 获取的元素对象内部本身可以调用根据标签获取元素方法,例如div元素对象也可以调用getElementsByTagName方法

    • 类似css的子级选择器

  • 目的:缩小选择元素的范围,类似css中的后代选择器

var box1 = document.getElementsById('box1').getElementsByTagName('p')
// 平时习惯会先保存box1然后再用box1获取其内部的p

2.4 根据name获取元素

  • 方法:调用document对象的getElementsByName方法

  • 参数:字符串类型的name属性值

  • 返回值:name属性值相同的的元素对象组成的数组,属于NodeList节点集合,而之前的是属于HTMLCollection

注意事项

  • 兼容问题:在IEOpera中有兼容问题,会多选中id属性值相同的元素,所以不推荐

  • 可以动态添加

2.5 根据类名获取元素

  • 方法:调用document对象的getElementsByClassName方法

  • 参数:字符串类型的class属性

  • 返回值:class属性值相同的元素对象组成的HTMLCollection数组

注意事项

  • 不支持IE8及以下浏览器

  • 可以动态添加

  • 元素对象中也可以调用getElementsByClassName

2.6 根据选择器获取元素

  • ① 调用document对象的querySelector方法,通过css中的选择器去选取第一个符合条件的标签元素

  • ② 调用document对象的querySelectorAll方法,通过css中的选择器去选取所有符合条件的标签元素

  • 参数:字符串类型的css中的选择器

  • 返回值:用all的话就会返回一个NodeList集合

注意事项

  • 需要在HTML结构加载完之后调用

  • 不支持IE8以下的浏览器

2.7 总结

掌握,没有兼容问题

  • getElementById()

  • getElementsByTagName()

了解

  • getElementsByName()

  • getElementsByClassName()

  • 下面两个在没有兼容问题的时候推荐使用

  • querySelector()

  • querySelectorAll()

三、DOM事件基本应用

3.1 事件的基本概念

  • 事件:在什么时候做什么事

  • 执行机制:触发--响应机制

  • 绑定事件(注册事件)三要素:

    • 事件源:给谁绑定事件

    • 事件类型:绑定什么类型的事件click单机

    • 事件函数:事件发生后执行什么内容,写在函数内部

事件监听

  • JavaScript解析器会给所有绑定事件的元素添加一个监听,解析器会一直检测这个元素,只要触发对应的绑定事件,会立刻执行时间函数

常用的鼠标事件类型

  • onclick 鼠标左键单击触发

  • ondbclick 鼠标左键双击触发

  • onmousedown 鼠标按键按下触发

  • onmouseup 鼠标按键放开时触发

  • onmousemove 鼠标在元素上移动触发

  • onmouseover 鼠标移动到元素上触发

  • onmouseout 鼠标移出元素触发

3.2 非表单元素属性操作

  • 例如:href、title、id、src

    • 路径会自动转换为绝对路径呈现

  • 调用方式:元素对象打点调用属性名,例如obj.href

  • 属性赋值:给元素属性赋值,等号右侧的赋值都是字符串格式

注意事项

  • id一般都是用作只读

    • 但也可以更改(不推荐

  • 注意:部分的属性名跟关键字和保留字冲突,会更换写法

    • class -> className

    • for -> htmlFor

    • rowspan -> rowSpan

案例

  • 点击按钮切换图片

  • 不可以把.src的属性作为判读按条件,因为获取到的是绝对路径并非相对路径

    • 可以使用一个变量来表示当前的状态

3.3 事件函数内部的this

  • 事件函数中的内部有一个this指向事件源

  • 区分一下不同函数内部this的指向

    • 普通函数 -> window对象

    • 构造函数 -> 生成实例的对象

    • 对象的方法 -> 对象本身

    • 事件函数 -> 事件源

案例

  • 美女画廊(点击图片可以让一个盒子的图片切换显示)

    • 取消a的默认行为,在其点击函数中return false,或者e.preventDefault()

    • 在for循环给a设置点击事件的时候

3.4 获取标签内部内容

  • 获取标签内部内容的属性有两个:innerHTML、innerText

  • innerHTML:

    • 如果标签内部包含标签,则获取到的内容也会包含标签(包括空白换行)

  • innerText:

    • 如果包含标签,则获取到的内容会过滤标签(去掉换行和缩进等空白)

更改标签内容

  • innerHTML:里面的内容会根据HTML语法的标签加载

    • 适用场景:内部有子标签结构

  • innerText:里面的内容会按照普通的字符串加载

    • 适用场景:设置纯字符串

3.5 表单元素属性

  • value:用于大部分表单元素的内容获取(option除外)

  • type:可以获取input标签的类型(输入框或复选框)

  • disable:禁用属性

  • checked:复选框选中属性

  • selected:下拉菜单选中属性

  • 注意在DOM中元素对象的属性只有一个(且只有同名的时候)时,会被转换成布尔值显示

    • disabled = true不建议写成disabled = 'disabled'

注意事项

  • 表单元素是value来获取的

  • 非表单元素是innerHTML或innerText获取的

    • 双标签的表单元素也是如:option

表单元素的案例

  • 检测输入内容

  • 设置下拉框的选中项

  • 搜索文本框

  • 全选反选

四、其它的一些DOM操作

4.1 自定义属性操作

  • getAttribute(name) 获取标签行内属性

  • setAttribute(name, value) 设置标签行内属性

  • removeAttribute(name) 移除标签行内属性

  • 与element.属性的区别:上述三个方法用于获取任意的行内属性包括自定义的属性

注意事项

  • 用setAttribute的时候传的参数不需要进行更改,如:传入class即可。因为传入的是字符串

4.2 style样式属性操作

  • 使用style属性方法设置的样式显示在标签行内

  • element.style 属性的值,是所有行内样式组成的一个样式对象(CSSStyleDeclaration)

  • 样式对象可以继续用点语法调用或更改css的行内样式属性,例如width、height等属性

注意事项

  • background-color在js的写法要写成驼峰法如backgroundColor

  • 通过样式熟悉感设置宽高、位置的属性类型是字符串,要加上px等单位

  • 点style只能获取行内样式的东西,不能获取因为类名而赋予的属性

修改样式的方法选择

  • className类名属性操作

    • 修改元素的className属性相当于直接修改标签的类名

    • 如果需要修改多条css样式,可以提前将修改后的样式设置到一个类选择器中,后续通过修改类名的方式,批量修改css样式

  • element.style方式修改

综合案例

(1)开关灯

  • 可以利用元素自身的属性来判断当前的状态

(2)显示隐藏二维码

  • 使用js修改className的时候切记这个方法是否会重置之前的类名

    • 可以使用replace

(3)排他思想-文本框高亮显示

  • 先用for排除所有,然后循环后单独为自己添加样式

(4)设置元素怒的大小和位置案例

  • 使用className设置样式

  • 在js中使用element.style方法设置样式,注意加单位

(5)表格隔行变色和高亮显示

  • 在定义事件函数的作用域中,添加一个变量来记录原本的颜色,然后给onmouseout事件中使用其来回复原来的颜色

(6)tab选项卡切换

  • 排他思想

  • 对应控制思想:有两组数据中存储了相同个数的元素对象,一组对象的变化,会引起另外一组的变化

    • 可以在变化的元素加上自定义属性.index = i,则在该元素的事件触发函数中,使用this.index即可获取相应的下标

五、DOM节点操作

5.1 节点属性

  • nodeType:节点属性,属性值为数字,表示不同的节点类型,共12种,且只读

    • 元素节点

      • nodeValue为null

    • 属性节点

      • 可以通过getAttributeNode()来获取

      • nodeName为属性名

      • nodeValue为其值

        • 如设置了style="width: 100px; height: 100px;"则getAttributeNode('style').nodeValue就是width: 100px; height: 100px;

    • 文本节点

      • 可以通过childNodes来获取

      • 其nodeName为#text

      • 其nodeValue为其文本值

  • nodeName:节点的名称(如果是元素则是标签名),只读

  • nodeValue:节点值,返回或设置当前节点的值,元素节点的nodeValue始终是null

5.2 父子节点常用属性

  • childNodes只读属性,获取一个节点素有子节点的实时的集合,集合是动态变化的。

  • children只读属性,获取一个节点所有的子元素节点集合,是一个动态更新的HTML元素集合

  • firstChild只读属性,返回该节点的第一个子节点,如果该节点没有子节点则返回null

  • lastChild只读属性,返回该节点的最后一个子节点,如果该节点没有子节点则返回nukk

    • 可以使用firstElementChild或者lastElementChild来获取元素节点而不是所有节点

  • parentNode:返回一个当前节点的父节点,如果没有这样的节点,比如说这个节点是书结构的顶端或者没有插入一棵树种,这个属性返回null

    • 比如createElement新创建的节点或者document节点

  • parentElement:返回当前节点的父元素节点,如果该元素没有父节点,或者父节点不是一个DOM元素,则返回null

5.3 兄弟节点常用属性

  • nextSibling:只读属性,返回与该节点同级的下一个节点

  • previousSibling:只读属性,返回与该节点同级的上一个节点

  • nextElementSibling:只读属性,返回与该节点同级的下一个元素节点

  • previousElementSibling:只读属性,返回与该节点同级的上一个元素节点

注意事项

  • nextElementSibling与previousElemtnSibling有兼容性问题,在IE9以后才支持

5.4 创建与添加新节点的方法

(1)创建方法

  • document.createElement('div'):创建元素节点

  • document.createAttribute('id'):创建属性节点

  • document.createTextNode('hello'):创建文本节点

  • 一般将创建的新节点存在变量中,方便使用

(2)添加方法

  • parentNode.appendChild(child):将一个节点添加到父节点的子节点列表末尾

  • parentNode.replaceChild(newChild, oldChild):用指定的节点替换当前节点的一个子节点,并返回被替换掉的节点

  • parentNode.insertBefore(newNode, referenceNode):在参考节点之前插入一个拥有指定父节点,referenceNode必须设置,如果referenceElement为null则newNode将被插入到子节点的末尾

  • parentNode.removeChild(child):移除当前节点的一个子节点,这个子节点必须存在于当前节点中

  • 注意事项

    • 原有节点用于此操作的话,会先移除在当前DOM的位置,再进行添加到DOM树指定位置,即剪切

5.5 克隆节点

  • Node.cloneNode():克隆一个节点,并且可以选择是否克隆这个节点下的所有内容

    • 参数为true:克隆所有后代节点

    • 参数为false:只克隆本身节点

  • 注意事项

    • 标签上的属性和属性值也会被克隆,行内绑定的事件可以被复制,js动态绑定的事件不会被复制

5.6 判断是否有后代节点

  • Node.hasChildNodes():没有参数,返回一个Boolean值,来表示是否含有

  • Node.contains(child):返回一个Boolean(),来表示是否为该节点的后代

    • 不一定是父子关系,包含即返回true

其它判断的方法

  • node.firstChild !== null

  • node.childNodes.length > 0

    • 可以用children来判断是否含有元素子节点

  • node.hasChildNodes()

六、DOM一些特效制作

  • 在制作这些之前,先认识一些常用的属性

6.1 偏移量属性offset系列属性

  • offsetParent:偏移参考父级,距离子级最近的有定位的父级,如果没有定位参考body(html)

  • offsetLeft / offsetTop:偏移位置

    • 可以是margin撑开的高度宽度

  • offsetWidth / offsetHeight:偏移大小

    • boder+padding+content

6.2 客户端大小client系列属性

  • client系列没有参考父级元素

  • clientLeft / clientTop:边框区域(border大小),不常用

  • clientWidth / clientHeight:边框内部大小,不算border的大小

6.3 滚动偏移属性scroll属性

  • scrollLeft / scrollTop 盒子内部滚动出去的尺寸

  • scrollWidth / scrollHeight 盒子内容的宽度和高度,包含不可见部分

6.4 一些案例

(1)拖拽案例

  • 确认鼠标在该元素中的位置

  • 然后给onmouseup中加入onmousemove事件

drop.onmousedown = function (e) {
 e = e || window.event
 // console.log (e.pageX + '-' + box.offsetLeft)
 var l = e.pageX - box.offsetLeft
 var t = e.pageY - box.offsetTop
 console.log(l, t)
 box.onmousemove = function (e) {
   this.style.top = e.pageY - t + 'px'
   this.style.left = e.pageX - l + 'px'
}
}
drop.onmouseup = function (e) {
 box.onmousemove = null
}

(2)弹出层

  • 弹出一个遮罩层,让其它元素不能点击,使用z-index和透明度属性

  • 显示的主体内容优先级要大于遮罩层

posted @ 2020-12-30 19:53  叻仔猪  阅读(44)  评论(0编辑  收藏  举报