web前端学习笔记--Dom
web前端学习笔记——DOM
一、概念
DOM:document object model,文档对象模型(将文档抽象为对象),是一种与平台和语言无关的应用程序接口(API),它可以动态地访问程序和脚本,更新其内容、结构和 www 文档的风格,是一种基于树 的API文档,在处理过程中整个文档都表示在存储器中
DOM又称为文档树模型
文档:一个网页
节点:网页中所有的内容都是节点(标签、属性、文本、注释等)
元素:网页中的标签
属性:标签的属性
二、常用操作
-
获取元素
-
根据id获取元素
方法:通过document对象的getElementById方法
参数:id的属性值
返回值:对应的id名的元素对象(没有值)
<script> var para = document.getElementById("text1"); console.log(para); </script> <p id="text1">这是一段文字</p> <p id="text2">这是一段文字</p> <p id="text3">这是一段文字</p>
效果:
发现得到的是null,主要是因为在js中获取元素必须保证元素已经在浏览器中渲染成功,故需要把获取元素部分在在代码后面
<p id="text1">这是一段文字</p> <p id="text2">这是一段文字</p> <p id="text3">这是一段文字</p> <script> var para = document.getElementById("text1"); console.log(para); </script>
效果:
扩:在后台查看具体的对象可以用console.dir();
可以设置其属性
para.style.background = "pink";
-
根据标签名获取元素
方法:document对象的getElementByTagName方法
参数:标签名
返回值:由同名的元素对象组成的数组(按照顺序排列)
<p>text1</p> <p>text2</p> <p>text3</p> <script> para = document.getElementsByTagName("p"); console.log(para); </script>
效果:
其中的HTMLCollection:html元素组成的集合 伪数组
在操作数据时,需要按照数组的方法进行
获取的元素是动态增加的(push加入),故可以写在html之前(渲染之前)
for (var i = 0; i <= para.length - 1; i++) { console.log(para[i]); //显示每一项 } para[0].style.background = "pink"; //设置属性
效果:
扩:元素对象内部获取标签元素(缩小选择元素的范围)
<div id="box1"> <p>text1 of box1</p> <p>text2 of box1</p> <p>text3 of box1</p> <p>text4 of box1</p> </div> <script> var box1 = document.getElementById("box1"); console.log(box1); var ps1 = box1.getElementsByTagName("p"); console.log(ps1); </script>
可以简写,类似后代选择器
var box1 = document.getElementById("box1").getElement sByTagName("p");
-
根据name获取元素
方法:调用 document 对象的 getElementsByName 方法。
参数:字符串类型的 name 属性值。
返回值:name 属性值相同的元素对象组成的数组。
不建议使用:在 IE 和 Opera 中有兼容问题,会多选中 id 属性值相同的元素。
<form> <input type="radio" name="age">0~10<br> <input type="radio" name="age">11~20<br> <input type="radio" name="age">20~30<br> </form> <div id="age">年龄</div> <script> var ages = document.getElementsByName("age"); console.log(ages); </script>
效果:
注:只能使用document去调用getElementsByName
Nodelist是返回节点的集合,元素节点,HTMLcollection是HTML的集合,是一个元素,是节点的一种,故可以理解为HTMLcollection是Nodelist的一种
-
根据类名获取元素
方法:调用 document 对象的 getElementsByClassName 方法。
参数:字符串类型的 class 属性值。
返回值:class 属性值相同的元素对象组成的数组。 (动态添加)
浏览器兼容问题:不支持 IE8 及以下的浏览器
<div id="box1"> <p class="para">text1 of box1</p> <p class="para">text2 of box1</p> <p>text3 of box1</p> <p>text4 of box1</p> </div> <script> var paras = document.getElementsByClassName("para"); console.log(paras); </script>
效果:
元素对象内部也可以调用getElementsClassName
var box1 = document.getElementById("box1"); var paras = box1.getElementsByClassName("para"); console.log(paras);
效果:
-
根据选择器获取元素
方法1:调用 document 对象的 querySelector 方法,通过 css 中的选择器去选取第一个
符合条件的标签元素。
参数:字符串类型的 css 中的选择器。
返回值:对象元素
<div> <p>text1 of box1</p> <p>text2 of box1</p> <p>text3 of box1</p> <p>text4 of box1</p> </div> <script> var para = document.querySelector("p"); console.log(para); </script>
效果:
方法2:调用 document 对象的 querySelectorAll 方法,通过 css 中的选择器去选取所
有符合条件的标签元素。
参数:字符串类型的 css 中的选择器。
返回值:数组
<div> <p>text1 of box1</p> <p>text2 of box1</p> <p>text3 of box1</p> <p>text4 of box1</p> </div> <script> var para = document.querySelectorAll("p"); console.log(para); </script>
效果:
浏览器兼容问题:不支持 IE8 以下的浏览器
-
-
对元素进行操作
-
动态创建元素
-
事件(什么时机做相应的操作)
事件:在什么时候做什么事
执行机制:触发–响应机制
绑定事件(注册事件)三要素:
1、事件源:给谁绑定事件
2、事件类型:绑定什么类型的事件 click 单击
3、事件函数:事件发生后执行什么内容,写在函数内部
事件监听:JavaScript 解析器会给有绑定事件的元素添加一个监听,解析器会一直监测这个元素,只要
触发对应的绑定事件,会立刻执行事件函数。
绑定方法(监听):
方法一:绑定HTML元素属性
<input type="button" value="点击有惊喜" onclick="alert('点击我做什么?')">
方法二:绑定DOM对象属性
1.获取元素
2.绑定事件
<input type="button" value="点击有惊喜" id="btn"> <script> var btn = document.getElementById("btn"); //获取元素 btn.onclick = function() { //绑定 alert("点击我做什么"); }; </script>
常用鼠标事件类型
• onclick 鼠标左键单击触发
• ondbclick 鼠标左键双击触发
• onmousedown 鼠标按键按下触发
• onmouseup 鼠标按键放开时触发
• onmousemove 鼠标在元素上移动触发
• onmouseover 鼠标移动到元素上触发
• onmouseout 鼠标移出元素边界触发
属性操作:
非表单元素属性(href、title、id、src等)
调用方式:元素对象打点调用属性名,例如 obj.href。
注意:部分的属性名跟关键字和保留字冲突,会更换写法。
class → className
for → htmlFor
rowspan → rowSpan
属性赋值:给元素属性赋值,等号右侧的赋值都是字符串格式
<a href="http://www.baidu.com" title="跳转到百度" id="link">跳转</a>
<img src="images/a.jpg" alt="图片" id="pic" width="100px">
<script>
var link = document.getElementById("link");
var pic = document.getElementById("pic");
// 调用
console.log(link.title);
console.log(link.href);
console.log(link.id);
console.log(pic.src);
console.log(pic.id);
</script>
案列:
点击按钮切换图片
<input type="button" value="点击" id="btn"><br>
<img src="images/a.jpg" alt="图片a" id="pic" width="200px">
<script>
// 获取元素
var btn = document.getElementById("btn");
var pic = document.getElementById("pic");
// 添加事件
// btn.onclick = function() {
// if (pic.src === "images/a.jpg") {
// pic.src = "images/b.jpg";
// } else {
// pic.scr = "images/a.jpg";
// }
// }
//失败原因是因为pic.src的值是绝对路径,可以添加一个值作为判断条件
var num = 1; //当num为1的时候,就是a照片,2的时候,为b照片
btn.onclick = function() {
if (num == 1) {
pic.src = "images/b.jpg";
num = 2; //可以循环切换
} else {
pic.src = "images/a.jpg";
num = 1; //可以循环切换
}
}
</script>
点击按钮,显示隐藏
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
.show {
display: block;
}
.hide {
display: none;
}
</style>
<body>
<input type="button" value="隐藏" id="btn"><br>
<div id="box"></div>
<script>
// 获取元素
var btn = document.getElementById("btn");
var box = document.getElementById("box");
// 事件
btn.onclick = function() {
if (btn.value == "隐藏") {
box.className = "hide";
btn.value = "显示"
} else {
box.className = "show";
btn.value = "隐藏";
}
}
</script>
</body>
this
在事件函数内部 有一个 this ,指向事件源
区分一下不同函数内部 this 的指向
普通函数 -> window 对象
构造函数 -> 指向的是生成的实例对象
对象的方法 -> 指向的是对象本身
事件函数 -> 指向的是事件源
美女相册
<h2>美女画廊</h2>
<div id="imagegallery">
<a href="images/1.jpg" title="美女A">
<img src="images/1-small.jpg" alt="美女1" width="100px">
</a>
<a href="images/2.jpg" title="美女B">
<img src="images/2-small.jpg" alt="美女2" width="100px">
</a>
<a href="images/3.jpg" title="美女C">
<img src="images/3-small.jpg" alt="美女3" width="100px">
</a>
<a href="images/4.jpg" title="美女A">
<img src="images/4-small.jpg" alt="美女4" width="100px">
</a>
</div>
<div style="clear:both"></div>
<img src="images/placeholder.png" alt="" width="450px" id="image">
<p id="des">选择一个图片</p>
<script>
// 获取元素
var imagegallery = document.getElementById("imagegallery");
var link = imagegallery.getElementsByTagName("a");
var image = document.getElementById("image");
var des = document.getElementById("des");
// 添加点击事件
for (var i = 0; i <= link.length - 1; i++) {
link[i].onclick = function() {
// alert("aaaa");
// image.src = link[i].href;
image.src = this.href;
return false; //取消a标签默认的返回效果
}
}
</script>
为什么不能使用**image.src = link[i].href;**是因为在for 循环内部添加的绑定事件,在触发时,所有的批量添加的事件已经成功,触发事件时都是在循环结束之后,当批量绑定的事件的事件函数内部有 变量 i,i的值是循环结束后的值,(循环内部定义的变量是一个全局变量)故在循环后执行的 i 变量的值是 i 跳出循环时的值此时的i的值是4,已超出link的长度。
获取标签内部内容的属性
1.innerHTML
是标签内部的所有内容,包括包含的标签、空白、换行等
设置属性值:可以给双标签内部更改内容,可以有标签(按照HTML语法中的标签加载)
使用场景:在设置有内部子标签结构时使用
2.innerText
只包含文本内容,会去掉标签、空白、缩进等
设置属性值:可以给双标签内部更改内容,可以有标签(按照普通的字符加载)
使用场景:在设置纯字符串的时候使用
<div id="box">
这是一个div标签
<p id="ps">这是一段文字</p>
</div>
<script>
var box = document.getElementById("box");
var ps = document.getElementById("ps");
var box1 = box.innerHTML;
console.log(box1);
console.log(box.innerText);
</script>
表单元素属性
• value 用于大部分表单元素的内容获取(option除外,option用innerHTML)
• type 可以获取input标签的类型(输入框或复选框等)
• disabled 禁用属性
• checked 复选框选中属性
• selected 下拉菜单选中属性
• 注意:在 DOM 中元素对象的属性值只有一个时,会被转成布尔值显示。
例如:txt.disabled = true;
案列:
检测用户名是否是3-6位,密码是否是6-8位,如果不满足要求高亮显示文本框
登录:
<input type="text" value="" placeholder="请输入用户名" id="loginName"> <br>密码:
<input type="password" placeholder="请输入密码" id="loginPassword"><br>
<input type="button" value="点击" id="btn">
<script>
var btn = document.getElementById("btn");
//判断
btn.onclick = function() {
var name = document.getElementById("loginName");
var pw = document.getElementById("loginPassword");
if (name.value.length < 3 || name.value.length > 6) {
name.className = "bg";
return;
} else {
name.className = "";
}
if (pw.value.length < 6 || pw.value.length > 8) {
pw.className = "bg";
return;
} else {
pw.className = "";
}
}
</script>
设置下拉框中的选中项 (随机选择)
<input type="button" value="点击" id="btn">
<select name="food" id="list">
<option value="">小龙虾</option>
<option value="">火锅</option>
<option value="">麻辣烫</option>
<option value="">鸡公煲</option>
<option value="">酸辣粉</option>
</select>
<!-- -->
<script>
var btn = document.getElementById("btn");
var list = document.getElementById("list");
var opts = list.getElementsByTagName("option");
btn.onclick = function() {
var num = Math.floor((Math.random()) * opts.length);
opts[num].selected = true;
};
</script>
搜索文本框 (获取焦点、失去焦点)
<input type="text" class="grey" value="请输入搜索内容" id="search">
<input type="button" value="搜索" id="btn">
<script>
var search = document.getElementById("search");
var btn = document.getElementById("btn");
// 设置高亮
search.onfocus = function() {
if (search.value === "请输入搜索内容") {
this.className = "black";
this.value = "";
}
};
search.onblur = function() {
if (search.value == "" || search.value == "请输入搜索内容") {
this.value = "请输入搜索内容";
this.className = "grey";
}
};
</script>
全选反选
<div class="wrap">
<table>
<thead>
<tr>
<td><input type="checkbox" id="all"></td>
<td>商品</td>
<td>价钱</td>
</tr>
</thead>
<tbody id="tb">
<tr>
<td><input type="checkbox"></td>
<td>iphone8</td>
<td>8000</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>ipad Pro</td>
<td>5000</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>ipad Air</td>
<td>4000</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Apple Watch</td>
<td>2000</td>
</tr>
</tbody>
</table>
<input type="button" value="反选" id="btn">
</div>
<script>
// 获取元素
var all = document.getElementById("all");
var tb = document.getElementById("tb");
var tb_input = tb.getElementsByTagName("input");
var btn = document.getElementById("btn");
// 全选
all.onclick = function() {
for (var i = 0; i < tb_input.length; i++) {
tb_input[i].checked = all.checked;
}
};
// 单选去全选
for (var i = 0; i < tb_input.length; i++) {
tb_input[i].onclick = function() {
// 判断所有子选项是否都是选中的状态
allChecked();
};
}
// 反选 与之前的状态相反
btn.onclick = function() {
for (var i = 0; i < tb_input.length; i++) {
tb_input[i].checked = !tb_input[i].checked;
}
allChecked();
};
// 定义isAllChecked函数
function allChecked() {
var isAllChecked = true;
for (var i = 0; i < tb_input.length; i++) {
if (tb_input[i].checked === false) {
isAllChecked = false;
break;
}
}
all.checked = isAllChecked;
}
</script>
自定义属性操作
<div id="box" age="18" sex="男">小明</div>
对于标签的自身属性可以通过打点的方式获取
console.log(box.id);
对于自定义的属性获取可以调用元素对象getAttribute
console.log(box.getAttribute("age"));
console.log(box.getAttribute("sex"));
也可以调用自有的属性
console.log(box.getAttribute("id"));
设置属性,添加新的自定义属性或者自有属性,修改属性setAttribute
box.setAttribute("name", "小明");
box.setAttribute("age", "20");
移出属性 removeAttribute
box.removeAttribute("age");
style样式属性操作
console.log(box.style);
box.style.width = "200px";
1.使用style属性方式设置的样式会显示在标签行内
2.element.style属性的值,是所有行内样式组成的一个样式对象
3.可以通过点语法去调用或者更改行内样式
4.复合属性即多个单词组成,要修改为驼峰命名方式
5.在设置宽高、位置等的属性时,需要加上px等单位
className类名属性操作
修改元素的 className 属性相当于直接修改标签的类名。
如果需要修改多条 css 样式,可以提前将修改后的样式设置到一个类选择器中,后续通过修改类名的方式,批量修改 css 样式
.cls{
width:100px;
height:100px;
background-color:pink;
}
box.className = "cls";
案例
开关灯
<input type="button" value="关灯" id="btn">
<script>
var btn = document.getElementById("btn");
// var isOpen = true;
// btn.onclick = function() {
// if (isOpen) {
// document.body.style.backgroundColor = "black";
// this.value = "开灯";
// isOpen = false;
// } else {
// document.body.style.backgroundColor = "white";
// this.value = "关灯";
// isOpen = true;
// }
// }
btn.onclick = function() {
if (this.value === "关灯") {
document.body.style.backgroundColor = "black";
this.value = "开灯";
} else {
document.body.style.backgroundColor = "white";
this.value = "关灯";
}
}
</script>
body是封装在document对象中,可以直接调用
图片切换二维码案例
<div class="box" id="box">
<div class="erweima hide" id="er">
<img src="images/456.png" alt="">
</div>
</div>
<script>
var box = document.getElementById("box");
var er = document.getElementById("er");
box.onmouseover = function() {
er.className = "erweima show";
}
box.onmouseout = function() {
er.className = "hide";
}
</script>
当前输入的文本框高亮显示
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<button id="btn">提交</button>
<script>
var txts = document.getElementsByTagName("input");
for (var i = 0; i < txts.length; i++) {
txts[i].onfocus = function() {
for (var j = 0; j < txts.length; j++) {
txts[j].style.backgroundColor = "";
}
this.style.backgroundColor = "yellow";
};
}
</script>
点击按钮改变div的大小和位置
<style>
div {
width: 100px;
height: 100px;
background-color: pink;
}
.new {
width: 200px;
height: 200px;
position: absolute;
left: 50px;
top: 50px;
}
</style>
<input type="button" value="按钮" id="btn">
<div id="box"></div>
<script>
var btn = document.getElementById("btn");
var box = document.getElementById("box");
btn.onclick = function() {
//修改类名
// box.className = "new";
//更改或者添加属性
box.style.width = "200px";
box.style.height = "200px";
box.style.position = "absolute";
box.style.top = "200px";
box.style.left = "200px";
}
</script>
表格隔行变色、高亮显示
<style>
td {
width: 100px;
height: 50px;
}
</style>
<table border="1" style="border-collapse: collapse;">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<script>
var trs = document.getElementsByTagName("tr");
for (var i = 0; i < trs.length; i++) {
if (i % 2 == 0) {
trs[i].style.backgroundColor = "pink";
} else {
trs[i].style.backgroundColor = "skyblue";
}
var bgc;
trs[i].onmouseover = function() {
bgc = this.style.backgroundColor;
this.style.backgroundColor = "yellow";
}
trs[i].onmouseout = function() {
this.style.backgroundColor = bgc;
}
}
</script>
tab选项卡切换
<style>
.box {
width: 400px;
height: 300px;
border: 1px solid black;
overflow: hidden;
}
.hd {
height: 45px;
}
.hd span {
display: inline-block;
width: 90px;
line-height: 45px;
text-align: center;
background-color: pink;
}
.hd span.current {
background-color: skyblue;
}
.bd div {
height: 255px;
background-color: skyblue;
display: none;
}
.bd div.current {
display: block;
}
</style>
<div class="box" id="box">
<div class="hd" id="hd">
<span class="current">体育</span>
<span>娱乐</span>
<span>新闻</span>
<span>综合</span>
</div>
<div class="bd" id="bd">
<div class="current">这是体育模块</div>
<div>这是娱乐模块</div>
<div>这是新闻模块</div>
<div>这是综合模块</div>
</div>
</div>
<script>
var hd = document.getElementById("hd");
var spans = hd.getElementsByTagName("span");
var bd = document.getElementById("bd");
var divs = bd.getElementsByTagName("div");
for (var i = 0; i < spans.length; i++) {
spans[i].index = i; //添加一个新属性记录下标
spans[i].onmouseover = function() {
for (var j = 0; j < spans.length; j++) {
spans[j].className = "";
divs[j].className = "";
}
this.className = "current";
divs[this.index].className = "current";
};
}
</script>
排他思想:
第一步: 排除其他的方法,就是将所有的项都恢复默认
第二步:保留自己,设置自己的特殊样式
对应控制思想:
当两组数据中存储了相同个数的元素时,一组数据变化时,会引起另一组变化
方法:找到两组数据的共同点,
DOM节点操作
节点属性:
- nodeType 节点类型 属性值:数字 只读 有12种,其中1为元素节点,2为属性节点,3为文本节点
- nodeName 标签名称 只读
- nodeValue 节点值,返回或设置当前节点的值,其中元素节点 的nodeValue始终是null
父子节点常用属性
-
childNodes 只读属性,获取一个节点所有子节点的实时的集合,集合是动态变化的。
-
children 只读属性,返回一个节点所有的子元素节点集合,是一个动态更新的 HTML 元素 集合。
-
firstChild 只读属性,返回该节点的第一个子节点,如果该节点没有子节点则返回 null。
-
lastChild 只读属性,返回该节点的最后一个子节点,如果该节点没有子节点则返回 null。
-
parentNode 返回一个当前节点的父节点,如果没有这样的节点,比如说像这个节点是树结构 的顶端或者没有插入一棵树中,这个属性返回 null。
-
parentElement 返回当前节点的父元素节点,如果该元素没有父节点,或者父节点不是一个 DOM 元素,则返回 null。
<div id="box">
<p> 这是一段文字</p>
<span>这是一个span标签</span>
</div>
<script>
var box = document.getElementById("box");
console.log(box.childNodes);
console.log(box.children);
console.log(box.firstChild);
console.log(box.lastChild);
console.log(box.lastElementChild);
console.log(box.parentNode);
console.log(box.parentElement);
</script>
兄弟节点常用属性
-
nextSibling 只读属性,返回与该节点同级的下一个节点,如果没有返回null。
-
previousSibling 只读属性,返回与该节点同级的上一个节点,如果没有返回null。
-
nextElementSibling 只读属性,返回与该节点同级的下一个元素节点,如果没有返回null。
-
previousElementSibling 只读属性,返回与该节点同级的上一个元素节点,如果没有返回null。
注意:nextElementSibling 和 previousElementSibling 有兼容性问题,IE9以后才支持。
创建新节点的方法
-
document.createElement(“div”) 创建元素节点
-
document.createAttribute(“id”) 创建属性节点
-
document.createTextNode(“hello”) 创建文本节点
一般将创建的新节点存在变量中,方便使用。
<div id="box">
<p>text1</p>
<p>text2</p>
<p>text3</p>
</div>
<script>
var div = document.createElement("div");
console.dir(div);
var cls = document.createAttribute("class");
console.dir(cls);
var txt = document.createTextNode("hello");
console.dir(txt);
</script>
节点常用操作
-
添加
parentNode.appendChild(child):将一个节点添加到指定父节点的子节点列表末尾。
box.appendChild(div); div.appendChild(txt);
-
替代
parentNode.replaceChild(newChild, oldChild):用指定的节点替换当前节点的一个子节 点,并返回被替换掉的节点。
box.replaceChild(div, p2);
-
插入
parentNode.insertBefore(newNode, referenceNode):在参考节点之前插入一个拥有指定 父节点的子节点,referenceNode 必须设置,如果 referenceElement 为 null 则 newNode 将被插入到子节点的末尾。
box.insertBefore(div, p2);
-
移出
parentNode.removeChild(child):移除当前节点的一个子节点。这个子节点必须存在于当前节点中。
box.removeChild(div);
-
克隆
Node.cloneNode():克隆一个节点,并且可以选择是否克隆这个节点下的所有内容。参数为 Boolean 布尔值,表示是否采用深度克隆,如果为 true,则该节点的所有后代节点也都会被克隆,如果为 false,则只克隆该节点本身,默认值为 true,节点下的内容会被克隆
注意:克隆时,标签上的属性和属性值也会被复制,写在标签行内的绑定事件可以被复制,但是通过 JavaScript 动态绑定的事件不会被复制。
-
判断是否有子节点
Node.hasChildNodes():没有参数,返回一个 Boolean 布尔值,来表示该元素是否包含有子节点
判断总结:
node.firstChild !== null
node.childNodes.length > 0
node.hasChildNodes()
<div id="box"> <p>段落内容 1</p> <div> <p id="p2">段落内容 2</p> </div> <p>段落内容 3</p> <p>段落内容 4</p> </div> <div id="demo"></div> <script> var box = document.getElementById("box"); var p2 = document.getElementById("p2"); var demo = document.getElementById("demo"); // 1.hasChildNodes() console.log(box.hasChildNodes()); console.log(p2.hasChildNodes()); console.log(demo.hasChildNodes()); //2.firstChild。length; console.log(box.firstChild != null); console.log(p2.firstChild != null); console.log(demo.firstChild != null); //3.childNodes.length console.log(box.childNodes.length > 0); console.log(p2.childNodes.length > 0); console.log(demo.childNodes.length > 0); </script>
-
判断是否有此节点
Node.contains(child):返回一个 Boolean 布尔值,来表示传入的节点是否为该节点的后代节点
//判断是否有后节点 console.log(box.contains(p2));
案列:
动态创建列表
<div id="box">
</div>
<script>
var box = document.getElementById("box");
// 添加数据
var food = ["小龙虾", "酸辣粉", "串串", "麻辣烫", "火锅", "干锅"]
//生成ul元素
var ul = document.createElement("ul");
//添加元素到box中
box.appendChild(ul);
// 根据数据添加li
for (var i = 0; i < food.length; i++) {
var li = document.createElement("li");
ul.appendChild(li);
li.innerText = food[i];
}
</script>
动态创建表格
<style>
th,
td {
width: 100px;
height: 40px;
text-align: center;
}
</style>
<h1>动态创建表格</h1>
<table border="1" style="border-collapse: collapse;">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tb">
</tbody>
</table>
<script>
var tb = document.getElementById("tb");
//添加数据
var datas = [{
name: "zs",
subject: "语文",
score: "80"
}, {
name: "cc",
subject: "数学",
score: "76"
}, {
name: "dl",
subject: "英语",
score: "90"
}, {
name: "yy",
subject: "生物",
score: "83"
}, {
name: "lld",
subject: "地理",
score: "90"
}, {
name: "sq",
subject: "物理",
score: "96"
}];
//生成tr
for (var i = 0; i < datas.length; i++) {
var tr = document.createElement("tr");
tb.appendChild(tr);
var data = datas[i];
for (var k in data) {
var td = document.createElement("td");
tr.appendChild(td);
td.innerText = data[k];
}
var td = document.createElement("td");
tr.appendChild(td);
var a = document.createElement("a");
td.appendChild(a);
a.innerText = "删除";
a.href = "javaScript:void(0);";
a.onclick = function() {
tb.removeChild(this.parentNode.parentNode);
}
}
</script>
选择水果
<style>
select {
width: 200px;
height: 200px;
background-color: pink;
font-size: 18px;
}
</style>
<select name="" id="all" multiple="multiple">
<option value="">苹果</option>
<option value="">梨</option>
<option value="">哈密瓜</option>
<option value="">西瓜</option>
<option value="">橘子</option>
</select>
<input type="button" value=">>" id="btn1">
<input type="button" value="<<" id="btn2">
<input type="button" value=">" id="btn3">
<input type="button" value="<" id="btn4">
<select name="" id="choose" multiple="multiple"></select>
<script>
var all = document.getElementById("all");
var choose = document.getElementById("choose");
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var btn3 = document.getElementById("btn3");
var btn4 = document.getElementById("btn4");
btn1.onclick = function() {
var opts = all.children;
var n = opts.length; //opts.length的值会随着元素到choose中而减小,不固定
for (var i = 0; i < n; i++) {
choose.appendChild(opts[0]);
}
}
btn2.onclick = function() {
// var opts = choose.children;
// var n = opts.length;
// for (var i = 0; i < n; i++) {
// all.appendChild(opts[0]);
// }
fun1(choose, all);
}
btn3.onclick = function() {
var opts = all.children;
var arr = [];
for (var i = 0; i < opts.length; i++) {
if (opts[i].selected === true) {
arr.push(opts[i]);
}
}
for (var i = 0; i < arr.length; i++) {
choose.appendChild(arr[i]);
arr[i].selected = false;
}
}
btn4.onclick = function() {
// var opts = choose.children;
// var arr = [];
// for (var i = 0; i < opts.length; i++) {
// if (opts[i].selected === true) {
// arr.push(opts[i]);
// }
// }
// for (var i = 0; i < arr.length; i++) {
// all.appendChild(arr[i]);
// arr[i].selected = false;
// }
fun2(choose, all);
}
//btn1,btn2的函数
function fun1(a, b) {
var opts = a.children;
var n = opts.length;
for (var i = 0; i < n; i++) {
b.appendChild(opts[0]);
}
}
//btn3,btn4的函数
function fun2(a, b) {
var opts = a.children;
var arr = [];
for (var i = 0; i < opts.length; i++) {
if (opts[i].selected === true) {
arr.push(opts[i]);
}
}
for (var i = 0; i < arr.length; i++) {
b.appendChild(arr[i]);
arr[i].selected = false;
}
}
</script>
注册事件的其他方法
-
element.addEventListener() 方法。
参数:
第一个参数:事件类型的字符串(直接书写”click”,不需要加 on)
第二个参数:事件函数
同一个元素可以多次绑定事件监听,同一个事件类型可以注册多个事件函数
兼容性问题:不支持 IE9 以下的浏览器
<input type="button" value="按钮" id="btn">
<script>
var btn = document.getElementById("btn");
// 绑定DOM0级
btn.onclick = function() {
alert(111);
};
//绑定DOM1级
btn.addEventListener("click", function() {
alert(222);
});
//多次绑定
btn.addEventListener("click", function() {
alert(333);
});
</script>
2.element.attachEvent() 方法。
参数:
第一个参数:事件类型的字符串(需要加 on)
第二个参数:事件函数
同一个元素可以多次绑定事件监听,同一个事件类型可以注册多个事件函数
兼容性问题:只支持 IE10 及以下的浏览器
btn.attachEvent("onclick",function () {
alert(3);
});
btn.attachEvent("onclick",clickEvent);
function clickEvent() {
alert(4);
}
3.自定义一个注册事件函数
参数:事件源,事件类型(不加 on),事件函数
IE9 及以上的浏览器,使用 addEventListener 方法
IE9 以下的浏览器,使用 attachEvent 方法
判断浏览器时,不需要判断它的版本,可以检测浏览器能力
浏览器能力检测:将某个方法的调用作为 if 语句的判断条件,如果浏览器认识该方法返回true,否则返回 false。
<input type="button" value="按钮" id="btn">
<script>
var btn = document.getElementById("btn");
addEvent(btn, "click", function() {
alert(222);
});
// 自定义函数
function addEvent(ele, type, fn) {
if (ele.addEventListener) {
ele.addEventListener(type, fn);
} else if (ele.attachEvent) {
ele.attachEvent("on" + type, fn)
}
};
移出事件的其他方法
1.ele.οnclick=null
btn.onclick = null;
2.element.removeEventListener() 方法。
参数:
第一个参数:事件类型的字符串(直接书写”click”,不需要加 on)
第二个参数:事件函数引用名
注意:没有办法移除一个匿名函数,所以在注册事件时需要单独声明一个有函数名的事件函数。
兼容性问题:不支持 IE9 以下的浏览器
btn.addEventListener("click", fun);
btn.removeEventListener("click", fun);
3.element.detachEvent() 方法。
参数:
第一个参数:事件类型的字符串(需要加 on)
第二个参数:事件函数
注意:没有办法移除一个匿名函数,所以在注册事件时需要单独声明一个有函数名的事件函数。
兼容性问题:只支持 IE10 及以下的浏览器
btn.attachEvent("onclick", fun);
btn.detachEvent("onclick", fun);
4.自定义一个移出事件函数
参数:事件源,事件类型(不加 on),事件函数
IE9 及以上的浏览器,使用 removeEventListener 方法
IE9 以下的浏览器,使用 detachEvent 方法
建议:将自己封装的一些常用函数和方法,放到一个单独的 .js 文件中。
function removeEvent(ele, type, fn) {
if (ele.removeEventListener) {
ele.removeEventListener(type, fn);
} else if (ele.detachEvent) {
ele.detachEvent("on" + type, fn);
}
}
DOM事件流
三阶段
第一阶段:事件捕获(从当前层往下走)
第二阶段:事件执行过程
第三阶段:事件冒泡(从当前层往上走)
addEventListener() 第三个参数为 false 时,事件冒泡 ,addEventListener() 第三个参数为 true 时,事件捕获
onclick 类型:只能进行事件冒泡过程,没有捕获阶段
attachEvent() 方法:只能进行事件冒泡过程,没有捕获阶段
事件委托
利用事件冒泡,将子级的事件委托给父级加载
案列:给点击的无序列表添加背景
<ul id="list">
<li>小龙虾</li>
<li>小面</li>
<li>火锅</li>
<li>干锅</li>
<li>麻辣烫</li>
</ul>
<script>
var list = document.getElementById("list");
var lis = list.children;
list.onclick = function(e) {
for (var i = 0; i < lis.length; i++) {
lis[i].style.backgroundColor = "";
}
e.target.style.backgroundColor = "pink";
}
</script>
事件对象
只要触发事件,就会有一个对象,内部存储了与事件相关的数据。
e 在低版本浏览器中有兼容问题,低版本浏览器使用的是 window.event
事件对象常用的属性:
e.eventPhase 查看事件触发时所处的阶段
console.log(e.eventPhase);
1:捕获阶段 2:目标阶段 3:冒泡阶段
e.target 用于获取触发事件的元素
e.srcElement 用于获取触发事件的元素,低版本浏览器使用
var target = e.target || e.scrElement;
console.log(target);
e.currentTarget 用于获取绑定事件的事件源元素
console.log(e.currentTarget);
e.type 获取事件类型
console.log(e.type);
大多数时候,会给同一个对象添加不同的事件类型,对应执行的代码不同
box3.onmouseover = fn;
box3.onmouseout = fn;
function fn(e) {
e = e || window.event;
switch (e.type) {
case "mouseover":
box3.style.backgroundColor = "black";
break;
case "mouseout":
box3.style.backgroundColor = "yellow";
break;
}
}
e.clientX/e.clientY 所有浏览器都支持,鼠标距离浏览器窗口左上角的距离
console.log(e.clientX);
console.log(e.clientY);
e.pageX/e.pageY IE8 以前不支持,鼠标距离整个HTML页面左上顶点的距离
console.log(e.pageX);
console.log(e.pageY);
案列
<style>
#pic {
position: fixed;
}
</style>
<img src="images/tianshi.gif" alt="" id="pic">
<script>
var pic = document.getElementById("pic");
document.onmousemove = function(e) {
e = e || window.event;
pic.style.left = e.pageX + "px";//一定要加单位
pic.style.top = e.pageY + "px";
}
</script>
取消默认行为
1.普通方式 return false;
2.DOM的方式 e.preventDefault(); 低版本:e.returnValue=false;
阻止事件传播
1.e.stopPropagation(); 阻止冒泡,标准方式
2.e.cancelBubble = true; 阻止冒泡,IE 低版本,标准中已废弃
DOM特效
偏移量属性
offsetParent 偏移参考父级,距离自己最近的有定位的父级,如果都没有定位参考body(html)
offsetLeft/offsetTop 偏移位置
offsetWidth/offsetHeight 偏移大小(width+padding+border)
客户端大小
clientLeft/clientTop 边框区域尺寸,不常用
clientWidth/clientHeight 边框内部大小
滚动偏移属性
scrollLeft/scrollTop 盒子内部滚动出去的尺寸
scrollWidth/scrollHeight 盒子内容的宽度和高度
案列
拖拽
<style>
* {
margin: 0;
padding: 0;
}
.nav {
height: 30px;
background-color: #036663;
line-height: 30px;
padding-left: 30px;
}
.nav a {
color: #fff;
font-size: 14px;
text-decoration: 30px;
}
.d-box {
width: 400px;
height: 300px;
border: 5px solid #eee;
position: absolute;
top: 40%;
left: 40%;
background-color: #fff;
/* 不让文字被选中 */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.d-box .hd {
width: 100%;
height: 25px;
background-color: #7c9299;
color: #fff;
line-height: 25px;
cursor: move;
}
.close {
float: right;
cursor: pointer;
}
</style>
<div class="nav">
<a href="javaScript:void(0);">注册信息</a>
</div>
<div class="d-box" id="d_box">
<div class="hd" id="hd">
注册信息(可以拖拽)
<span class="close" id="close">【关闭】</span>
</div>
<div class="bd"></div>
</div>
<script>
var box = document.getElementById("d_box");
var drop = document.getElementById("hd");
var close = document.getElementById("close");
drop.onmousedown = function(e) {
e = e || window.event;
// 记忆当前鼠标在内部的距离
var l = e.pageX - box.offsetLeft;
var t = e.pageY - box.offsetTop;
drop.onmousemove = function(e) {
e = e || window.event;
var newl = e.pageX - l;
var newt = e.pageY - t;
box.style.left = newl + "px";
box.style.top = newt + "px";
};
};
// 当鼠标弹起后移动事件取消
drop.onmouseup = function() {
drop.onmousemove = null;
};
//点击关闭box
close.onclick = function() {
box.style.display = "none";
}
</script>
弹出层
<style>
ul,
li,
ol,
dl,
dt,
dd,
div,
p,
span,
h1,
h2,
h3,
h4,
h5,
h6,
a {
padding: 0px;
margin: 0px;
}
a {
text-decoration: none;
color: #000;
}
.login-header {
width: 100%;
height: 30px;
font-size: 24px;
line-height: 30px;
text-align: center;
}
.login {
width: 512px;
height: 280px;
position: absolute;
left: 50%;
margin-left: -256px;
margin-top: 140px;
border: 1px solid #ebebeb;
background-color: #fff;
z-index: 9999;
display: none;
}
.title {
position: relative;
width: 100%;
margin: 10px 0px 0px 0px;
text-align: center;
line-height: 40px;
font-size: 18px;
cursor: move;
-moz-user-select: none;
/*火狐*/
-webkit-user-select: none;
/*webkit浏览器*/
-ms-user-select: none;
/*IE10*/
-khtml-user-select: none;
/*早期浏览器*/
user-select: none;
}
.title .close {
position: absolute;
right: -20px;
top: -30px;
width: 40px;
height: 40px;
border-radius: 20px;
background-color: #fff;
border: 1px solid #ebebeb;
font-size: 14px;
cursor: pointer;
}
.login-input-content {
margin-top: 20px;
}
.login-input {
overflow: hidden;
margin: 0 0 20px 0;
}
.login-input label {
float: left;
width: 90px;
text-align: right;
font-size: 14px;
height: 35px;
line-height: 35px;
}
.login-input .list-input {
float: left;
width: 350px;
height: 35px;
line-height: 35px;
border: 1px solid #ebebeb;
text-indent: 5px;
}
.loginBtn {
width: 50%;
height: 40px;
border: 1px solid #ebebeb;
text-align: center;
line-height: 40px;
margin: 30px auto 0;
font-size: 14px;
}
.login-bg {
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background-color: #000;
opacity: 0.3;
-moz-opacity: 0.3;
-khtml-opacity: 0.3;
filter: alpha(opacity=30);
display: none;
}
</style>
<div class="login-header"><a href="javaScript:void(0);" id="link">点击弹出登录框</a></div>
<div class="login" id="login">
<div class="title" id="login_title">登录会员
<span class="close" id="close">关闭</span>
</div>
<div class="login-input-content">
<div class="login-input">
<label for="">用户名:</label>
<input type="text" placeholder="请输入用户名" id="userName" class="list-input">
</div>
<div class="login-input">
<label for="">密码:</label>
<input type="text" placeholder="请输入用户密码" id="password" class="list-input">
</div>
</div>
<div class="loginBtn" id="loginBtn"><a href="javaScript:void(0);">登录会员</a> </div>
</div>
<div id="bg" class="login-bg"></div>
<script>
var link = document.getElementById("link");
var close = document.getElementById("close");
var bg = document.getElementById("bg");
var login = document.getElementById("login");
link.onclick = function() {
login.style.display = "block";
bg.style.display = "block";
}
close.onclick = function() {
login.style.display = "none";
bg.style.display = "none";
}
</script>
上一篇: 部分代码3
下一篇: 书小宅之网页设计——基本概念