一、DOM初始
1、DOM(Document object Model) 文档对象模型,操作html 中的标签的一些能力
2、我们可以操作那些内容
- 获取一个元素
- 移除一个元素
- 创建一个元素
- 向页面添加一个元素
- 给元素绑定一些事件
- 获取元素的属性
- 给元素添加一些CSS样式....
3、DOM的核心对象就是document,document对象就是浏览器内置的一个对象,里面存储着专门操作元素的各种方法;
4、DOM对象:页面中的标签,我们通过js获取到以后,就把这个对象叫做DOM对象;
二、获取一个元素,操作元素的样式
在JS中获取元素分为两类,一类是非常规标签,一类是常规标签
非常规标签:html、head、body
// html
// 语法:document.documentElement
console.log(document.documentElement);
//head
// 语法:document.head
console.log(document.head);
//body
//语法:document.body
console.log(document.body);
常规标签获取
1、getElementById 通过id名获取标签
//通过id获取标签
//语法:document.getElementById('id名称')
//返回值就是你获取到的那个元素(标签)
var box = document.getElementById('box')
2、getElementsByClassName 通过class名获取标签
//通过class 名称获取标签
var box = document.getElementsByClassName('box')
注意: (1)必然获取到的是一个伪数组,若没有就是一个空的伪数组;
(2)哪怕你获取的class只有一个,那也是获取一组元素 ,只不过一组数据中只能有一个DOM元素而已;
(3)这个一组数据也是按照索引排列的 ,我们可以通过索引拿到这个值;
3、getElementsByTagName 通过标签的标签名获取标签
//通过标签名获取标签
var box = document.getElementsByTagName('div')
注意:同getElementsByClassName 一样;
4、getElementByName 通过name属性获取标签
//通过name属性获取
<input type="text" name="user">
document.getElementsByTagName('user')
5、querySelector 按照写的CSS选择器的方式来获取元素
//以下方法在 IE低版本不支持
console.log(document.querySelector('div')) // 获取页面中的第一个 div 元素
console.log(docuemnt.querySelector('.box')) // 获取页面中第一个有 box 类名的元素
console.log(document.querySelector('#box')) // 获取页面中第一个 id 名为 box 的元素
注意:这个只能获取到一个元素,并且是页面中第一个满足条件的元素;
6、querySelectorAll 按照 选择器的方式来获取元素
console.log(document.querySelectorAll('div')) // 获取页面中的所有的 div 元素
console.log(docuemnt.querySelectorAll('.box')) // 获取页面中所有有 box 类名的元素
注意:(1)同getElementsByClassName 一样;
(2)这个会自带一个forEach()方法,是querySelectorAll 自带的,特有的,所以是可以使用的;
三、操作元素的文本内容
1、我们可以通过各种获取元素的方式获取到页面的标签之后,直接操作DOM元素的属性,就可以把效果展示在页面上;
操作元素的文本内容有:innerHTML、innerText、value
2、innerHTML 是一个读写属性
=》读(获取)
- 语法: 元素.innerHTML
- 返回值就是这个元素中的所有内容
=》写(设置)
- 语法: 元素.innerHTML = 值;
- 特点: 会完全覆盖式的替换掉之前的所有内容;
- 特点: 认识标签 , 会识别这个标签;
//获取元素内部的HTML结构
var div = document.querySelector('div')
console.log(div.innerHTML)
//设置元素内容
//设置之后,页面的div会嵌套一个p标签
var div = document.querySelector('div')
div.innerHTML = '<p>hello</p>'
3、innerText 也是读写属性
- 获取元素内部的文本(只能获取到文本内容,获取不到HTML标签)
=》读(获取)
- 语法: 元素.innerText
- 返回值: 就是这个元素中的所有内容
=》写(设置)
- 语法: 元素.innerText = 值;
- 特点: 会完全覆盖式的替换掉之前的所有内容;
- 特点: 不认识标签 , 不会识别这个标签 , 会把标签当做文本对待;
//获取元素内部的文本
var div = document.querySelector('div')
console.log(div.innerText) // hello
//设置元素内部标签
//设置之后,会把<p>hello</p>当做一个文本,不会当做标签
var div = document.querySelector('div')
div.innerText = '<p>hello</p>'
4、 value 也是一个读写属性
=》读(获取)
- 语法: 元素.value
- 注意: 凡是用户输入的都是字符串
=》写(设置)
- 语法: 元素.value = 值
// value
btn.onclick = function () {
// var res = inp.value
// console.log(res);
// console.log(typeof res);
var res = selectBtn.value;
console.log(res);
}
四、DOM树
1、含义:DOM 树就是我们 html 结构中一个一个的节点构成的,不光我们的标签是一个节点,我们写的文本内容也是一个节点,注释,包括空格都是节点。即文档流中的内容,把文档流中的内容抽象成一颗树;
2、DOM节点:就是组成页面的任何一个部分;
3、DOM的节点分类:元素节点、文本节点、属性节点、注释节点
- 元素节点:指的我们的标签
- 文本节点:页面上的每一段文本(空格 换行 缩进...)
- 属性节点:就是书写在标签上的每一个属性;
注意: 属性节点不会独立出现 , 也不会和其它的任何一个节点产生父子级关系
- 注释节点:页面上的每一段注释(空格 换行 缩进...)
//有7个子节点
<div class="box" >
hello
<p>我是第一个p标签</p>
<!-- 我是一段注释 -->
<p>我是第二个p标签</p>
world
</div>
4、获取节点
获取元素节点(标签)和之前获取非常规和常规标签一致
获取节点
(1)childNodes
=>语法: 元素.childNodes
=>返回值: 是一个伪数组 , 里面是所有的 子节点
(2)children
=>语法: 元素.children
=>返回值: 是一个伪数组 , 里面是所有的子元素节点
(3)firstChild
=>语法: 元素.firstChild
=>返回值: 第一个子节点
(4)lastChild
=>语法: 元素.lastChild
=>返回值: 最后一个子节点
(5)firstElementChild
=>语法: 元素.firstElementChild
=>返回值: 第一个子元素节点
(6)lastElementChild
=>语法: 元素.lastElementChild
=>返回值: 最后一个子元素节点
(7)nextSibling
=>语法: 元素.nextSibling
=>返回值: 就是下一个兄弟节点
(8)previousSibling
=>语法: 元素.previousSibling
=>返回值: 就是上一个兄弟节点
(9)nextElementSibling
=>语法: 元素.nextElementSibling
=>返回值: 就是下一个兄弟元素节点
(10)previousElementSibling
=>语法: 元素.previousElementSibling
=>返回值: 就是上一个兄弟元素节点
(11)parentNode
=>语法: 元素.parentNode
=>返回值: 父节点
(12)parentElement
=>语法: 元素.parentElement
=>返回值: 父元素元素节点
(13)attributes
=>语法: 元素.attributes
=>返回值: 伪数组 , 里面是所有的属性节点
<span>我是div前面的span</span>
<div class="box" >
hello
<p>我是第一个p标签</p>
<!-- 我是一段注释 -->
<p>我是第二个p标签</p>
world
</div>
<span>我是div后面的span</span>
<script>
var box = document.querySelector('div')
// childNodes
console.log(box.childNodes); //NodeList(7) [text, p, text, comment, text, p, text]
//children
console.log(box.children); //HTMLCollection(2) [p, p]
// firstChild
console.log(box.firstChild); //"hello"
// firstElementChild
console.log(box.firstElementChild); //<p>我是第一个p标签</p>
// lastChild
console.log(box.lastChild); //"world"
// lastElementChild
console.log(box.lastElementChild); //<p>我是第二个p标签</p>
// previousSibling
console.log(box.previousSibling); //#text
// previousElementSibling
console.log(box.previousElementSibling); //<span>我是div前面的span</span>
// nextSibling
console.log(box.nextSibling); //#text
//nextElementSibling
console.log(box.nextElementSibling); //<span>我是div后面的span</span>
// parentNode
console.log(box.parentNode); //<body>...</body>
//parentElement
console.log(box.parentElement); //<body>...</body>
//attributes
console.log(box.attributes); //NamedNodeMap {0: class, class: class, length: 1}
</script>
5、节点属性:就是描述节点属性的,常见的有以下几种:
语法:元素.节点属性
(1)nodeType:获取节点的节点类型,用数字表示
(2)nodeName:获取节点的节点名称
(3)nodeValue:获取节点的值
节点属性的返回值:
/ | nodeType | nodeName | nodeValue |
元素节点 | 1 | 大写标签名 | null |
属性节点 | 2 | 属性名 | 属性值 |
文本节点 | 3 | #text | 文本内容 |
注释节点 | 8 | #comment | 数值内容 |
6、操作DOM节点
- 操作:增删改查、克隆
(1)增加和插入
- createElement :创建一个元素节点
=>语法: document.createElement('你要创建的节点')
- createTextNode :创建一个文本节点
=>语法: document.createTextNode('文本内容')
- appendChild :向一个元素节点的末尾追加一个节点
=>语法: 父节点.appendChild(你要插入的节点) 插入的位置: 存放到父节点的最后面
- insertBefore :向某一个节点前插入一个节点
=> 语法: 父节点.insertBefore(要插入的节点,谁的前面)
//createElement
// 创建一个 div 元素节点
var oDiv = document.createElement('div')
console.log(oDiv) // <div></div>
//`createTextNode`
// 创建一个文本节点
var oText = document.createTextNode('我是一个文本')
console.log(oText) // "我是一个文本"
//`appendChild`
//语法: '父节点.appendChild(要插入的子节点)'
//存放到父节点的最后面
// 创建一个 div 元素节点
var oDiv = document.createElement('div')
var oText = document.createTextNode('我是一个文本')
// 向 div 中追加一个文本节点
oDiv.appendChild(oText)
console.log(oDiv) // <div>我是一个文本</div>
//`insertBefore`
//语法: `父节点.insertBefore(要插入的节点,插入在哪一个节点的前面)`
<div>
<p>我是一个 p 标签</p>
</div>
<script>
var oDiv = document.querySelector('div')
var oP = oDiv.querySelector('p')
// 创建一个元素节点
var oSpan = document.createElement('span')
// 将这个元素节点添加到 div 下的 p 的前面
oDiv.insertBefore(oSpan, oP)
console.log(oDiv)
/*
<div>
<span></span>
<p>我是一个 p 标签</p>
</div>
*/
</script>
(2)删除
- removeChild :移除某一节点下的某一个节点
语法:'父节点.removeChild(要移除的字节点) '
- remove() 语法: 要删除的节点.remove() 是属于自我杀害的行为
<div><p>我是一个 p 标签</p></div>
var div1 = document.querySelector(div)
var res = div.querySelector('p')
// 移除 div 下面的 p 标签
div1.removeChild(res)
console.log(div1);// <div></div>
// remove()
div1.remove()
(3)修改
- replaceChild :将页面中的某一个节点替换掉
语法:'父节点.replaceChild(新节点,旧节点) '
<div>
<p>我是一个 p 标签</p>
</div>
<script>
var oDiv = document.querySelector('div')
var oP = oDiv.querySelector('p')
// 创建一个 span 节点
var oSpan = document.createElement('span')
// 向 span 元素中加点文字
oSpan.innerHTML = '我是新创建的 span 标签'
// 用创建的 span 标签替换原先 div 下的 p 标签
oDiv.replaceChild(oSpan, oP)
console.log(oDiv)
/*
<div>
<span>我是新创建的 span 标签</span>
</div>
*/
</script>
(4) 克隆节点 cloneNode()
=>语法: 节点.cloneNode(参数)
=>参数: 可以写也可以不写 是一个布尔值;默认是 false 表示的是不克隆后代,选填是 true 表示克隆后代;
var box = document.querySelector('div')
// cloneNode()
// var res = box.cloneNode(false)
var res = box.cloneNode(true)
console.log(res);
五、获取元素的非行间样式
1、在JS中样式分为行内样式和非行内样式两种:
2、获取行内样式:元素.style.样式名 返回值就是对应的值,以字符串的形式,带有单位;
注意:->元素是需要我们获取到的那个元素(对象);
->如果是带有中划线的属性,需要使用驼峰命名法;
->如果没有这个属性,返回值是一个空字符串;
//获取元素
var box = document.querySelector('div')
var s = box.style.width
var s1 = box.style.fontSize
console.log(s) //300px
console.log(s1) //30px
设置行内样式
注意:->如果之前没有,就是添加这个样式;
->如果有就是修改这个样式;
box.style.width = '500px'
box.style.fontSize = '40px'
3、非行内样式:只能获取不能设置,但是这个既能获取行内样式,也可以获取非行内样式;
语法:window.getComputedStyle(元素).样式名
注意:->这个也是需要是获取的那个元素;
->如果是带有中划线的,需要使用大驼峰命名法;
->currentStyle,用法是一样的,只不过getComputedStyle是非IE,currentStyle是IE浏览器使用;
六、操作元素的属性
1、操作元素的属性
注意:->书写在我们的标签上的;
->以 key = value 的形式存在
->我们操作属性 不操作样式和类名,因为有专门用来操作的
2、属性的分类
->原生属性:就是在w3c中提到的属性,对我们的标签有一定的说明或者是描述作用,比如id 、type 、name、checked...
->自定义属性:就是在w3c中没有被提到的属性,也没有什么特殊的意义,就是为了向标签上添加一些内容,或者往标签上记录一些东西;
->H5自定义属性:也是自定义属性,凡是H5自定义属性,都是以 data-xxx 开头;
->当我们看到data-xxx开头的时候就是自定义属性了;
3、属性的操作
(1)原生属性:
获取:语法:元素.属性名 返回值: 就是该属性名对应的属性值
设置: 语法:元素.属性名 = 属性值 作用:如果之前有这个属性,就是修改,没有就是添加;
// 获取元素
var box = document.querySelector('div')
// 原生属性
//获取
var res = box.id
console.log(res);
// 设置
box.id = 'box1'
(2)自定义属性
=》获取
+语法:元素.getAttribute(属性名)
+返回值:如果有这个属性,获取到的就是这个属性对应的值,如果没有就是null;
=》设置
+语法:元素.setAttribute(属性名,属性值)
+作用:就是设置一个自定义属性
=》删除
+语法:元素.removeAttribute(属性名)
//获取
var res = box.getAttribute('index')
console.log(res)
//设置
box.setSttribute('index2','你好')
//删除
box.removeAttribute('index2')
(3)H5自定义属性:每一个元素天生自带一个属性,dataset,里面保存的就是以data-开头的自定义属性;
console.log(box.dataset)
->操作H5自定义属性
+获取
->语法:元素.dataset.属性名
->返回值:就是该属性对应的属性值
+设置
->语法:元素.dataset.属性名 = 属性值
->作用:就是设置一个属性
+删除
->语法:delete 元素.dataset.属性名
//获取
var res = box.dataset.move
//设置
box.dataset.type = 'hello'
//删除
delete box.dataset.type
七、案例:密码可见
<input type="text">
<button>密码可见</button>
<script>
// 需求,如果之前是可见的,点击之后变成不可见的,反之亦然
// 获取元素
var btn = document.querySelector('button')
var inp = document.querySelector('input')
// 给按钮添加一个点击事件
btn.onclick = function (){
// 这里我们需要获取到input的属性
// type属于原生属性
var res = inp.type
// 判断我们的属性名
if(res === 'text'){
// 需要把type之前的值变成password
// 代码可以执行,表示现在是可见的
inp.type = password
}else{
inp.type = 'text'
}
}
八、操作元素的类名
1、操作元素的类名作用:就是为了批量设置样式,进行修改;
2、两种方式:className 和classList
3、className:就是为了避开关键字 class 从新起了一个名 叫做 className;
=> 获取 -> 语法: 元素.className
-> 返回值: 就是所有的类名
=> 设置 -> 语法: 元素.className = '值'
-> 注意: 就是完全覆盖式的替换掉之前的内容
=> 追加 -> 语法: 元素.className += ' 值'
// 获取元素
var box = document.querySelector('div')
// className
// 获取
// var res = box.className
// console.log(res);
// 设置
// box.className = 'box1'
// 追加
// box.className += ' box1'
4、classList 每一个元素天生自带一个属性 就的classList,里面保存的就是所有的类名,也是一个伪数组;
=> 添加一个类名 -> 语法: 元素.classList.add(类名);
=> 删除一个类名 -> 语法: 元素.classList.remove(类名);
=> 切换类名 -> 语法: 元素.classList.toggle(类名)
-> 作用: 如果之前有就是删除,如果之前没有就是添加;
// classList
console.log(box.classList);
// 添加一个类名
box.classList.add('box4')
// 删除
box.classList.remove('a')
// 切换
box.classList.toggle('box5')
box.classList.toggle('box5')
九、获取可视窗口的尺寸
1、获取宽度:documentElement.clientWidth
console.log('获取宽度 :',document.documentElement.clientWidth);
2、获取高度: documentElement.clientHeight
console.log('获取高度 :',document.documentElement.clientHeight);
注意:BOM获取的是包含滚动条的,而这个是DOM的,不包含滚动条;
十、获取元素尺寸
1、获取元素的尺寸:就是得到这个元素的"占地面积"
2、有两种语法:offset 和 client
=>offset
- 宽度:语法: 元素.offsetWidth
- 高度:语法: 元素.offsetHeight
注意:(1)获取到的尺寸是内容区域 + 内边距 + 边框的尺寸;
(2)设置了display:none 的时候获取的尺寸是0;
(3)返回值: 就是一个数字 , 表示的就是对应的宽度或者是高度
=>client
- 宽度:语法: 元素.clientWidth
- 高度:语法: 元素.clientHeight
注意:(1)获取到的尺寸是内容区域 + 内边距的尺寸;
(2)设置了display:none 的时候获取的尺寸是0;
(3)返回值: 就是一个数字 , 表示的就是对应的宽度或者是高度
十一、获取元素的偏移量
1、偏移量:指的是距离某一坐标点的上边或者左边的距离;
2、父级:有两个,一个是结构父级,一个是定位父级;其中定位父级就是相对于那个元素定位;
3、有两种语法:offset 和 client
=>offset
- 距离上边的偏移量 语法: 元素.offsetTop
- 距离左边的偏移量 语法: 元素.offsetLeft
注意:就是一个数字 表示的就是距离上边或者是左边的距离,获取到的尺寸是相对于定位父级的距离;
=>client
- 距离上边的偏移量 语法: 元素.clientTop
- 距离左边的偏移量 语法: 元素.clientLeft