<button id="btn" οnclick="f()" >显示/隐藏</button> <div id="poet"style="visibility: visible"> 春眠不觉晓 </div> <script> var btn=document.getElementById("btn") var f=function () { let p =document.getElementById("poet"); if(p.style.visibility==="visible"){ p.style.visibility="hidden" }else{ p.style.visibility="visible" } } </script>
1.DOM树介绍
DOM:文档对象模型。DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。目的其实就是为了能让js操作html元素而制定的一个规范。
DOM就是由节点组成的:HTML加载完毕,渲染引擎会在内存中把HTML文档,生成一个DOM树。
在HTML当中,一切都是节点:(非常重要)
- 元素节点:HTML标签。
- 文本节点:标签中的文字(比如标签之间的空格、换行)
- 属性节点::标签的属性。
整个html文档就是一个文档节点。所有的节点都是Object。
object节点维护的内容
dom操作的内容
2.节点查找
2.1直接查找
DOM节点的获取方式其实就是获取事件源的方式
操作元素节点,必须首先找到该节点。有三种主要方式可以获取DOM节点:
var div1 = document.getElementById("box1"); //方式一:通过id获取单个标签
var arr2 = document.getElementsByTagName("div");//方式二:通过 标签名 获得 标签数组,
var arr3 = document.getElementsByClassName("hehe");//方式三:通过 类名 获得 标签数组
所以方式二、方式三获取的是标签数组,那么习惯性是先遍历之后再使用。
即便如此,这一个值也是包在数组里的。这个值的获取方式如下:
document.getElementsByTagName("div")[0]; //取数组中的第一个元素
document.getElementsByClassName("hehe")[0]; //取数组中的第一个元素
特殊情况:数组中的值只有1个。
2.2间接查找
DOM的节点并不是孤立的,因此可以通过DOM节点之间的相对关系对它们进行访问。如下:
节点的访问关系,是以属性的方式存在的。
JS中的父子兄访问关系:
这里我们要重点知道parentNode和children这两个属性的用法。下面分别介绍。
2.2.1获取父节点[A1]
调用者就是节点。一个节点只有一个父节点,调用方式就是
节点.parentNode
2.2.2获取兄弟节点
下一个兄弟节点
nextElementSibling
:火狐、谷歌、IE9+版本:指的是下一个元素节点(标签)。
总结:为了获取下一个元素节点,我们可以这样做:在IE678中用nextSibling,在火狐谷歌IE9+以后用nextElementSibling.
前一个兄弟节点
previousElementSibling
:火狐、谷歌、IE9+版本:都指的是前一个元素节点(标签)。
总结:为了获取前一个元素节点,我们可以这样做:在IE678中用previousSibling,在火狐谷歌IE9+以后用previousElementSibling.
补充:获得任意一个兄弟节点:
节点自己.parentNode.children[index];
//随意得到兄弟节点
获取子节点——单个子节点
1、第一个子节点 | 第一个子元素节点:
总结:为了获取最后一个子元素节点,我们可以这样做:在IE678中用lastChild,在火狐谷歌IE9+以后用lastElementChild.
2.2.3获取子节点——所有子节点
childNodes:标准属性
子节点数组 = 父节点.childNodes;
//获取所有节点。
返回的是指定元素的子元素节点的集合。【重要】
它只返回HTML节点,甚至不返回文本节点。
在IE6/
7/
8中包含注释节点(在IE678中,注释节点不要写在里面)。
虽然不是标准的DOM属性,但它和innerHTML方法一样,得到了几乎所有浏览器的支持。
children:[A2] 非标准属性(用的最多)
子节点数组 = 父节点.children;
//获取所有节点。用的最多。
3.节点操作
节点的访问关系都是属性。而节点的操作都是函数(方法)。
3.1节点本身操作
3.1.1创建节点(自己看)
新的标签(元素节点) =
document.createElement(
"标签名");
比如,如果我们想创建一个li标签,或者是创建一个不存在的adbc标签,可以这样做:
<script type="text/javascript">
var a1 = document.createElement("li"); //创建一个li标签
var a2 = document.createElement("adbc"); //创建一个不存在的标签
console.log(a1);
console.log(a2);
console.log(typeof a1);
console.log(typeof a2);
</script>
结果:
3.1.2插入节点
父节点.appendChild(新的子节点);
//方式1:父节点的最后插入一个新的子节点。
父节点.insertBefore(新的子节点,作为参考的子节点);
//方式2:在参考节点前插入一个新的节点。如果参考节点为null,那么他将在父节点最后插入一个子节点。
3.1.3删除节点
父节点.removeChild(子节点);
//用父节点删除子节点。必须要指定是删除哪个子节点。
node1.parentNode.removeChild(node1);
//删除自己这个节点
3.1.4复制节点(克隆节点)
要复制的节点.cloneNode();
//括号里不带参数和带参数false,效果是一样的。不带参数/带参数false:只复制节点本身,不复制子节点。
要复制的节点.cloneNode(
true);
//带参数true:既复制节点本身,也复制其所有的子节点。
3.1.5替换节点
父节点.replaceChild(newnode, 某个节点);
//找到这个父标签里面的要被替换的子标签,然后用新的标签将该子标签替换掉
3.2节点属性操作
我们可以获取节点的属性值、设置节点的属性值、删除节点的属性。
我们统一拿下面这个标签举例:
<img src="images/1.jpg" class="image-box" title="图片" id="a1">
3.2.1获取节点的属性值
方式1:
元素节点.属性;
元素节点[属性];
<body>
<img src="images/1.jpg" class="image-box" title="美女图片" alt="地铁一瞥" id="a1">
<script type="text/javascript">
var myNode = document.getElementsByTagName("img")[0];
console.log(myNode.src);
console.log(myNode.className); //注意,是className,不是class
console.log(myNode.title);
console.log("------------");
console.log(myNode["src"]);
console.log(myNode["className"]); //注意,是className,不是class
console.log(myNode["title"]);</script>
</body>
方式2:
元素节点.getAttribute(
"属性名称");
console.log(myNode.getAttribute(
"src"));
console.log(myNode.getAttribute(
"class"));
//注意是class,不是console.log(myNode.getAttribute("title"));
方式1和方式2的区别在于:前者是直接操作标签,后者是把标签作为DOM节点。
3.2.2设置节点的属性值
方式1:
myNode.src =
"images/2.jpg"//修改src的属性值
myNode.className =
"image2-box";
//修改class的name
方式2:
元素节点.setAttribute(属性名, 新的属性值);
myNode.setAttribute(
"src",
"images/3.jpg");
myNode.setAttribute(
"class",
"image3-box");
myNode.setAttribute(
"id",
"你好");
3.2.3删除节点的属性
元素节点.removeAttribute(属性名);
myNode.removeAttribute(
"class");
myNode.removeAttribute(
"id");
3.3节点文本操作
3.3.1获取文本节点的值
vardivEle =
document.getElementById(
"d1")
divEle.innerText
//输入这个指令,一执行就能获取该标签和内部所有标签的文本内容
divEle.innerHTML
//获取的是该标签内的所有内容,包括文本和标签
3.3.2设置文本节点的值
vardivEle =
document.getElementById(
"d1")
divEle.innerText=
"1"
divEle.innerHTML=
"<p>2</p>"//能识别成一个p标签
3.4获取值操作
elementNode.value 适用于以下标签,用户输入或者选择类型的标签:input 、select 、textarea
variEle =
document.getElementById(
"i1");
console.log(iEle.value);
varsEle =
document.getElementById(
"s1");
console.log(sEle.value);
vartEle =
document.getElementById(
"t1");
console.log(tEle.value);
3.5class的操作
className
获取所有样式类名(字符串)
首先获取标签对象
[3]
标签对象.classList.remove(cls) 删除指定类
classList.add(cls)
添加类
classList.contains(cls)
存在返回
true,否则返回
false
classList.toggle(cls)
存在就删除,否则添加,toggle的意思是切换,有了就给你删除,如果没有就给你加一个
3.6指定CSS操作
obj.style.backgroundColor=
"red"
对于没有中横线的CSS属性一般直接使用style.属性名即可
obj.style.margin
obj.style.width
obj.style.left
obj.style.position
对含有中横线的CSS属性,将中横线后面的第一个字母换成大写即可
obj.style.marginTop
obj.style.borderLeftWidth
obj.style.zIndex
obj.style.fontFamily
4.事件
JS是以事件驱动为核心的一门语言。
比如,我用手去按开关,灯亮了。这件事情里,事件源是:手。事件是:按开关。事件驱动程序是:灯的开和关。
再比如,网页上弹出一个广告,我点击右上角的X,广告就关闭了。这件事情里,事件源是:X。事件是:onclick。事件驱动程序是:广告关闭了。
于是我们可以总结出:谁引发的后续事件,谁就是事件源。
总结如下:
事件源:引发后续事件的html标签。
事件:js已经定义好了(见下图)。
事件驱动程序:对样式和html的操作。也就是DOM。
事件的三要素:事件源、事件、事件驱动程序。
代码书写步骤如下:(重要)
(
1)获取事件源:
document.getElementById(
“box”);
//类似与ios语言的 UIButton *adBtn = [UIButton buttonWithType:UIButtonTypeCustom];
(
2)绑定事件: 事件源box.事件onclick =
function(){
事件驱动程序 };
(
3)书写事件驱动程序:关于DOM的操作
代码举例:
<body>
<div id="box1"></div>
<script type="text/javascript">
// 1、获取事件源
var div = document.getElementById("box1");
// 2、绑定事件
div.onclick = function () {
// 3、书写事件驱动程序
alert("我是弹出的内容");
}
</script>
</body>
常见事件如下:
事件名 | 说明 |
onclick[4] | 鼠标单击 |
ondblclick | 鼠标双击 |
onkeyup | 按下并释放键盘上的一个键时触发 |
onchange[5] | 文本内容或下拉菜单中的选项发生改变 |
onfocus[A6] | 获得焦点,表示文本框等获得鼠标光标 |
onblur[A7] | 失去焦点,表示文本框等失去鼠标光标 |
onmouseover | 鼠标悬停,即鼠标停留在图片等得上方 |
onmouseout | 鼠标移出,即离开图片等所在的区域 |
onload | 网页文档加载事件 |
onunload | 关闭网页时 |
onsubmit | 表单提交事件 |
onreset | 重置表单时 |
4.1获取事件源(DOM节点的获取)
获取事件源的常见方式如下:
var div1 = document.getElementById("box1"); //方式一:通过id获取单个标签
var arr1 = document.getElementsByTagName("div1"); //方式二:通过 标签名 获得 标签数组
var arr2 = document.getElementsByClassName("hehe"); //方式三:通过 类名 获得 标签数组
4.2绑定事件的方式
4.2.1直接绑定匿名函数
<div id="box1" ></div>
<script type="text/javascript">
var div1 = document.getElementById("box1");
//绑定事件的第一种方式
div1.onclick = function () {
alert("我是弹出的内容");
}
</script>
4.2.2先单独定义函数,再绑定
<div id="box1" ></div>
<script type="text/javascript">
var div1 = document.getElementById("box1");
//绑定事件的第二种方式
div1.onclick = fn; //注意,这里是fn,不是fn()。fn()指的是返回值。
//单独定义函数
function fn() {
alert("我是弹出的内容");
}
</script>
绑定的时候,是写fn,不是写fn()。fn代表的是整个函数,而fn()代表的是返回值。
4.2.3行内绑定
<!--行内绑定-->
<div id="box1" οnclick="fn()"></div>
<script type="text/javascript">
function fn() {
alert("我是弹出的内容");
}
</script>
绑定时,是写的"fn()"
,不是写的"fn"
。因为绑定的这段代码不是写在js代码里的,而是被识别成了字符串。
4.3事件驱动程序
4.3.1操作标签的属性和样式
<head>
<style>
#box {
width: 100px;
height: 100px;
background-color: pink;
cursor: pointer;
}
</style>
</head>
<body>
<div id="box" ></div>
<script type="text/javascript">
var oDiv = document.getElementById("box");
//点击鼠标时,原本粉色的div变大了,背景变红了
oDiv.onclick = function () {
oDiv.style.width = "200px"; //属性值要写引号
oDiv.style.height = "200px";
oDiv.style.backgroundColor = "red"; //属性名是backgroundColor,不是background-Color
}
</script>
上方代码的注意事项:
- 在js里写属性值时,要用引号
- 在js里写属性名时,是
backgroundColor
,不是CSS里面的background-Color
。记得所有的像css属性的text-,line-、backgroun-*等在js中都写成驼峰
4.3.2onload事件
当页面加载(文本和图片)完毕的时候,触发onload事件。
<script type="text/javascript">
window.onload = function () {
console.log("小马哥"); //等页面加载完毕时,打印字符串
}
</script>
js的加载是和html同步加载的。因此,如果使用元素在定义元素之前,容易报错。这个时候,onload事件就能派上用场了,我们可以把使用元素的代码放在onload里,就能保证这段代码是最后执行。
建议是:整个页面上所有元素加载完毕在执行js内容。所以,window.onload可以预防使用标签在定义标签之前。
onload事件(屏幕可视区域)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
// 屏幕的可视区域
window.onload = function(){
// document.documentElement 获取的是html标签
console.log(document.documentElement.clientWidth);
console.log(document.documentElement.clientHeight);
// 窗口大小发生变化时,会调用此方法
window.onresize = function(){
console.log(document.documentElement.clientWidth);
console.log(document.documentElement.clientHeight);
}
}
</script>
</html>
onload事件(offset系列)
<!DOCTYPE html><html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
</style>
</head>
<body style="height: 2000px">
<div>
<div class="wrap" style=" width: 300px;height: 300px;background-color: green">
<div id="box" style="width: 200px;height: 200px;border: 5px solid red;position: absolute;top:50px;left: 30px;">
</div>
</div>
</div>
</body>
<script type="text/javascript">
window.onload = function(){
var box = document.getElementById('box')
/*
offsetWidth占位宽 内容+padding+border
offsetHeight占位高
* offsetTop: 如果盒子没有设置定位 到body的顶部的距离,如果盒子设置定位,那么是以父辈为基准的top值
* offsetLeft: 如果盒子没有设置定位 到body的左部的距离,如果盒子设置定位,那么是以父辈为基准的left值
* */
console.log(box.offsetTop)
console.log(box.offsetLeft)
console.log(box.offsetWidth)
console.log(box.offsetHeight)
}
</script>
</html>