一、DOM基础
DOM:document object model,用来操作页面标签和css
DOM实际上是BOM的一部分
DOM的基本操作:
console.log(document) ; //打印整个页面
console.log(document.documentElement) ; //打印 html
console.log(document.body) ; //打印 body内容
console.log(document.head) ; //打印 head内容
console.log(document.title); // 打印 title内容
注:title中的内容可以直接编辑,也可以通过document.title修改。title是可读可写的
document.title = '百度一下' //此时title的内容修改为<title>百度一下</title>
二、页面的几种宽高
页面的宽高包含浏览器的实际宽高、浏览器的可视宽高、页面被卷去的宽高。通过具体实例来简单了解一下吧。
//css样式
.a{
width: 2000px;
height: 3000px;
background-color: pink;
}
<!-- html -->
<div class="a"></div>
1.浏览器的可视宽高: clientWidth / clientHeight
//js
console.log(document.documentElement.clientWidth); //690
console.log(document.documentElement.clientHeight); //705
2.浏览器的实际宽高: scrollWidth / scrollHeight
由于一般浏览器都给body设置了8px的 margin值。所以浏览器的实际宽高比我们设置的要大。
console.log(document.documentElement.scrollHeight); //3016
console.log(document.documentElement.scrollWidth); //2008
3.页面被卷去的宽高: scrollTop / scrollLeft
简单的理解就是:当可视窗体就是浏览器的高宽 不足以显示整个页面时,会自动出现一个滚动条,当滚动条滚动后,页面上面被隐藏掉的高度或者宽度就是scrollTop 和scrollLeft了
scrollTop:滚动条距离顶部的距离
scrollLeft:滚动条距离左边的距离
console.log(document.documentElement.scrollTop); //2311.199951171875
console.log(document.documentElement.scrollLeft); //488.79998779296875
三、返回顶部与判断到达底部
使用ByClassName获取元素:得到的一定是一个数组,即使只有一个值也是数组
<!-- html样式 -->
<div class="a"></div>
// js样式
var oDivs = document.getElementsByClassName('a') ;
console.log(oDivs) ; //[div.a]
console.log(oDivs[0]) ; //<div class="a"></div>
1.利用ByClassName获取元素返回顶部
- document.documentElement 返回的是 html 根节点
- document.documentElement.scrollTop 获取滚动条位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
height: 3000px;
}
.a{
width: 130px;
height: 130px;
background-color: pink;
position: fixed;
right: 0;
bottom: 0;
}
</style>
</head>
<body>
<div class="a"></div>
<script>
//获取元素
//ByClassName 得到的一定是一个数组,即使只有一个值也是数组
var oDivs = document.getElementsByClassName('a') ;
console.log(oDivs) ; //[div.a]
console.log(oDivs[0]) ; //<div class="a"></div>
//执行返回顶部操作
oDivs[0].onclick = function () {
//定义一个定时器
var t = setInterval(function () {
//滚动条位置每10毫秒向上移动20
document.documentElement.scrollTop -= 20 ;
// 滚动条所在的位置不一定能被20整除
if(document.documentElement.scrollTop <= 0){
//清除定时器
clearInterval(t) ;
}
},10)
}
</script>
</body>
</html>
但是此时,我们会发现存在一个bug。当我们不停点击滚动条向上滑动时,滑动条会加速。此时我们可以采用函数的防抖和节流来解决。
// js防抖 执行返回顶部操作码
var t ;
oDivs[0].onclick = function (){
clearInterval(t) ;
t = setInterval(function () {
document.documentElement.scrollTop -= 20 ;
if(document.documentElement.scrollTop <= 0){
clearInterval(t) ;
}
},10)
}
// js 采用节流来解决 执行返回顶部操作码
var flag = true ;
oDivs[0].onclick = function (){
if(flag){
flag = false ;
var t = setInterval(function () {
document.documentElement.scrollTop -= 20 ;
if(document.documentElement.scrollTop <= 0){
clearInterval(t) ;
flag = true ;
}
},300)
}
}
2.判断到达底部
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
height: 3000px;
}
p {
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
display: none;
}
</style>
</head>
<body>
<p id="p">别拉了,到底了</p>
<script>
var oP = document.getElementById('p');
// 这个计算如果写在事件里面每次触发都要不断计算,所以写在外面可以减少计算的时间 --- 优化性能
// 最大的滚动高度 = 页面的实际高度 - 浏览器的可视高度
var maxHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight - 10;
// 判断到达底部
var t;
window.onscroll = function () {
clearTimeout(t);
t = setTimeout(function () {
if (document.documentElement.scrollTop >= maxHeight) {
console.log('到达底部')
oP.style.display = 'block'
}
},300)
}
</script>
</body>
</html>
3.获取元素的方法
- document.getElementById :获取一个元素
- document.getElementsByClassName :class是关键字, className 获取一个元素集合
- document.getElementsByName :通过name属性来获取元素集合(一般只有表单才有name属性)
- document.getElementsByTagName() :通过标签名获取元素集合
ES6新增的方法
querySelectorAll() 获取所有的元素集合
querySelector() 获取第一个
<input type="text" name="a">
<input type="text" name="a">
<input type="text">
<div class="a"></div>
<div class="a"></div>
<script>
var oInps = document.getElementsByName('a') ;
console.log(oInps) ; // [input, input]
var oInps = document.querySelectorAll('input') ;
console.log(oInps) ; // [input, input, input]
var oDivs = document.querySelectorAll('.a') ;
console.log(oDivs) ; // [div.a, div.a]
var oDivs = document.querySelectorAll('input[name="a"]') ;
console.log(oDivs) ; // [input, input]
var oInp = document.querySelector('input:nth-child(2)') ;
console.log(oInp) ; //<input type="text" name="a">
</script>
三、标签的内容操作
- value : 输入框的内容
- innerHTML :标签的内容 , 识别标签
- innerText :标签的内容 ,不识别标签 — 把标签当做了内容的一部分
<body>
<div class="a"></div>
<input type="text" id="inp">
<script>
var oDiv = document.querySelector('.a') ;
var oInp = document.getElementById('inp') ;
var content = '<span>呵呵<span>' ;
// value 输入框的内容
oInp.value = content ;
//innerHTML 标签的内容 识别标签
oDiv.innerHTML = content ; //呵呵
//innerText 标签的内容 不识别标签 --- 把标签当做了内容的一部分
oDiv.innerText = content ; //<span>呵呵<span>
</script>
</body>
四、获取标签的属性
- 获取所有的属性 :attributes
attribute 属性:包括自有属性和自定义属性
<body>
<di id="a" class="b" aa="a" vv="s"></div>
<script>
//拿对象
var oDiv = document.querySelector('#a') ;
// attribute 属性:包括自有属性和自定义属性
console.log(oDiv.attributes) ;
//{0: id, 1: class, 2: aa, 3: vv, id: id, class: class, aa: aa, vv: vv, length: 4}
//获取自有属性id的属性
console.log(oDiv.attributes.id) ; //id='a'
//获取自有属性class的属性
console.log(oDiv.attributes.class) ; // class='b'
//获取自定义aa的属性
console.log(oDiv.attributes.aa) ; // aa='a'
</script>
</body>
- getAttribute():获取具体属性点 方法
<body>
<di id="a" class="b" aa="a" vv="s"></div>
<script>
//拿对象
var oDiv = document.querySelector('#a') ;
//获取id的属性值
console.log(oDiv.getAttribute('id')) ; //a
//获取class的属性值
console.log(oDiv.getAttribute('class')) ; //b
//获取aa的属性值
console.log(oDiv.getAttribute('aa')) ; //a
</script>
</body>
- setAttribute(‘属性名’ , ‘属性值’):添加属性,如果已经存在,就会产生覆盖。
<body>
<di id="a" class="b" aa="a" vv="s"></div>
<script>
//拿对象
var oDiv = document.querySelector('#a')
//添加属性
oDiv.setAttribute('class' , 'a') ;
console.log(oDiv) ; //此时产生了覆盖,class的属性值变成了'a'
</script>
</body>
- 删除指定的属性 removeAttribute(‘属性名’)
<body>
<di id="a" class="b" aa="a" vv="s"></div>
<script>
var oDiv = document.querySelector('#a') ;
// 删除属性
oDiv.removeAttribute(oDiv.id) ;
</script>
</body>
注意: 自有属性可以直接使用,如id,class。自定义属性不能直接使用
五、特殊标签的属性
表单上的自有属性也可以直接简写
<!-- 此时表示该输入框禁用 --> < input type="text" class="inp1" disabled>
disabled = true / false
checked = true / false
selected = true / false
<body>
<!-- 表单上的自有属性也可以直接简写 -->
<input type="text" class="inp1" disabled>
<input type="checkbox" class="inp2" checked>
<select name="" id="a">
<option value="+" selected>+</option>
<option value="-">-</option>
</select>
<script>
//拿对象
var oInp1 = document.querySelector('.inp1') ;
var oInp2 = document.querySelector('.inp2') ;
var oInp3 = document.querySelector('#a') ;
var oOptions = document.querySelectorAll('option') ;
//设置定时器,1s后输入框的属性改变
setTimeout(function () {
// 1s后 inp1的从禁用变成不禁用
oInp1.disabled = false ;
// 1s后 inp2的从选中变成不选中
oInp2.checked = false ;
// 1s后 option的符号有 + 变成 -
oOptions[1].selected = true ;
},1000)
</script>
</body>
根据这些属性,我们可以做出反选和全选。具体参考另外的博客哦~
六、标签
1.标签的类名
- className:返回值是字符串类型,可以兼容所有的浏览器
<div class="ano b">66</div>
<script>
//拿对象
var oDiv = document.querySelector('.b') ;
console.log(oDiv.className); // ano b
</script>
- classList:是一个伪数组。属性是只读的,不能通过直接赋值来进行修改元素的类名,但是可以通过 .add()添加类名、.remove()删除类名、replace()替换类名的方法对classList进行修改。
方法一:
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.on {
color: pink;
}
</style>
</head>
<body>
<div class="ano b">66</div>
<script>
//拿对象
var oDiv = document.querySelector('.b');
oDiv.onclick = function () {
//将字符串按照空格切割成数组 ['ano', 'b']
var arr = oDiv.className.split(' ');
//判断数组中是否存在这个类名,如果存在就删除
if(arr.includes('on')){
//把不包含on的值存入新的数组
var arr2 = [] ;
for(var i in arr){
if(arr[i] !== 'on'){
arr2.push(arr[i])
}
}
//将数组转换成字符串,这里的this.className指的是arr的class属性
this.className = arr2.join(' ') ;
}
else{
this.className += ' on' ;
}
}
</script>
</body>
方法二:利用classList属性,判断存在就删除,不存在就添加。
/* css样式 */
.on {
color: pink;
}
<body>
<div class="ano b">66</div>
<script>
//拿对象
var oDiv = document.querySelector('.b');
oDiv.onclick = function () {
if(this.className.includes(' on')){
this.classList.remove('on')
}
else{
this.classList.add('on')
}
}
</script>
</body>
2.标签的样式操作
- 获取样式 getComputedStyle(obj)[‘color’],如果是行内样式,就可以直接获取 obj.style.color
/* css */
.a{
width: 300px;
height: 300px;
border: 1px solid #000;
}
<body>
<!-- 此时是行内样式 -->
<div class="a" style="width:500px; color: pink;">555</div>
<script>
//拿对象
var oDiv = document.querySelector('.a') ;
//1 获取样式
var style = getComputedStyle(oDiv)['color'] ;
console.log(style) ; //rgb(255, 192, 203)
//如果是行内样式,就可以直接获取
console.log(oDiv.style.color) ; //pink
</script>
</body>
- 设置样式
在设置样式的时候,js动态添加的样式会以行内样式的形式出现。需要注意的是当获取类似font-size 属性时,为避免混淆 Javascript 的保留字符 - ,需要转化为驼峰命名法,改为 fontSize;同时 Javascript 只能拿到行内样式,非行内样式无法获取。
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* css */
.a{
width: 300px;
height: 300px;
border: 1px solid #000;
}
</style>
</head>
<body>
<!-- 行内样式 -->
<div class="a" style="width:500px; color: pink;">555</div>
<script>
//拿对象
var oDiv = document.querySelector('.a') ;
// 设置样式:js动态添加的样式会以行内样式的形式出现
oDiv.style.color = 'red' ;
//改为驼峰
oDiv.style.fontSize = '20px' ;
//js只能拿到行内样式
console.log(oDiv.style.color) ; // red
console.log(oDiv.style.height) ; //height为非行内样式,所以无法获取
</script>
</body>
cssText 给标签添加多个样式,但是会覆盖之前的行内样式
oDiv.style.cssText += 'width:100px;height:100px;color:blue;'
- getComputedStyle() 方法用于获取指定元素的 CSS 样式。获取的样式是元素在浏览器中最终渲染效果的样式。
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* css */
.a{
width: 300px;
height: 300px;
border: 1px solid #000;
}
</style>
</head>
<body>
<!-- 此时是行内样式 -->
<div class="a" style="width:500px; color: pink;">555</div>
<script>
//拿对象
var oDiv = document.querySelector('.a') ;
console.log(getComputedStyle(oDiv).height) ; //300px
console.log(getComputedStyle(oDiv)['height']) ; //300px
console.log(getComputedStyle(oDiv).color) ; //rgb(255, 192, 203)
</script>
</body>
currentStyle 只在IE8及以下可以识别。在ie、opera上是可行的,无法适用于所有浏览器的。currentStyle获取计算后的样式,也叫当前样式、最终样式。优点:可以获取元素的最终样式,包括浏览器的默认值,而不像style只能获取行间样式,所以更常用到。注意:不能获取复合样式如background属性值,只能获取单一样式如background-color等。
console.log(oDiv.currentStyle.color);
浏览器样式的兼容,如果浏览器是IE8及一下,就使用currentStyle()获取元素的CSS样式。
function css(obj , prop) {
if(getComputedStyle) {
return getComputedStyle(obj)[prop]
}
//当浏览器为IE8以下时
return obj.currentStyle[prop]
}
console.log(css(oDiv , 'color'));
//console.log(css(obj , prop));
2.给标签添加样式
- 通过cssText添加
<h1>标签样式</h1>
<script>
//拿对象
var oH1 = document.querySelector('h1') ;
//通过cssText添加
oH1.style.cssText = 'color:red;width:100px;height:200px;background-color:blue';
</script>
- 直接加类名 (更为方便)
/* css样式 */
.a {
color: pink;
width: 100px;
height: 100px;
border-color: yellow;
}
<h1>标签样式</h1>
<script>
//拿对象
var oH1 = document.querySelector('h1') ;
//直接加类名
oH1.classList.add('a') ;
</script>
getComputedStyle()获取所有样式