2017.12.17-学习笔记:DOM 知识点整理
前言:古人云,温故而知新,把自己学习 js dom 笔记整理一下,有错误之处还望指出,谢谢。
→点我去看js基础知识点整理
→点我去看js进阶知识点整理
→点我去看jQuery知识点整理
DOM:文档 对象 模型 Document Object Model
1.概念:
- DOM 把页面中所有的东西都一一对应成了一个对象,我们操作页面中元素的时候,只要操作对象即可。
- 页面中所有的东西都是对象
- 节点:Node 标签节点 文本节点 注释节点 属性节点
- 文档:document,指的是整个页面。
- 元素:element 标签节点
2.获取元素:
-
1.通过id获取元素:document.getElementById("id");
- 参数:字符串类型的id名;
- 返回值:元素,如果id不存在,返回null;
- console.log()打印一个元素的时候: 标签的形式
console.dir()打印一个元素的时候: 对象的形式
-
2.通过标签名获取元素:document.getElementsByTagName("li"); 获取页面中所有的li
-
box.getElementsByTagName("li") 获取的是box中所有li
-
返回值:伪数组,无论找到多少个元素,返回的都是伪数组,如果只有一个元素,返回的还是伪数组。
伪数组:不是数组,但是可以跟数组一样遍历,可以通过下标操作,不能使用数组的方法- 通过
Array.prototype.slice.apply(arrLike)
或[...arrLike]
或Array.from(arrLike)
将伪数组转为真数组
- 通过
-
-
3.通过类名获取元素: document.getElementsByClassName("cool");
- 参数:字符串类型 类名
- 返回值: 伪数组
-
4.通过选择器获取一个元素:document.querySelector("div.cool");
- 参数: 字符串类型的 css选择器
- 返回值:元素, 如果是多个,只会返回第一个
-
5.通过选择器获取多个元素:document.querySelectorAll("li.cool");
- 参数:字符串类型 css选择器
- 返回值: 伪数组
-
document.body:可以获取页面中的body,可以直接使用。
3.注册事件:
- 三要素:
-
事件源,我们给谁注册事件 this
事件名称,注册什么类型的事件 click
事件处理程序,触发这个事件的时候,要干什么function
-
事件源,我们给谁注册事件 this
- 如果是a标签,return false阻止a标签跳转
4.属性操作:
-
标签的普通属性(固有属性):
title src alt id class href
对于这些属性来说,标签有这个属性,标签对应的对象也有这些属性,我们可以操作对象的这些属性,达到修改标签属性的目的;
class属性对应className。 -
表单标签的属性:
type、value、name、disabled、selected、checked- disabled、checked、selected 布尔类型的属性
特点:
标签中,只要写了,就生效,不管值
对象中,除了true就是false。 true:生效; false:不生效
- disabled、checked、selected 布尔类型的属性
-
自定义属性:
-
获取属性
参数:name:属性名
返回值:对应的属性值
var value = box.getAttribute(name); -
设置属性
参数:name:设置的属性名 value:设置的属性值
返回:没有返回值
box.setAttribute(name, value); -
移除属性
参数:name:移除的属性名
box.removeAttribute(name)
-
5.排他思想:
- 干掉所有人;复活我自己。
inputs[i].onclick = function() {
//干掉所有人,遍历inputs,把所有的input的className
for (var i = 0; i < inputs.length; i++) {
inputs[i].className = "";
}
//复活我自己
this.className = "red";
}
6.获取当前元素的下标:
// 打印当前按钮对应的下标:
// 第一种: 使用let定义变量 es6 let特点: {}
// 也能形成作用域
var btns = document.querySelectorAll("button");
for (let i = 0; i < btns.length; i++) {
btns[i].onclick = function() {
console.log(i);
}
}
// 第二种: 使用属性存储下标
var btns = document.querySelectorAll("button");
for (var i = 0; i < btns.length; i++) {
btns[i].index = i;
btns[i].onclick = function() {
console.log(this.index);
}
}
// 第三种: 使用forEach遍历
var btns = document.querySelectorAll("button");
btns.forEach(function(e, i) {
//e:是每一个元素 i:每一个下标
btns[i].onclick = function() {
console.log(i);
}
});
// 第四种: 闭包解决
var btns = document.querySelectorAll("button");
for (var i = 0; i < btns.length; i++) {
(function(num) {
btns[num].onclick = function() {
console.log(num);
}
})(i); //调用btns.length-1次匿名函数,每次调用都产生相应的函数作用域,
//在每个相应的函数作用域中给注册事件赋值一个函数
}
// 第五种:
var btns = document.querySelectorAll("button");
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = (function(num) {
function fn() {
console.log(num);
}
return fn;
})(i); //给btn注册btns.length-1次事件赋值,每次注册调用匿名函数产生相应的函数作用域
}
// 使用setTimeout 每秒钟打印一个数字 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
// 第一种:
// let
for (let i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000)
}
// 第二种: 闭包
for (var i = 0; i < 10; i++) {
(function(num) {
setTimeout(function() {
console.log(num);
}, num * 1000)
})(i);
}
// 第三种: 闭包
for (var i = 0; i < 10; i++) {
var fn = (function(i) {
return function() {
console.log(i);
}
})(i);
setTimeout(fn, i * 1000);
}
8.tab栏案例:
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function() {
//干掉所有人
for (var i = 0; i < lis.length; i++) {
lis[i].className = "";
divs[i].className = "";
}
//复活我自己
this.className = "now";
//复活this对应的那个div
var index = this.getAttribute("index");
divs[index].className = "now";
}
}
9.标签内容:
- innerHTML :(文本+标签)
-
innerText :(文本)
- innerText有兼容性问题
解决方法:textContent
判断使用innerText能否获取到内容,如果能获取,就用innerText获取,如果获取不到,就用textContent获取
- innerText有兼容性问题
//参数:element 获取谁的innerText
function getInnerText(element) {
if (typeof element.innerText === "string") {
return element.innerText;
} else {
return element.textContent;
}
}
10.样式操作:
-
className:
box.className = "pink";
缺点: 如果样式频繁的发生改变,比较麻烦
使用场景:一次性修改多个样式 -
Style:
box.style.backgroundColor = "pink";
缺点:如果一次性需要改很多样式,很麻烦
使用场景:一次只需要修改一个样式,style更方便, 如果某一个样式需要不停的变化,style更方便。
10.节点操作:
-
找节点:
-
找孩子:
childNodes:获取的是所有的子节点(包括标签节点、注释节点);
children:获取的是所有的子元素(标签);
firstChild: 获取第一个孩子节点, childNodes[0];
firstElementChild:获取的是第一个孩子元素,相当于children[0];
lastChild: 获取最后一个孩子节点;
lastElementChild: 获取最后一个孩子元素. -
找兄弟:
previousSibling : 获取的当前元素的上一个兄弟节点;
previousElementSibling: 获取当前元素的上一个兄弟元素;
nextSibling: 获取的当前元素的下一个兄弟节点;
nextElementSibling: 获取的是当前元素下一个兄弟元素。 -
找父元素:
parentNode: 获取的是当前元素的父节点, 父元素。 -
jQuery中(方法)
- 1.eq(index)
2.children()---子代
3.parent() 和 parents( selector )
4.find( selector )---后代
5.siblings()--兄弟
6.next() 和 prev()
- 1.eq(index)
-
-
添加节点:
-
appendChild
语法:parent.appendChild(newChild)
功能:把newChild添加到parent的子元素的最后面
参数:需要新增加的节点 -
insertBefore
语法:parent.insertBefore(newChild, refChild);
功能:把newChild添加到refChild的前面,需要注意:parent来调用这个方法。
参数: newChild:需要添加的节点;refChild:添加到谁前面。- parent.insertBefore(newChild, null):添加到最后面,类似appendChild
parent.insertBefore(newChild, parent.children[0]);添加到最前面
- parent.insertBefore(newChild, null):添加到最后面,类似appendChild
-
-
克隆节点:
cloneNode(deep)
参数:布尔值- false:浅复制:只复制标签
- true:深复制,复制标签和内容
返回值:克隆出来的节点,克隆出来的节点和原来的节点没有关系了。
div.cloneNode(); -
创建节点:
-
document.write
缺点:只能往document里面写内容;
如果页面加载完成了,再往页面中写内容,会把原来的内容覆盖掉。 -
innerHTML
原理:innerHTML可以识别HTML标签
缺点:如果使用innerHTML创建元素的话,慎用,容易出现效率问题。 -
createElement(重点)
语法: document.createElement("tagName")
功能:在内存中创建一个元素
参数:字符串类型的标签名
返回值:创建出来的元素(空的标签)
-
-
删除节点
语法:parent.removeChild(node)
功能:删除当前节点的某个子节点
参数:node,要删除的子节点
11.In操作符:
- 判断对象能否使用某个属性
- 语法:"属性名" in 对象
如果返回true,说明有这个属性,false,没有这个属性。
12.a 标签阻止页面跳转:
- href="" 页面跳转了,不写地址,默认跳转到当前页面,页面刷新了
- href="#" 页面没跳转,没有刷新 ,跳到了当前页面的锚点。
- href="#@ 查找不到@的锚点
- href="###" 查找不到##的锚点
- href="javascript:;"伪协议
13.Window:
- window对象是js中的老大,顶级对象
- window特别常用,我们可以省略不写。
-
- 我们定义的全局变量,声明的函数都是window的
- alert() console.log() document confirm 都是window对象的
- window.onload
要等待页面加载完成了,等待页面依赖的所有文件都加载完成才会执行。
使用场景:获取页面中载入图片的宽高。 - window.open/window.close:开启关闭一个窗口
14.定时器:
-
延时定时器:可以让代码延迟一段时间之后才执行(定时炸弹)。
语法:setTimeOut(callback, time);
参数1:回调函数,时间到了就会执行。
参数2:延时的时间
返回:定时器的id,用于清除
示例:var timer = setTimeOut(function(){ //1秒后将执行的代码。}, 1000)
; -
清除延时定时器
语法:clearTimeOut(timerId)
参数:定时器id
示例:clearTimeOut(timer);//清除上面定义的定时器
-
间歇定时器:让定时器每隔一段时间就会执行一次,并且会一直执行,直到清除定时器为止.
语法:setInterval(func, delay);
参数1:重复执行的函数
参数2:每次延迟的毫秒数
返回:定时器的id,用于清除
示例:var timer = setInterval(function(){ //重复执行的代码。}, 1000)
; -
清除间歇定时器
语法:clearInterval(intervalID)
参数:定时器id
示例:clearInterval(timer);//清除上面定义的定时器
15.location对象(地址栏):可以设置或返回
- location.protocol ==> 协议
- location.href ==> 整个url
- location.host ==> 主机名和当前 URL 的端口号
- location.hostname ==> 主机名
- location.port ==> 端口号
- location.pathname ==> 当前 URL 的路径部分
- location.search ==> 获得 包含?后的参数(查询字符串)
- location.hash ==> 锚点,包含#后的参数
- location.reload() ==> 刷新页面
16.offset系列
-
获取元素自身的大小和位置:offsetHeight、offsetWidth、offsetParent、offsetLeft、offsetTop
-
offsetHeight 与 offsetWidth
1.获取的是元素真实的高度和宽度
2.获取到的是数值类型,方便计算
3.offsetHeight与offsetWidth是只读属性,不能设置。 -
style.height 与 style.width
1.只能获取行内样式
2.获取到的是字符串类型,需要转换-
结论
1.设置宽度高度使用style.width与style.height
2.获取宽度和高度offsetWidth与offsetHeight
-
结论
-
offsetParent(定位父级元素)
parentNode和offsetParent
1.parentNode始终是父元素
2.offsetParent是离当前元素最近的定位元素(absolute、relative),如果没有,那就找body -
offsetLeft 与 offsetTop
1.元素自身与offsetParent真实的距离
2.获取到的是数值类型,方便计算
3.只读属性,只能获取,不能设置 -
style.left 与 style.top
1.只能获取行内样式
2.获取到的是字符串,需要转换
3.可以获取,也可以设置-
结论
1.获取操作:用offset系列
2.设置操作:用style.xxx进行设置。
-
结论
17.三大家族:
-
Offset:
获取盒子的大小、位置(相对最近的父级定位元素)
offsetWidth / offsetHeight
offsetLeft / offsetTop- jQuery 中的 offset( ):设置或返回 偏移的位置
$(selector).offset() ==> 返回一个带有两个属性(top 和 left)的对象
$(selector).offset({top:value,left:value}) ==> 设置 偏移位置
- jQuery 中的 offset( ):设置或返回 偏移的位置
-
scroll:
-
获取 页面滚动条 滚动的距离(window 注册 scroll 事件)
window.pageXOffset ==> 兼容IE ==> document.documentElement.scrollLeft
window.pageYOffset ==> 兼容IE ==> document.documentElement.scrollTop -
获取 盒子滚动条 滚过的距离(盒子 注册 scroll 事件)
e.target.scrollLeft ==> jQuery 中用 scrollLeft( ) 设置或返回
e.target.scrollTop ==> jQuery 中用 scrollTop( ) 设置或返回 -
设置盒子滚动条滚过的距离
box.scrollTop=100 ==> jQuery 中用 scrollTop( ) 设置或返回
-
// 获取
box.addEventListener("scroll", function(e) {
console.log(e); // 事件对象
console.log(e.target.scrollTop); // 盒子滚动过的距离
})
// 设置
box.scrollTop = 100
btn.addEventListener("click", function(e) {
box.scrollTop = 200
})
-
client:
- 获取页面可视区的大小
window.innerWidth ==> jQuery 中用 $(window).width( ) 获取
window.innerHeight ==> jQuery 中用 $(window).height( ) 获取
- 获取页面可视区的大小
18.事件对象:
-
在触发某个事件的时候,都会产生一个事件对象Event,这个对象中包含所有与事件相关的一些信息,包括触发事件的元素,事件的类型以及其他与事件相关的信息。
-
获取事件对象:传一个形参e
-
事件对象的常用属性:
鼠标:pageX与pageY:光标相对于网页(文档document)左上角的水平位置与垂直位置(推荐使用);
键盘:keyCode:键盘按下的那个键的键盘码;- 放大镜效果:
获取鼠标在盒子中的位置:
var spaceX = e.pageX - box.offsetLeft;
var spaceY = e.pageY - box.offsetTop;
- 放大镜效果:
19.注册事件的两种方式
-
1.on+事件名称(不推荐)
缺点:同一个元素同一类型的事件,只能注册一个,如果注册了多个,会出现覆盖问题。 -
2.addEventListener(type, func, useCapture) 和 removeEventListener(type, func, useCapture);
事件监听(推荐)
20.事件流:
-
事件的三个阶段
- 事件的捕获阶段:当addEventListener第三个参数为true时,表示事件捕获
- 事件的目标阶段(触发自己的事件)
- 事件的冒泡阶段
-
阻止冒泡或者捕获带来的影响:
link.onclick = function (event) {
event = event || window.event;//兼容
event.stopPropagation();
}
21.事件总结:
-
常见的鼠标事件
mousedown:鼠标按下事件
mouseup:鼠标弹起事件
click:单击事件
dblclick:双击事件
mouseover:鼠标经过事件
mouseout:鼠标离开事件
mousemove:鼠标移动事件
focus:鼠标获得焦点事件
blur:鼠标失去焦点事件 -
常见的键盘事件
keydown:键盘按下时触发
keyup:键盘弹起时触发 -
常见的 window 事件
resize:浏览器窗口调整大小
scroll:窗口滚动
22.轮播图详细版
代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
.carousel {
width: 790px;
height: 340px;
margin: 100px auto;
overflow: hidden;
position: relative;
}
.carousel ul {
width: 900%;
position: absolute;
}
.carousel ul li {
float: left;
}
.carousel ol {
width: 182px;
height: 20px;
background-color: rgba(255, 255, 255, .5);
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
border-radius: 10px;
}
.carousel ol li {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #fff;
float: left;
margin-top: 4px;
margin-left: 10px;
cursor: pointer;
}
.carousel ol li.now {
background-color: red;
}
.left,
.right {
width: 30px;
height: 60px;
background-color: rgba(0, 0, 0, 0.3);
position: absolute;
top: 50%;
margin-top: -30px;
line-height: 60px;
text-align: center;
text-decoration: none;
color: #fff;
font-family: "宋体";
font-size: 24px;
}
.left {
left: 0;
}
.right {
right: 0;
}
.left:hover,
.right:hover {
background-color: rgba(0, 0, 0, .8);
}
.arrow {
display: none;
}
.carousel:hover .arrow {
display: block;
}
</style>
</head>
<body>
<div class="carousel">
<ul>
<li><a href="#"><img src="images/1.jpg" alt=""></a></li>
<li><a href="#"><img src="images/2.jpg" alt=""></a></li>
<li><a href="#"><img src="images/3.jpg" alt=""></a></li>
<li><a href="#"><img src="images/4.jpg" alt=""></a></li>
<li><a href="#"><img src="images/5.jpg" alt=""></a></li>
<li><a href="#"><img src="images/6.jpg" alt=""></a></li>
<li><a href="#"><img src="images/7.jpg" alt=""></a></li>
<li><a href="#"><img src="images/8.jpg" alt=""></a></li>
<li><a href="#"><img src="images/1.jpg" alt=""></a></li>
</ul>
<ol>
<li class="now"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
<div class="arrow">
<a href="javascript:void(0);" class="left"><</a>
<a href="javascript:void(0);" class="right">></a>
</div>
</div>
<script src=animate.js></script>
<script>
//找对象
//轮播框
var carousel = document.querySelector(".carousel");
//长图ul
var ul = document.querySelector(".carousel ul");
//图片
var imgs = document.querySelectorAll(".carousel ul li");
//圆点
var points = document.querySelectorAll(".carousel ol li");
//箭头
var leftArrow = document.querySelector(".arrow .left");
var rightArrow = document.querySelector(".arrow .right");
//图片宽度
var imgWidth = carousel.offsetWidth;
//遍历圆点
for (var i = 0; i < points.length; i++) {
//给圆点对象添加index并赋值i;用于存储下标
points[i].index = i;
//圆点注册点击事件
points[i].onclick = function() {
//排他
for (var i = 0; i < points.length; i++) {
points[i].className = '';
}
this.className = 'now';
//判断过去的张数如果等于除了假图的张数,表示框内的是假图,那就把ul位置重设,也就是把第一张放进框内
if (count == imgs.length - 1) {
ul.style.left = 0;
count = 0;
}
//移动ul
animate2(ul, -this.index * imgWidth); //中间不加单位
count = this.index;
}
}
//右箭头
var count = 0; //表示过去图片的张数
rightArrow.onclick = function() {
//判断计数器是否超过最后一张,当等于最后一张时自动移到第一张
if (count == imgs.length - 1) {
ul.style.left = 0;
count = 0;
}
//每次点击,计数器加一
count++;
//调用动画函数
animate2(ul, -count * imgWidth);
//绑定小圆点,排他
for (var i = 0; i < points.length; i++) {
points[i].className = '';
}
//判断是否到最后一张,最后一张前就改圆点类名,最后一张就直接改第一圆点
if (count < imgs.length - 1) {
points[count].className = 'now';
} else {
points[0].className = 'now';
}
}
leftArrow.onclick = function() {
if (count == 0) {
ul.style.left = -(imgs.length - 1) * imgWidth + 'px';
count = imgs.length - 1;
}
//每次点击,计数器减一
count--;
//调用动画函数
animate2(ul, -count * imgWidth);
//绑定小圆点,排他
for (var i = 0; i < points.length; i++) {
points[i].className = '';
}
if (count < imgs.length - 1) {
points[count].className = 'now';
} else {
points[0].className = 'now';
}
}
</script>
</body>
</html>