web api 概述
标准库:ECMAScript中的对象和函数
Web Api:浏览器宿主环境中的对象和函数
- 知识繁杂
- 成体系的知识
- 程序思维:知识+程序思维 = 应用
- 兼容性:了解,不记忆
Web Api:
- BOM:Browser Object Model,浏览器对象模型
- DOM:Document Object Model,文档对象模型
BOM:控制浏览器本身
DOM:控制HTML文档
ES 由 ECMAScript 规定的
WebApi 由 W3C(万维网联盟) 制定
关于DOM
- DOM 0
- DOM 1
- DOM 2
- DOM 3
- DOM 4 2015年
DOM是什么
DOM的核心理念,是将一个HTML或XML文档,用对象模型表示,每个对象称之为dom对象
dom对象又称之为节点Node
节点的类型:
- DocumentType,文档类型节点
- Document,文档节点,表示整个文档
- Comment,注释节点
- Element,元素节点
- Text,文本节点
- Attribute,属性节点
- DocumentFragment,文档片段节点
dom树:文档中不同的节点形成的树形结构。
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标题</title>
</head>
<body>
<!-- 注释 -->
<p>lorem</p>
</body>
</html>
获取dom节点
获取dom对象
全局对象 window 中有属性document,代表的是整个文档节点
旧的获取元素节点的方式
dom 0
- document.body:获取body元素节点
- document.head:获取head元素节点
- document.links:获取页面上所有的超链接元素节点,类数组
获取多个节点 返回的一般都是伪数组
- document.anchors:获取页面上所有的锚链接(具有name属性)元素节点
最早的时候 锚链接并不是 id 而是 name
- document.forms:获取页面中所有的form元素节点
- document.documentElement: 获取根元素
html
新的获取元素节点的方式
通过方法获取
- document.getElementById:通过id获取对应id的元素
document.getElementsByTagName
(链): 通过元素名称获取元素document.getElementsByClassName
(链):通过元素的类样式获取元素,IE9以下无效- document.getElementsByName:通过元素的name属性值获取元素
document.querySelector
(链):通过CSS选择器获取元素,得到匹配的第一个,IE8以下无效document.querySelectorAll
(链):通过CSS选择器获取元素,得到所有匹配的结果,IE8以下无效
细节:
- 在所有的得到类数组的方法中,除了querySelectorAll,其他的方法都是实时更新的。
- getElementById 得到元素执行效率最高。
- 书写了id的元素,会自动成为window对象的属性。它是一个实时的单对象。事实上的标准。不推荐使用。
导致的主要问题: 1. 全局污染; 2. 实时单对象...被删除导致对象消失...无法获取数据
- getElementsByTagName、getElementsByClassName、querySelector、querySelectorAll,可以作为其他元素节点对象的方法使用
==> 链式操作
根据节点关系获取节点
- parentNode:获取父节点(元素、文档)
==> 获取到的是元素节点 因为是父级 比较特殊... 下面其他的则不同 获取到的就不一定是元素节点了 文本 注释 啥的都有可能
- previousSibling:获取上一个兄弟节点
- nextSibling:获取下一个兄弟节点
- childNodes:获取所有的子节点
- firstChild:获取第一个子节点
- lastChild:获取最后一个子节点
- attributes: 获取某个元素的属性节点
获取元素节点这个才是咋们需要的 因为我们需要操作的一般都是dom元素 没事获取文本节点, 注释节点干啥..
- parentElement:获取父元素
- previousElementSibling:获取上一个兄弟元素
IE9
- nextElementSibling:获取下一个兄弟元素
IE9
- children:获取子元素
- firstElementChild:获取第一个子元素
IE9
- lastElementChild:获取最后一个子元素
IE9
获取节点信息
- nodeName:获取节点名称
获取到的dom节点名称 是大写的字符串形式 如:'DIV'
- nodeValue:获取节点的值
- nodeType:节点类型,是一个数字
不要记
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>旧的获取元素节点的方式</title>
</head>
<body>
<form action="">
<a href="">Lorem.</a>
<a href="">Beatae?</a>
<a href="">At.</a>
<a href="" name="abc">Inventore.</a>
<a href="">Facere.</a>
<a href="">Magnam.</a>
<a href="">Voluptate?</a>
<a href="">Consequatur.</a>
<a href="">Temporibus?</a>
<a href="">Quos!</a>
</form>
<form action="">
<ul>
<li><a href="">Lorem.</a></li>
<li><a href="">Suscipit.</a></li>
<li><a href="" name="bcd">Corrupti.</a></li>
<li><a href="">Ut!</a></li>
<li><a href="">Explicabo!</a></li>
<li><a href="">Dignissimos.</a></li>
<li><a href="">Quaerat!</a></li>
<li><a href="">Non?</a></li>
<li><a href="">Facilis?</a></li>
<li><a href="">Magnam!</a></li>
</ul>
</form>
<script>
// 旧的获取元素节点的方式 目前只有 ==> document.body 还有点用 别的基本没啥用
console.log(document.body) // ==> 获取body节点
console.log(document.head) // ==> 获取head节点
console.dir(document.head) // ==> dir ==> 打印对象结构 log 打印元素结构
console.log(document.links, Array.isArray(document.links)) // ==> 获取页面上所有的超链接元素节点,类数组
console.log(document.anchors) // ==> 获取页面上所有的锚链接(具有name属性)元素节点
console.log(document.forms) // ==> 获取页面中所有的form元素节点
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新的获取元素节点的方式</title>
</head>
<body>
<div name="n" id="score" class="abc">123</div>
<div id="mydiv2" class="abc">456</div>
<div name="n">asdfasdfasf</div>
<ul>
<li>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Pariatur reprehenderit nobis expedita
quibusdam nulla sapiente amet nam iusto id neque in, laborum optio repellendus rerum quos est laboriosam
tempore cum?</div>
</li>
<li>
<div>Quos, quibusdam nobis consectetur quis quae maxime ad culpa eligendi ut, nisi totam, assumenda magni
adipisci fugiat rem beatae minima aliquam odio vitae earum deleniti! Consectetur perferendis distinctio
reiciendis! Magnam!</div>
</li>
<li>
<div>Mollitia iure tempora rem nemo dignissimos necessitatibus, modi est harum amet cumque? Facere eaque
provident excepturi, labore blanditiis voluptatibus cumque autem sed beatae atque eos tenetur, quasi,
quidem rem vel?</div>
</li>
<li>
<div>Nisi consequatur eveniet ea? Nesciunt, laborum minima soluta quasi facilis eligendi aspernatur
accusamus quod quidem corporis perferendis ut accusantium? Inventore quam enim sed non nulla aspernatur
architecto maxime, sit vitae?</div>
</li>
<li>
<div>Natus, hic dolorum? Harum maiores, laudantium error quod quia laborum. Fugit reiciendis ipsum cumque
placeat numquam asperiores optio harum quibusdam consequatur eveniet doloribus officiis eum earum alias,
tenetur vero quis.</div>
</li>
<li>
<div>Eligendi a voluptates alias praesentium libero, necessitatibus deserunt quia est laudantium nihil, at
dolorem consequatur esse molestiae totam tempore eos commodi. Tempore, non quo. Autem dignissimos
deleniti velit non nulla!</div>
</li>
<li>
<div>Ex eveniet in iste esse? Distinctio ratione animi nemo quisquam molestias id similique dignissimos
suscipit asperiores? Dignissimos, natus itaque, quod autem aut voluptatum, neque quisquam expedita odit
enim laudantium esse.</div>
</li>
<li>
<div>Optio, natus aut. Quas eaque officia, esse facere architecto, quia ut laboriosam commodi exercitationem
totam quis voluptas, accusamus dolorum illo. Alias at iste, est hic obcaecati reprehenderit veniam saepe
veritatis.</div>
</li>
<li>
<div>Quos soluta provident nisi corporis mollitia harum distinctio laborum doloremque? Aperiam quam corrupti
deserunt odit voluptates iusto nemo officiis dolor consequatur maxime molestiae minus in totam, quia
quibusdam modi laudantium!</div>
</li>
<li>
<div>Veritatis, nisi. In nam, ratione incidunt aut minus quod eius placeat dicta hic! Eum laboriosam error
molestiae provident sequi. Labore cumque deleniti corporis commodi quibusdam vero? Excepturi fugit culpa
autem.</div>
</li>
</ul>
<script>
// document.getElementById ==> 通过id获取对应id的元素 ==> 细节: 1. 多个同id的节点 只选中第一个; 2. 找不到对应id的节点 则返回 null; 3. 兼容性很好
console.log(document.getElementById('mydiv2'))
// document.getElementsByTagName: 通过元素名称获取元素
console.log(document.getElementsByTagName('div')[0])
// document.getElementsByClassName ==> 通过元素的类样式获取元素 ==> 细节: 1. IE9以下无效(兼容性)
console.log(document.getElementsByClassName('abc'))
// document.getElementsByName ==> 通过元素的name属性值获取元素
console.log(document.getElementsByName('n'))
// document.querySelector ==> 通过CSS选择器获取元素 ==> 细节: 1. IE8以下无效(兼容性); 2. 得到匹配的第一个
console.log(document.querySelector("#mydiv2"))
console.log(document.getElementsByClassName('abc')[0] === document.querySelector(".abc")); // true
// document.querySelectorAll ==> 通过CSS选择器获取元素 ==> 细节: 1. IE8以下无效(兼容性); 2. 得到所有的匹配结果
console.log(document.querySelectorAll("ul li div")[0]);
// document.documentElement ==> 获取根元素
// 细节:
// 1. 在所有的得到类数组的方法中,除了querySelectorAll,其他的方法都是实时更新的。
// 2. getElementById 得到元素执行效率最高。
// 3. 书写了id的元素,会自动成为window对象的属性。它是一个实时的单对象。事实上的标准。不推荐使用。
// 4. getElementsByTagName、getElementsByClassName、querySelector、querySelectorAll,可以作为其他元素节点对象的方法使用
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>根据节点关系获取节点</title>
</head>
<body>
<div class="container">
<ul class="list">
<li><a href="">Lorem ipsum dolor sit.</a></li>
<li>
<!-- 注释 -->
啊手动阀手动阀 <a href="https://www.baidu.com" title="阿三发射点发 撒旦发生">Laboriosam commodi quis at!</a>
</li>
<li><a href="">Placeat sit quae necessitatibus.</a></li>
<li><a href="">Rem ducimus adipisci impedit.</a></li>
<li><a href="">Facere corrupti qui consequatur?</a></li>
<li><a href="">Molestias rerum aperiam eveniet.</a></li>
<li><a href="">Quas assumenda quae cumque!</a></li>
<li><a href="">Unde quas exercitationem corrupti.</a></li>
<li><a href="">Necessitatibus nobis tempore dolorum.</a></li>
<li><a href="">Accusamus excepturi iusto corporis.</a></li>
</ul>
</div>
<script>
var a = document.querySelectorAll('.container .list li a')[1]
// parentNode ==> 获取父节点(元素、 文档) ==> 获取到的一般是元素
console.log(a);
console.log(a.parentNode); // a
console.log(a.parentNode.parentNode); // li
console.log(a.parentNode.parentNode.parentNode); // ul.list
console.log(a.parentNode.parentNode.parentNode.parentNode); // div.container
console.log(a.parentNode.parentNode.parentNode.parentNode.parentNode); // body
console.log(a.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode); // html
console.log(a.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode); // null
// previousSibling ==> 获取上一个兄弟节点
console.log(a.previousSibling); // TextNode
console.log(a.previousSibling.previousSibling); // CommentNode
console.log(a.previousSibling.previousSibling.previousSibling); // TextNode ==> 空白也算是文本节点
console.log(a.previousSibling.previousSibling.previousSibling.previousSibling); // null
console.log(document.documentElement.previousSibling); // DocumentType 文档类型节点
// nextSibling ==> 获取下一个兄弟节点
// childNodes ==> 获取所有的子节点
// firstChild ==> 获取第一个子节点
// lastChild ==> 获取最后一个子节点
// attributes ==> 获取某个元素的属性节点
/* 获取元素节点 */
// parentElement ==> 获取父元素
// previousElementSibling ==> 获取上一个兄弟元素
// nextElementSibling ==> 获取下一个兄弟元素
// children ==> 获取子元素
// firstElementChild ==> 获取第一个子元素
// lastElementChild ==> 获取最后一个子元素
</script>
</body>
</html>
[作业讲解]获取dom节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul id="list1">
<li><a href="">Lorem ipsum dolor sit.</a></li>
<li><a href="">Doloremque fuga amet hic.</a></li>
<li><a href="">Officia incidunt veritatis provident?</a></li>
<li><a href="">Repellat eum exercitationem voluptatum?</a></li>
<li><a href="">Soluta repellendus nobis maiores.</a></li>
<li><a href="">Doloribus minima voluptas rerum!</a></li>
<li><a href="">Molestiae nulla doloremque dicta.</a></li>
<li><a href="">Molestiae at sequi corporis.</a></li>
<li><a href="">Atque perspiciatis quaerat quisquam!</a></li>
<li><a href="">Totam fugiat alias officiis?</a></li>
</ul>
<ul id="list2">
<li><a href="">Lorem ipsum dolor sit.</a></li>
<li><a href="">Ipsa quam neque repudiandae.</a></li>
<li><a href="">Tenetur accusantium illo quam!</a></li>
<li><a href="">Quibusdam odit repellendus non.</a></li>
<li><a href="">Placeat officia aut dolores!</a></li>
<li><a href="">Cum nostrum facere nemo.</a></li>
<li><a href="">Impedit nisi nobis quaerat!</a></li>
<li><a href="">Quis nemo tempore ullam.</a></li>
<li><a href="">Voluptate aliquid sed quod.</a></li>
<li><a href="">Nihil mollitia dolores quae!</a></li>
</ul>
<script>
// 准备两个数组,分别存放list1和list2中所有超链接的内容
var list1Links, list2Links;
// 得到某个元素下面的所有a元素的内容数组
function getLinkContents(dom) {
return Array.from(dom.getElementsByTagName("a")).map(function(a) {
return a.firstChild.nodeValue;
})
// var arr = dom.getElementsByTagName("a"); //a元素数组
// var newArr = [];
// for (var i = 0; i < arr.length; i++) {
// var a = arr[i];
// newArr.push(a.firstChild.nodeValue);
// }
// return newArr;
}
list1Links = getLinkContents(document.getElementById("list1"))
console.log(list1Links);
list2Links = getLinkContents(document.getElementById("list2"))
console.log(list2Links);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="container">
<ul>
<li><a href="">Lorem ipsum dolor sit.</a></li>
<li><a href="">Laboriosam esse voluptatibus accusamus!</a></li>
<li><a href="">Minima cumque alias numquam!</a></li>
<li><a href="">Beatae sit quod earum?</a></li>
<li><a href="">Doloremque vitae totam pariatur.</a></li>
<li><a href="">Autem ab iusto quae.</a></li>
<li><a href="">Mollitia accusamus iure maxime.</a></li>
<li><a href="">Sapiente vitae nostrum ex?</a></li>
<li><a href="">Aut quos est amet!</a></li>
<li><a href="">Laudantium dicta fuga debitis.</a></li>
</ul>
</div>
<div class="container2">
<span>asdfasfd</span>
<strong>asdfasdfgasdfa</strong>
<i>asadfasfas</i>
<p>aasdfdasf</p>
<div class="c3">
<p>dfgasdfasfaf</p>
</div>
</div>
<script>
// 写一个函数,传入一个dom对象,返回该对象的第一个div容器
function getDivContainer(dom) {
// var parent = dom.parentElement;
// while (parent && parent.nodeName !== "DIV") {
// parent = parent.parentElement;
// }
// return parent;
for (var parent = dom.parentElement; parent && parent.nodeName !== "DIV"; parent = parent.parentElement) {}
// 注意 这里不能使用 let 因为其具有块级作用域
return parent;
}
var div = getDivContainer(test);
console.log(div);
</script>
</body>
</html>
dom元素操作
初识元素事件
元素事件:某个元素发生一件事 如: 被点击 click
事件处理程序:是一个函数,发生了一件事,应该做什么事情
注册(绑定)事件:将事件处理程序与某个事件关联
this关键字在事件处理程序中指代当前发生的事件元素
获取和设置元素属性
- 通用方式:getAttribute、setAttribute
可识别属性
正常的HTML属性
- dom对象.属性名
推荐
细节:
- 正常的属性即使没有赋值,也有默认值
- 布尔属性在dom对象中,得到的是boolean
如: checked= "checked"
- 某些表单元素可以获取到某些不存在的属性
- 某些属性与标识符冲突,此时,需要更换属性名
自定义属性
HTML5 建议自定义属性使用data-
作为前缀
如果遵从HTML5 自定义属性规范,可以使用dom对象.dataset.属性名
控制属性
删除自定义属性可识别的属性删不掉
- removeAttribute(“属性名”);
- delete dom.dataset.属性名
获取和设置元素内容
- innerHTML:获取和设置元素的内部HTML文本
- innerText:获取和设置元素内部的纯文本,仅得到元素内部显示出来的文本
- textContent:获取和设置元素内部的纯文本,textContent得到的是内部源代码中的文本
元素结构重构
- 父元素.appendChild(元素):在某个元素末尾加入一个子元素
- 父元素.insertBefore(待插入的元素, 哪个元素之前)
- 父元素.replaceChild(替换的元素, 被替换的元素)
细节:
更改元素结构效率较低,尽量少用。
创建和删除元素
创建元素
document.createElement(“元素名”):创建一个元素对象
- document.createTextNode(“文本”)
- document.createDocumentFragment(): 创建文档片段
- … 还有注释呀啥的… 不过基本都不会用
dom.cloneNodes(是否深度克隆):复制一个新的dom对象并返回
childNodes 也是实时集合
删除元素
- removeChild:父元素调用,传入子元素
- remove:把自己删除
test.html
<!-- 事件.html ==> 认识 1. 元素事件 2. 事件处理程序 3. 注册(绑定)事件 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>事件.html</title>
</head>
<body>
<button id="btn">点我</button>
<script>
var btn = document.getElementById("btn");
var count = 0;
//注册事件
btn.onclick = function() {
console.log(count++);
console.log(this, this === btn);
}
</script>
</body>
</html>
<!-- 属性.html ==> 认识可识别属性1 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>属性.html ==> 认识可识别属性</title>
</head>
<body>
<input type="text" value="abc123">
<button id="btnGetTxt">获取文本框内容</button>
<button id="btnSetTxt">设置文本框内容</button>
<script>
var input = document.querySelector("input[type=text]");
document.getElementById("btnGetTxt").onclick = function () {
// 获取文本框的值 ==> input元素中 value 是它的正常属性(可识别属性)
console.log(input.value, typeof input.value); // abc123 string
}
document.getElementById("btnSetTxt").onclick = function () {
input.value = "请输入文本";
console.log('设置后文本框内容为: ', input.value); // 设置后文本框内容为: 请输入文本
}
</script>
</body>
</html>
<!-- 属性.html ==> 认识可识别属性2 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>属性.html</title>
<style>
img {
width: 300px;
height: 300px;
border: 2px solid;
object-fit: contain;
/*
object-fit CSS 属性指定可替换元素的内容应该如何适应到其使用的高度和宽度确定的框。
您可以通过使用 object-position 属性来切换被替换元素的内容对象在元素框内的对齐方式。 */
/* contain ==> 图片的 长-宽 比 保持不变 并尽可能的填满 */
display: block;
}
</style>
</head>
<body>
<img src="1.jpg" alt="">
</div>
<script>
// 点击图片切换
var i = 1; // 第几张图片
var img = document.querySelector("img");
img.onclick = function () {
i++;
if (i === 3) {
i = 1;
}
img.src = i + ".jpg"; // img元素中 src 是它的正常属性(可识别属性)
}
</script>
</body>
</html>
<!-- 属性.html ==> 细节 ==> 1. 正常的(可识别的)属性即使没有赋值 也有默认值 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>属性.html ==> 正常的(可识别的)属性即使没有复制 也有默认值</title>
</head>
<body>
<input type="text">
<button id="btnGetTxt">获取文本框内容</button>
<button id="btnSetTxt">设置文本框内容</button>
<script>
var input = document.querySelector("input[type=text]");
document.getElementById("btnGetTxt").onclick = function () {
// 获取文本框的值 ==> input元素中 value 是它的正常属性(可识别属性)
// 此时没有给 value 属性赋值 但是由于它是正常的属性 所以依旧能获取到它的值 ==> 空字符串 ==> ""
// 所以对于可识别的属性而言 即便一开始没有给它赋值 再后续读取它的值时 也不会报错 而是读到它的默认值
console.log(input.value, typeof input.value); // "" string
}
document.getElementById("btnSetTxt").onclick = function () {
input.value = "请输入文本";
// 对于可识别的属性而言 即便一开始在写元素的时候 没写上该属性(value)
// 后续再对其进行赋值时 依旧不会有影响 不会报错
// 通过js对该属性进行赋值 依旧有效 ==> 见: 页面上的输入框
console.log('设置后文本框内容为: ', input.value); // 设置后文本框内容为: 请输入文本
}
</script>
</body>
</html>
<!-- 属性.html ==> 细节 ==> 2. 布尔属性在dom对象中, 得到的是 boolean 值 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>属性.html ==> 布尔属性在dom对象中, 得到的是 boolean 值</title>
</head>
<body>
<input type="checkbox" checked="checked">
<button id="btnGetTxt">yes</button>
<button id="btnSetTxt">no</button>
<script>
var input = document.querySelector("input[type=checkbox]");
document.getElementById("btnGetTxt").onclick = function () {
input.checked = true; // 也可以直接写成 input.checked = 'checked' 赋值符号右边的值先会隐式的转换为 boolean值之后再进行赋值 所以写个 1 也ok
// 获取复选框的值 ==> input[type=checkbox]元素中 value checked 是它的正常属性(可识别属性)
// 而且 checked 是一个布尔属性 ==> 布尔属性就两种写法: 1. 不写属性值 ==> checked 2. 写属性值则只能写一个值,也就是字符串形式的属性名 checked="checked"
// 如果一个可识别属性 是一个布尔属性 那么 get 到的将会是一个 Boolean 类型的值
console.log(input.checked, typeof input.checked);
}
document.getElementById("btnSetTxt").onclick = function () {
input.checked = false;
console.log(input.checked, typeof input.checked);
}
</script>
</body>
</html>
<!-- 属性.html ==> 细节 ==> 3. 某些表单元素可以获取到某些不存在的属性
下拉列表的读写操作 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>属性.html</title>
</head>
<body>
<select class="sel">
<option value="chengdu">成都</option>
<option value="beijing">北京</option>
<option value="haerbin">哈尔滨</option>
</select>
<button class="btn1">成都</button>
<button class="btn2">北京</button>
<button class="btn3">哈尔滨</button>
<button class="getValue">get</button>
<button class="getNodeValue">getNodeValue</button>
<script>
var oSel = document.querySelector("select.sel")
var Obtn1 = document.querySelector('button.btn1')
var Obtn2 = document.querySelector('button.btn2')
var Obtn3 = document.querySelector('button.btn3')
var getValueBtn = document.querySelector('button.getValue')
var getNodeValueBtn = document.querySelector('button.getNodeValue')
// 注意 js 操作下拉列表 操作的是 option 元素中的 value 属性 而不是 nodeValue
Obtn1.onclick = function () {
oSel.value = 'chengdu'
}
Obtn2.onclick = function () {
oSel.value = 'beijing'
}
Obtn3.onclick = function () {
oSel.value = 'haerbin'
}
// 读取下拉列表中当前选中的值
getValueBtn.onclick = function () {
// select 元素 自身不带value属性 ==> 判断某个属性是否是自身带有 ==> 可以利用在该元素身上输入属性 看是否有智能提示
// 但是由于某些表单元素(如 select)可以获取到某些不存在的属性
// 也就是说 select元素 比较特殊 虽然自身不带有 value 属性 但是通过它来读取属性值很方便 所以...
// 所以 可以通过该属性来读取相应的 option 元素的 value 属性值
console.log(oSel.value)
}
// 尝试获取 当前 option 下的 nodeValue
getNodeValueBtn.onclick = function () {
var opts = oSel.querySelectorAll('option')
for (var i = 0; i < opts.length; i++) {
var item = opts[i]
if (item.selected) {
// item.firstChild ==> TextNode
console.log(item.firstChild.nodeValue)
}
}
}
</script>
</body>
</html>
<!-- 属性.html ==> 细节 ==> 3. 某些表单元素可以获取到某些不存在的属性
读多行文本框的内容 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>属性.html</title>
</head>
<body>
<button id="btnGetTxt">获取文本框内容</button>
<button id="btnSetTxt">设置文本框内容</button>
<p>
<textarea>哈哈哈哈哈哈哈</textarea>
</p>
</div>
<script>
var txt = document.querySelector("textarea");
document.getElementById("btnGetTxt").onclick = function () {
// 获取多行文本框的值 ==> textarea元素也一样 自身不带有 value 属性
// 但是可以通过 value 来实现读写操作
console.log(txt.value, typeof txt.value);
}
document.getElementById("btnSetTxt").onclick = function () {
txt.value = "请输入文本";
}
</script>
</body>
</html>
<!-- 属性.html ==> 某些属性与标识符冲突, 此时, 需要更换属性名 ==> 这样的属性并不多 下面先来认识俩
1. for ==> htmlFor -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>属性.html</title>
</head>
<body>
<input id="cbgender" type="checkbox" checked="checked">
<label for="cbgender">男</label>
<button id="btnGetTxt">获取复选框的值</button>
<button id="btnSetTxtYes">yes</button>
<button id="btnSetTxtNo">no</button>
<script>
var input = document.querySelector("input[type=checkbox]");
document.getElementById("btnGetTxt").onclick = function () {
console.log(input.checked, typeof input.checked);
}
document.getElementById("btnSetTxtYes").onclick = function () {
input.checked = true;
}
document.getElementById("btnSetTxtNo").onclick = function () {
input.checked = false;
}
var lbl = document.querySelector("label")
// 读取label的for属性值
// 错误写法: lbl.for 正确写法: lbl.htmlFor
// 因为for这个属性名和关键字重复了 所以不能直接使用for属性名带读
// 其他的情况 ==> 无法直接用属性名来读取 ==> 除了和关键字重复 这个原因 还有可能是 这个属性名是将来要使用的保留字
console.log(lbl.for) // undefined
console.log(lbl.htmlFor) // cbgender
</script>
</body>
</html>
<!-- 属性.html ==> 某些属性与标识符冲突, 此时, 需要更换属性名
2. class ==> className -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>属性.html</title>
<style>
div {
height: 100px;
width: 100px;
}
.red {
background: red;
}
.blue {
background: blue;
}
</style>
</head>
<body>
<div class="red"></div>
<button id="btnGetClassName">读取方块class属性值</button>
<button id="btnSetClassName1">设置方块class属性值 ==> blue</button>
<button id="btnSetClassName2">设置方块class属性值 ==> red</button>
<script>
var oDiv = document.querySelector(".red");
document.getElementById("btnGetClassName").onclick = function () {
// 读取dom元素的class属性 不能直接通过属性名来读取
// class ==> className
console.log(oDiv.className, typeof oDiv.className);
}
document.getElementById("btnSetClassName1").onclick = function () {
oDiv.className = 'blue'
}
document.getElementById("btnSetClassName2").onclick = function () {
oDiv.className = 'red'
}
</script>
</body>
</html>
<!-- 获取和设置元素属性 ==> 通用方式 ==> dom.getAttribute('attr') dom.setAttribute('attr','newVlaue')
对于正常的(可识别的)属性 不要使用通用方式来进行读写操作...
因为这里面有很多细节... 比如
1. input.setAttribute('value', 'abc') ==> 打开控制台 看Element选项卡下找到对应的input元素 会发现对应的value值已经被修改了 但是页面上并没有刷新过来...
2. input.getAttribute('value') ==> 要求input元素上必须手动写上value属性 否则即便value属性是有值的 也无法get到
3. 假设 input 此时是一个复选框
input.getAttribute('checked') ==> 得到的是写在该元素上的checked属性上的值 而不是一个boolean
...
小结: 这里的细节特多. 不过不需要记 只要注意不要使用这两种通用方法来读写可识别属性即可
可识别属性 ==> 直接 ==> dom.attr ==> 实现读写操作
但是 通用方式 ==> dom.getAttribute('attr') dom.setAttribute('attr','newVlaue')
也并不是一无是处 ==> 对于非正常的(可识别的)属性而言 ==> 也就是自定义属性 ==> 通用方式还是很有效的
因为自定义属性 一般都是手动写到元素上的 这样正好可以直接通过 dom.getAttribute('attr') 来读取属性值
-->
<!-- 内容.html ==> dom.innerHTML ==> 获取和设置元素的内部HTML文本
1. 获取到的是对应dom下面的全部节点 包括 TextNode ElementNode 等...
2. dom.innerHTML可读可写 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.div1{
width:300px;
height: 300px;
border: 2px solid;
}
</style>
</head>
<body>
<div class="div1">123abc</div>
<button class="btnAdd">添加内容</button>
<script>
var div1 = document.querySelector(".div1");
console.log(div1.innerHTML === div1.firstChild.nodeValue) // true
// 注意: 之前在写作业的时候 用的写法 ==> firstChild.nodeValue 基本在实际开发中 不会这么使用的
document.querySelector(".btnAdd").onclick = function(){
div1.innerHTML += `<span style="color: red;">添加了一个span标签 并带有红色样式</span>`
}
</script>
</body>
</html>
<!-- 内容.html
1. dom.innerText ==> 获取和设置元素内部的纯文本, 仅得到元素内部显示出来的文本
2. dom.textContent ==> 获取和设置元素内部的纯文本, 得到的是内容源代码中的文本
小结 ==> 了解即可 一般不会使用到 使用到最多的也就是 innerHTML
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.div1{
width:300px;
height: 300px;
border: 2px solid;
}
</style>
</head>
<body>
<div class="div1">
<p>
Lorem ipsum dolor sit.
</p>
<style>
.div1{
color: black;
}
</style>
<p style="display: none">
哈哈哈哈哈哈哈
</p>
<img src="1.jpg" alt="">
</div>
<script>
var div1 = document.querySelector(".div1");
console.log(div1.innerText); // Lorem ipsum dolor sit.
console.log(div1.textContent);
/*
Lorem ipsum dolor sit.
.div1{
color: black;
}
哈哈哈哈哈哈哈
*/
</script>
</body>
</html>
<!-- 想起了一件事.html ==> 在页面上编辑样式 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>想起了一件事</title>
</head>
<body>
<style contenteditable="true" style="display: block; white-space: pre;">
/* 写在body内的style元素 在浏览器中有一个默认样式 ==> display: none; */
.container {
color: red;
}
.container a {
color: inherit;
/* 浏览器样式表中 有给a添加样式 */
}
</style>
<div class="container">
<ul>
<li><a href="">Lorem.</a></li>
<li><a href="">Aliquam.</a></li>
<li><a href="">Sed.</a></li>
<li><a href="">Maiores!</a></li>
<li><a href="">Reprehenderit.</a></li>
<li><a href="">Vel.</a></li>
<li><a href="">Culpa?</a></li>
<li><a href="">Voluptate?</a></li>
<li><a href="">Quis!</a></li>
<li><a href="">Eaque!</a></li>
</ul>
</div>
</body>
</html>
<!-- 元素结构1.html ==> 父元素.appendChild(dom) ==> 将dom添加到父元素的末尾
也可以直接用 append ==> 而且用append可以一次添加多个 而 appendChild 一次只能添加一个
但是 append 这还不是一个标准 尽力少用 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>append 和 appendChild</title>
<style>
.red {
color: red;
}
</style>
</head>
<body>
<ul id="ul1">
<li>选项1-1</li>
<li>选项1-2</li>
<li>选项1-3</li>
<li data-1-abc-1="123" class="red">选项1-4</li>
<li>选项1-5</li>
</ul>
<ul id="ul2">
<li>选项2-1</li>
<li>选项2-2</li>
<li>选项2-3</li>
<li>选项2-4</li>
<li>选项2-5</li>
</ul>
<script>
// 将 1-4 插入到 2-5 之后
var li = ul1.getElementsByTagName('li')[3]
ul2.appendChild(li)
</script>
</body>
</html>
<!-- 元素结构1.html ==> 父元素.insertBefore(待插入的元素, 哪个元素之前) -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.red {
color: red;
}
</style>
</head>
<body>
<ul id="ul1">
<li>选项1-1</li>
<li>选项1-2</li>
<li>选项1-3</li>
<li data-1-abc-1="123" class="red">选项1-4</li>
<li>选项1-5</li>
</ul>
<ul id="ul2">
<li>选项2-1</li>
<li>选项2-2</li>
<li>选项2-3</li>
<li>选项2-4</li>
<li>选项2-5</li>
</ul>
<script>
var li1_4 = ul1.getElementsByTagName('li')[3]
var li2_2 = ul2.getElementsByTagName('li')[1]
ul2.insertBefore(li1_4, li2_2) // 将 1-4 插入到 2-2 之前
ul2.insertBefore(li1_4, li2_2.nextElementSibling) // 将 1-4 插入到 2-2 之前
// ==> bug 如果2-2是最后一项咋办 ==> 实际上这个bug并不存在
// 因为如果 li2_2 是最后一项 那么 li2_2.nextElementSibling ==> null ==> 也就是说第二个参数是 null
// 第二个参数若为 null , 那么 insertBefore(参数1, null) 会将 参数1 也就是需要插入的节点 直接插入到父元素的最后
</script>
</body>
</html>
<!-- 元素结构1.html ==> 父元素.replaceChild(替换的元素, 被替换的元素) -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.red {
color: red;
}
</style>
</head>
<body>
<ul id="ul1">
<li>选项1-1</li>
<li>选项1-2</li>
<li>选项1-3</li>
<li data-1-abc-1="123" class="red">选项1-4</li>
<li>选项1-5</li>
</ul>
<ul id="ul2">
<li>选项2-1</li>
<li>选项2-2</li>
<li>选项2-3</li>
<li>选项2-4</li>
<li>选项2-5</li>
</ul>
<script>
var li1_4 = ul1.getElementsByTagName('li')[3]
var li2_2 = ul2.getElementsByTagName('li')[1]
ul2.replaceChild(li1_4, li2_2) // 用 1-4 替换 2-2
</script>
</body>
</html>
<!-- 元素结构重构 ==> 效率较低 ==> 尽量少用 -->
<!-- 创建元素.html
1. document.createElement("元素名") ==> 创建一个元素对象
2. document.createTextNode("文本") ==> 创建一个文本节点对象 ==> 很少用
3. document.createDocumentFragment() ==> 创建文档片段 ==> 很少用 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<ul id="ul1">
<li>Lorem, ipsum.</li>
<li>Quas, vero.</li>
<li>Laborum, totam.</li>
<li>Fugit, a.</li>
<li>Beatae, ipsum.</li>
<li>Odit, quas.</li>
<li>Sunt, unde.</li>
<li>Soluta, in!</li>
<li>Blanditiis, repellat!</li>
<li>Eius, iusto.</li>
</ul>
<script>
var ul = document.getElementById("ul1");
var newLi = document.createElement('li')
newLi.innerHTML = '<span style="color: red">程序创建的li</span>'
// 上述代码创建了一个 dom 元素 ==> li ==> 与页面中的li唯一不同的就是它此时还位于内存中
// 需要通过下面这行代码将其添加到页面中 页面上才会显示这个li
ul.appendChild(newLi)
newLi.appendChild(document.createTextNode("abc"))
</script>
</body>
</html>
<!-- 创建元素.html ==> 3. document.createDocumentFragment() ==> 创建文档片段 ==> 很少用 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul id="ul1">
<li>Lorem, ipsum.</li>
<li>Quas, vero.</li>
<li>Laborum, totam.</li>
<li>Fugit, a.</li>
<li>Beatae, ipsum.</li>
<li>Odit, quas.</li>
<li>Sunt, unde.</li>
<li>Soluta, in!</li>
<li>Blanditiis, repellat!</li>
<li>Eius, iusto.</li>
</ul>
<script>
var ul = document.getElementById("ul1");
for (var i = 1; i <= 100; i++) {
var li = document.createElement("li");
li.innerText = "选项" + i;
ul.appendChild(li);
}
// 这种做法 ==> 页面重构了 100次 ==> 也就是页面重新渲染了 100次
// 更好的做法 ==> 先将100项装到一个容器(文档片段)中 ==> 然后一次性加入到页面中
// 文档片段可以理解为一个没有名儿的 div ...
var ul = document.getElementById("ul1");
var frag = document.createDocumentFragment();
for (var i = 1; i <= 100; i++) {
var li = document.createElement("li");
li.innerText = "选项" + i;
frag.appendChild(li);
}
ul.appendChild(frag);
</script>
</body>
</html>
<!-- 创建元素.html ==> dom.cloneNode(是否深度克隆) ==> 复制一个新的dom对象并返回
注意: childNodes 也是一个实时集合 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.red {
color: red;
}
</style>
</head>
<body>
<ul id="ul1">
<li>选项1-1</li>
<li>选项1-2</li>
<li>选项1-3</li>
<li data-1-abc-1="123" class="red">选项1-4</li>
<li>选项1-5</li>
</ul>
<ul id="ul2">
<li>选项2-1</li>
<li>选项2-2</li>
<li>选项2-3</li>
<li>选项2-4</li>
<li>选项2-5</li>
</ul>
<script>
// 需求: 将 1-4插入到2-5后面 要求原来的 1-4 不被删除 依旧存在
// "笨"办法 ==> 在内存中创建一个li元素 然后将其赋值为 1-4 并将这个新创建的li插入即可
// var li1_4 = ul1.getElementsByTagName('li')[3]
// var newLi = document.createElement('li')
// newLi.innerHTML = li1_4.innerHTML
// ul2.appendChild(newLi)
// bug ==> 1-4 自身设置的 属性 还需要手动转过去..
// "新"办法 ==>
var li1_4 = ul1.getElementsByTagName('li')[3]
var newLi1 = li1_4.cloneNode(true) // true ==> 深克隆
console.log(newLi1, li1_4 === newLi1); // <li data-1-abc-1="123" class="red">选项1-4</li> false
var newLi2 = li1_4.cloneNode(false) // false ==> 浅克隆 (内部的东西全部忽略)
console.log(newLi2); // <li data-1-abc-1="123" class="red"></li>
ul2.appendChild(newLi1)
ul2.appendChild(newLi2)
</script>
</body>
</html>
<!-- 删除元素 ==> removeChild 谋杀 ==> 父元素.removeChild(dom) -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.red {
color: red;
}
</style>
</head>
<body>
<ul id="ul1">
<li>选项1-1</li>
<li>选项1-2</li>
<li>选项1-3</li>
<li data-1-abc-1="123" class="red">选项1-4</li>
<li>选项1-5</li>
</ul>
<ul id="ul2">
<li>选项2-1</li>
<li>选项2-2</li>
<li>选项2-3</li>
<li>选项2-4</li>
<li>选项2-5</li>
</ul>
<script>
// 需求: 将 1-4 从页面中删除
// 1. 谋杀
var li1_4 = ul1.getElementsByTagName('li')[3]
var remLi1 = ul1.removeChild(li1_4) // 返回值是被删除的元素
console.log(remLi1, li1_4) // <li data-1-abc-1="123" class="red">选项1-4</li> <li data-1-abc-1="123" class="red">选项1-4</li>
console.log(remLi1 === li1_4) // true 被删除的元素只是在页面上无法显示了 在内存中占的实际空间还是依旧的 所以说在合适的时候 完全可以再添加回去
// 2. 自杀
var li2_1 = ul2.getElementsByTagName('li')[0]
var remLi2 = li2_1.remove() // 返回值是 undefined
console.log(remLi2, li2_1) // undefined <li>选项2-1</li>
console.log(remLi2 === li2_1) /// false
</script>
</body>
</html>
<!-- 删除自定义属性
1. removeAttribute("属性名")
2. delete dom.dataset.属性名 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.red {
color: red;
}
</style>
</head>
<body>
<ul id="ul1">
<li>选项1-1</li>
<li>选项1-2</li>
<li>选项1-3</li>
<li data-1-abc-1="123" class="red">选项1-4</li>
<li>选项1-5</li>
</ul>
<ul id="ul2">
<li data-bcd>选项2-1</li>
<li>选项2-2</li>
<li>选项2-3</li>
<li>选项2-4</li>
<li>选项2-5</li>
</ul>
<script>
// 需求1: 删除 1-4 的自定义属性
var li1_4 = ul1.getElementsByTagName('li')[3]
// 1. removeAttribute("属性名")
// li1_4.removeAttribute("data-1-abc-1")
// 2. delete dom.dataset.属性名
// console.log(li1_4.dataset) // 先打印出来 展开看一下 需要删除的属性长啥样..
// delete li1_4.dataset["1Abc-1"] // 此时不能用 .属性名 的形式来获取属性 而需要通过对象字面量的形式来获取
// 细节 1. 若自定义属性 写在了元素身上 但是没有对其进行赋值 那么get到的是一个空字符串 如: li2_1.dataset.bcd 若get的属性没有写在元素身上 那么get到的将会是一个 undefined
// 这就类似于从一个空对象中读取一个不存在的属性
// var obj = {} ==> obj.bcd ==> undefined
</script>
</body>
</html>
[作业讲解]dom元素操作
test.html
<!-- 作业1 ==> 删除列表.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>删除列表</title>
<style>
.container {
width: 400px;
margin: 0 auto;
}
.container li {
margin: 20px 0;
}
.container button {
margin-left: 10px;
}
</style>
</head>
<body>
<div class="container">
<p>
<button id="btnClear">清空</button>
</p>
<ul class="list">
<li>项目1<button>删除1</button></li>
<li>项目2<button>删除2</button></li>
<li>项目3<button>删除3</button></li>
<li>项目4<button>删除4</button></li>
<li>项目5<button>删除5</button></li>
<li>项目6<button>删除6</button></li>
<li>项目7<button>删除7</button></li>
<li>项目8<button>删除8</button></li>
<li>项目9<button>删除9</button></li>
<li>项目10<button>删除10</button></li>
</ul>
</div>
<script>
var ul = document.querySelector(".list")
var btnClear = document.querySelector("#btnClear")
btnClear.onclick = function () {
ul.innerHTML = ''
}
// 得到 ul 下的所有按钮
var btns = ul.querySelectorAll('button')
// 给按钮绑定事件处理函数
// 写法1 ==> 经典的由变量声明提升所导致的一种错误写法
// for (var i = 0; i < btns.length; i++) {
// var b = btns[i]
// b.onclick = function () {
// b.parentNode.remove()
// console.log(b, b.parentNode, i) // 以下是输出的三个值
// // <button>删除10</button>
// // <li>项目10<button>删除10</button></li>
// // 10
// }
// }
// 第一种解决方法 ==> 利用函数 ==> 固定变量值
// for (var i = 0; i < btns.length; i++) {
// var b = btns[i]
// regEvent(b) // 固定变量值
// }
// function regEvent(btn) {
// btn.onclick = function () {
// btn.parentNode.remove()
// console.log(btn, btn.parentNode)
// }
// }
// 第二种解决方法 ==> 立即执行函数
// for (var i = 0; i < btns.length; i++) {
// var b = btns[i]; // 得到当前按钮
// (function (b) {
// b.onclick = function () {
// b.parentNode.remove();
// }
// }(b));
// }
// 问题: 由分号导致的一个bug
// for (var i = 0; i < btns.length; i++) {
// var b = btns[i]; // 该语句后面如果不加分号 那么会有bug 不清楚为什么
// (function (b) {
// b.onclick = function () {
// b.parentNode.remove()
// }
// }(b))
// }
// 第三种解决方法 ==> 使用this关键字
// for (var i = 0; i < btns.length; i++) {
// var b = btns[i]; //得到当前按钮
// b.onclick = function () {
// this.parentNode.remove();
// }
// }
// 写法二 ==> 下面这种写法多练练
/* 回顾: 伪数组 ==> 真数组
* 1. [].slice.call(arr) ==> [].slice() === Array.prototype.slice(); // true
* 2. Array.from(arr)
*/
// 1. [].slice.call(arr)
// var abc = [].slice.call(btns).filter(function (item) { // 这里如果不写成一个表达式(也就是省略"var abc = ") 会报错 应该是语法上的错误... 但是写成表达式后 反而特别的鸡肋...
// item.onclick = function () {
// item.parentNode.remove()
// }
// })
// Array.prototype.slice.call(btns).filter(function (item) {
// item.onclick = function () {
// item.parentNode.remove()
// }
// })
// 2. Array.from(arr)
// Array.from(btns).forEach(function (b) {
// b.onclick = function () {
// b.parentNode.remove();
// }
// })
</script>
</body>
</html>
<!-- 作业2 ==> 图片切换器.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>图片切换器</title>
<style>
.banner {
width: 500px;
margin: 0 auto;
text-align: center;
}
.banner img {
width: 100%;
height: 300px;
object-fit: contain;
border: 1px solid;
display: block;
}
</style>
</head>
<body>
<div class="banner">
<img id="img" src="img/1.jpg" alt="">
<p>
<button id="btnPrev">上一张</button>
<button id="btnNext">下一张</button>
</p>
</div>
<script>
var i = 1;
var img = document.getElementById("img"),
btnPrev = document.getElementById("btnPrev"),
btnNext = document.getElementById("btnNext");
/* 回顾 ==> img元素中的src属性是一个正常属性 即: 可识别属性
可以直接通过 imgDom.src 对该属性的属性值进行读写操作 */
// btnPrev.onclick = function () {
// i--;
// if (i === 0) {
// i = 5;
// }
// img.src = `img/${i}.jpg`;
// }
// btnNext.onclick = function () {
// i++;
// if (i === 6) {
// i = 1;
// }
// img.src = `img/${i}.jpg`;
// }
</script>
</body>
</html>
<!-- 作业3 ==> 库存变更器 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
span {
min-width: 50px;
display: inline-block;
text-align: center;
color: red;
}
</style>
</head>
<body>
<p>
库存的最小值为0
</p>
<div>
库存:
<button data-plus="-1000">-1000</button>
<button data-plus="-100">-100</button>
<button data-plus="-10">-10</button>
<button data-plus="-1">-1</button>
<span id="spanNumber">10</span>
<button data-plus="1">+1</button>
<button data-plus="10">+10</button>
<button data-plus="100">+100</button>
<button data-plus="1000">+1000</button>
</div>
<script>
// 学会使用自定义属性 ==> 查看自定义属性对象 ==> dom.dataset
var btns = document.querySelectorAll("button");
var span = document.getElementById("spanNumber");
/* 第一次练习 */
for (var i = 0; i < btns.length; i++) {
var b = btns[i]
b.onclick = function () {
var iCur = parseInt(span.innerText)
// console.log(iCur)
var changeNum = parseInt(this.innerText)
var result = iCur + changeNum
if (result < 0) {
result = 0
}
span.innerText = result
}
}
// for (var i = 0; i < btns.length; i++) {
// var b = btns[i];
// b.onclick = function () {
// // 每次点击按钮之前 先获取到当前值
// var num = parseInt(span.innerText); // span.innerText 获取到的是一个字符串类型的数据
// // 加某个数
// // console.log(this.dataset) // 可以把这个对象输出 看看自定义属性 及 其值 组成的键值对
// var plus = parseInt(this.dataset.plus);
// // var plus = parseInt(this.innerText); // 换成这种写法实际上也能实现
// var result = num + plus;
// if (result < 0) {
// result = 0;
// }
// span.innerHTML = result;
// // span.innerText = result; // ==> 这么写也行
// }
// }
</script>
</body>
</html>
<!-- 作业4 ==> 添加列表 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
width: 400px;
margin: 0 auto;
}
p {
text-align: center;
}
p.error {
color: red;
}
</style>
</head>
<body>
<div class="container">
<p>不能添加空的文本</p>
<div class="input">
<input type="text">
<button id="btnAdd">添加</button>
</div>
<ul class="list">
<li>项目1</li>
<li>项目2</li>
</ul>
</div>
<script>
var btnAdd = document.getElementById("btnAdd");
var ul = document.querySelector(".list");
var inp = document.querySelector("input");
var p = document.querySelector("p");
/* 第一次练习 */
// btnAdd.onclick = function () {
// // 若输入内容有误
// if (!(inp.value.trim())) {
// p.className = 'error'
// } else {
// p.className = ''
// var li = document.createElement('li')
// li.innerText = inp.value
// inp.value = ''
// ul.appendChild(li)
// }
// }
btnAdd.onclick = function () {
// 若输入框内的内容为空
if (!inp.value.trim()) {
p.className = "error";
return;
}
// 若输入内容正常 ==> 去掉p元素上的className ==> 清除由于输入错误而给p元素添加上的样式
p.className = "";
// 每次点击 都创建一个新的 li
var li = document.createElement("li");
// 先将当前文本框的内容 ==> 文本框的值 ==> inp.value ==> 赋值给 之前创建的 li 的 innerText
li.innerText = inp.value;
// 再清空文本框内容
inp.value = "";
// 最后将创建好的li插入到ul的底部即可
ul.appendChild(li);
}
</script>
</body>
</html>
<!-- 作业5 ==> 穿梭框 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
overflow: hidden;
width: 550px;
margin: 0 auto;
}
.container .left {
float: left;
margin: 0 30px;
}
.container select {
width: 100%;
height: 200px;
}
.container .mid {
padding-top: 70px;
}
</style>
</head>
<body>
<div class="container">
<div class="left">
<h2>成哥的现任女友</h2>
<select id="sel1" multiple>
<option value="1">幂幂</option>
<option value="2">花花</option>
<option value="3">春春</option>
<option value="4">盈盈</option>
<option value="5">红红</option>
</select>
</div>
<div class="left mid">
<p>
<button id="btnToRight" title="右移动选中的">>></button>
</p>
<p>
<button id="btnToRightAll" title="右移动全部">>>|</button>
</p>
<p>
<button id="btnToLeft" title="左移动选中的"><<</button>
</p>
<p>
<button id="btnToLeftAll" title="左移动全部">|<<</button>
</p>
</div>
<div class="left">
<h2>成哥的前女友</h2>
<select id="sel2" multiple>
<option value="6">坤坤</option>
</select>
</div>
</div>
<script>
var btnLeft = document.getElementById("btnToLeft"),
btnRight = document.getElementById("btnToRight"),
btnLeftAll = document.getElementById("btnToLeftAll"),
btnRightAll = document.getElementById("btnToRightAll"),
selLeft = document.getElementById("sel1"),
selRight = document.getElementById("sel2");
//得到某个select元素内部被选中的option数组
function getSelectedOptions(sel) {
return Array.from(sel.children).filter(function (item) {
return item.selected;
// 被选中的 option 元素的 selected 属性 的属性值是 true
});
// var opts = [];
// for (var i = 0; i < sel.children.length; i++) {
// if (sel.children[i].selected) {
// opts.push(sel.children[i]);
// }
// }
// return opts;
}
//将option数组中的东西添加到制定的select中
//opts: 要添加的option数组
//sel:要添加到的select元素
function appendToSelect(opts, sel) {
opts = Array.from(opts);
var frag = document.createDocumentFragment();
for (var i = 0; i < opts.length; i++) {
opts[i].selected = false;
frag.appendChild(opts[i]);
}
sel.appendChild(frag);
}
btnLeft.onclick = function () {
//获取右边选中的
var opts = getSelectedOptions(selRight);
//循环将该数组添加到左边的select中
appendToSelect(opts, selLeft);
}
btnRight.onclick = function () {
//获取右边选中的
var opts = getSelectedOptions(selLeft);
//循环将该数组添加到左边的select中
appendToSelect(opts, selRight);
}
btnLeftAll.onclick = function () {
appendToSelect(selRight.children, selLeft);
}
btnRightAll.onclick = function () {
appendToSelect(selLeft.children, selRight);
}
</script>
</body>
</html>
dom元素样式
控制dom元素的类样式
- className: 获取或设置元素的类名
- classList: dom4的新属性
IE10以下不兼容
,是一个用于控制元素类名的对象第二个参数(true/false)在IE中不兼容
- add:用于添加一个类名
- remove:用于移除一个类名
- contains:用于判断一个类名是否存在
- toggle:用于添加/移除一个类名
获取样式
CSS的短横线命名,需要转换为小驼峰命名
- dom.style:得到行内样式对象
- window.getComputedStyle(dom元素):得到某个元素最终计算的样式
- 可以有第二个参数,用于得到某个元素的某个伪元素样式
设置样式
dom.style.样式名 = 值
设置的是行内样式。
test.html
<!-- 控制DOM元素的类样式
1. className
2. classList (可以打印出来看看)
add ==> 用于添加一个类名
remove ==> 用于移除一个类名
contains ==> 用于判断一个类名是否存在
toggle ==> 用于添加/移除一个类名 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>点击切换颜色</title>
<style>
.item {
width: 100px;
height: 100px;
}
.red {
background: red;
}
.green {
background: green;
}
</style>
</head>
<body>
<div class="item red"></div>
<script>
var div = document.querySelector(".red");
div.onclick = function () {
// if (this.className.search(/\bred\b/) !== -1) {
// this.className = this.className.replace(/\bred\b/, "green")
// } else {
// this.className = this.className.replace(/\bgreen\b/, "red")
// }
// if (this.className.includes("red")) {
// this.classList.remove("red")
// this.classList.add("green")
// } else {
// this.classList.remove("green")
// this.classList.add("red")
// }
if (this.classList.contains("red")) {
this.classList.remove("red");
this.classList.add("green");
} else {
this.classList.remove("green");
this.classList.add("red");
}
}
</script>
</body>
</html>
<!-- 控制DOM元素的类样式
2. classList ==> toggle ==> 两种状态(添加/移除)之间切换 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>toggle</title>
<style>
.item {
width: 100px;
height: 100px;
background: gray;
}
.red {
background: red;
}
</style>
</head>
<body>
<div class="item red"></div>
<script>
var div = document.querySelector(".item");
div.onclick = function () {
this.classList.toggle("red");
// this.classList.toggle("red", true); // 强制添加 相当于 add 不再具备移除功能
// this.classList.toggle("red", false); // 强制移除 相当于 remove 不再具备添加功能
}
</script>
</body>
</html>
<!-- 获取样式
1. dom.style ==> 得到 行内样式 对象
2. window.getComputedStyle() ==> 得到某个元素最终计算的样式值
可以有第二个参数 ==> 用于得到某个元素的某个伪元素样式
注意: CSS的短横线命名 ==> 需要转换为小驼峰命名 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>获取样式</title>
<style>
.item {
width: 8em;
height: 100px;
background: gray;
}
.red {
background: red !important;
}
</style>
</head>
<body>
<div class="item red" style="background-color: green; width:auto">
</div>
<script>
var div = document.querySelector(".item");
console.log(div.style.backgroundColor) // green ==> 虽然页面上显示的是红色 但是该div的行内样式 ==> background-color: green; ==> 所以读取到的依旧是行内的 "green"
// 得到div最终计算的样式
var style = getComputedStyle(div);
console.log(style.backgroundColor) // rgb(255, 0, 0) 其实就是红色 但是这是最终的计算结果 颜色最终的计算结果是以rgb函数的形式来表示的
</script>
</body>
</html>
<!-- 获取样式
2. window.getComputedStyle() ==> 得到某个元素最终计算的样式值
可以有第二个参数 ==> 用于得到某个元素的某个伪元素样式 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>window.getComputedStyle() 第二个参数 ==> 用于得到某个元素的某个伪元素样式</title>
<style>
.item {
width: 8em;
height: 100px;
background: gray;
}
.red {
background: red !important;
}
.item::before {
content: "";
display: block;
width: 50px;
height: 50px;
background: #008c8c;
}
</style>
</head>
<body>
<div class="item red" style="background-color: green; width:auto">
</div>
<script>
var div = document.querySelector(".item");
//得到div 的伪元素 before 的最终计算的样式值
var style = getComputedStyle(div, "before");
// console.log(style.content)
// console.log(style.display)
// console.log(style.width)
// console.log(style.height)
// console.log(style.background)
</script>
</body>
</html>
<!-- 设置样式 ==> dom.style.样式名 = 样式值
注意: 1. 设置 ==> 设置的一定是行内样式
2. 获取 ==> 获取的可以是最终计算的值 也可以是行内样式
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>设置样式 dom.style.样式名</title>
</head>
<body>
<div></div>
<script>
var div = document.querySelector("div")
div.style.width = '100px'
div.style.height = '100px'
div.style.border = '10px solid #008c8c'
</script>
</body>
</html>
[作业讲解]dom元素样式
test.html
<!-- 作业1 ==> 选中效果 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>选中效果</title>
<style>
body {
margin: 0;
}
header {
width: 100%;
background: #333;
color: #eee;
}
nav {
overflow: hidden;
/* 为什么"overflow:hidden"能清除浮动的影响 */
/* [BFC](https://www.jianshu.com/p/7e04ed3f4bea) */
}
span {
float: left;
/* 回顾 bfc 设置了 float ==> display的属性值必为block
若不设置 float: left; 那么下面给span设置行高为 50px 将失效 */
line-height: 50px;
margin: 0 15px;
cursor: pointer;
}
span.active {
color: gold;
}
</style>
</head>
<body>
<header>
<nav>
<span>Lorem.</span>
<span>Explicabo.</span>
<span>Harum?</span>
<span>Delectus?</span>
<span>Commodi.</span>
<span>Ullam!</span>
<span>Tempora!</span>
</nav>
</header>
<script>
var spans = document.getElementsByTagName("span");
// Array.prototype.slice.call(spans).forEach(function (spanDom) {
// spanDom.onclick = function () {
// var span = document.querySelector('span.active')
// if (span) {
// span.classList.remove("active")
// // this.classList.remove("active") // 注意 ==> 这里不能写成 this.
// }
// this.classList.add("active")
// }
// })
// Array.from(spans).forEach(function (sp) {
// sp.onclick = function () {
// //去掉之前的所有具有active的类样式
// var span = document.querySelector("span.active");
// if (span) {
// span.classList.remove("active");
// }
// this.classList.add("active");
// }
// })
</script>
</body>
</html>
<!-- 作业2 ==> 随机背景色 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>随机背景色</title>
<style>
.container {
width: 200px;
height: 200px;
border: 2px solid;
cursor: pointer;
}
</style>
</head>
<body>
<p>
点击div,设置div的背景色为随机颜色
</p>
<div class="container">
</div>
<script src="../../common/BetterFunction.js"></script>
<script>
var MyFunctions = {
getRandom: function (a, b) {
return Math.floor(Math.random() * (b - a)) + 1
}
}
var div = document.querySelector(".container");
div.onclick = function () {
// 0 - 255
this.style.background =
`rgb(${MyFunctions.getRandom(0, 255)},${MyFunctions.getRandom(0, 255)},${MyFunctions.getRandom(0, 255)})`;
}
// setInterval(() => {
// div.style.background =
// `rgb(${MyFunctions.getRandom(0, 255)},${MyFunctions.getRandom(0, 255)},${MyFunctions.getRandom(0, 255)})`
// }, 1000);
</script>
</body>
</html>
<!-- 作业3 ==> 文字放大和缩小 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>放大和缩小</title>
<style>
.container {
overflow: hidden;
border: 2px solid;
width: 200px;
height: 200px;
position: relative;
line-height: 200px;
text-align: center;
font-size: 100px;
font-family: 宋体;
}
</style>
</head>
<body>
<div class="container">袁</div>
<p>
<button id="btnbig">放大</button>
<button id="btnsmall">缩小</button>
</p>
<script>
var btnBig = document.getElementById("btnbig"),
btnSmall = document.getElementById("btnsmall"),
div = document.querySelector(".container");
if (!("currentStyle" in Element.prototype)) {
Object.defineProperty(Element.prototype, "currentStyle", {
get: function () {
return window.getComputedStyle(this);
}
});
}
btnBig.onclick = function () {
var size = parseInt(div.currentStyle['fontSize'])
div.style.fontSize = size + 10 + 'px'
}
btnSmall.onclick = function () {
var size = parseInt(div.currentStyle['fontSize'])
result = size - 10
if (result < 10) {
result = 10
}
div.style.fontSize = result + 'px'
}
// btnBig.onclick = function () {
// // 得到当前的字体大小
// var size = parseInt(getComputedStyle(div).fontSize);
// div.style.fontSize = size + 10 + "px";
// }
// btnSmall.onclick = function () {
// //得到当前的字体大小
// var size = parseInt(getComputedStyle(div).fontSize);
// var result = size - 10;
// if (result < 10) {
// result = 10;
// }
// div.style.fontSize = result + "px";
// }
</script>
</body>
</html>
<!-- 作业4 ==> 扑克牌 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>扑克牌</title>
</head>
<body>
<p>
利用pokers文件夹中的图片,用纯JS生成图片依次排列到页面上。不允许使用样式表
</p>
<div id="divcontainer">
</div>
<script>
var div = document.getElementById("divcontainer");
var imgs = [];
// A-K
for (var i = 1; i <= 13; i++) {
for (var j = 1; j <= 4; j++) {
imgs.push(createImg(`pokers/${i}_${j}.jpg`));
// createImg ==> 创建img元素 ==> 传入的参数作为 img的src属性
}
}
// 大小王
imgs.push(createImg(`pokers/14_1.jpg`));
imgs.push(createImg(`pokers/15_1.jpg`));
// 乱序
imgs.sort(function () {
return Math.random() - 0.5;
});
// 将每一张图片插入到页面中
imgs.forEach(function (img) {
div.appendChild(img);
});
// createImg ==> 创建img元素 ==> 传入的参数作为 img的src属性
function createImg(src) {
var img = document.createElement("img");
img.src = src;
img.style.margin = "30px";
return img;
}
</script>
</body>
</html>
练习:拼图游戏
很早之前写过 不记得丢哪了… 找时间在写一遍 再丢上来