1.什么是 WebAPI
API 是一个更广义的概念. 而 WebAPI 是一个更具体的概念, 特指 DOM+BOM
所谓的 API 本质上就是一些现成的函数/对象, 让程序猿拿来就用, 方便开发.
DOM和BOM
操作网页结构都属于DOM范畴
操作浏览器的都属于BOM范畴
2.获取元素
这里选取let来定义变量而非var定义原因:
- var没有块级作用域,let有块级作用域
- var可以重复定义重复变量;let不能重复定义变量
- let更接近于java的变量定义规则
1.querySelector
<div class="one">hello</div>
<div class="one">world</div>
<script>
let div=document.querySelector(".one");
// 使用 log 打印一个元素对象(element),此时看到的是 html 片段
console.log(div);
// 使用 dir 打印一个元素对象,此时看到的是里面具体的值
console.dir(div);
</script>
2.querySelectorAll
<div class="one">hello</div>
<div class="one">world</div>
<script>
let div=document.querySelectorAll(".one");
// 使用 log 打印一个元素对象(element),此时看到的是 html 片段
console.log(div);
// 使用 dir 打印一个元素对象,此时看到的是里面具体的值
console.dir(div);
</script>
3.事件初识
1.基本概念
JS 要构建动态页面, 就需要感知到用户的行为.
用户对于页面的一些操作(点击, 选择, 修改等) 操作都会在浏览器中产生一个个事件, 被 JS 获取到, 从而进行更复杂的交互操作.
2.事件三要素
- 事件源: 哪个元素触发的
- 事件类型: 是点击, 选中, 还是修改?
- 事件处理程序: 进一步如何处理. 往往是一个回调函数.
3.简单示例
<style>
div {
width: 100px;
height: 100px;
background-color: grey;
text-align: center;
line-height: 100px;
color: white;
}
div:active {
background-color: orange;
}
</style>
<div>按钮</div>
<script>
let btn = document.querySelector("div");
btn.onclick = function () {
alert("点击了按钮");
}
</script>
1.源:btn
2.类型:onclick的点击
3.处理程序function
这个匿名函数相当于回调函数,不需要主动调用而是交给浏览器在合适的时间自动独调用
4.操作元素
1.获取/修改元素内容
<style>
div {
width: 100px;
height: 50px;
background-color: grey;
text-align: center;
line-height: 50px;
color: white;
}
div:activ {
background-color: orange;
}
</style>
<div>按钮弹起</div>
<script>
let button = document.querySelector("div");
button.onclick = function () {
if (button.innerHTML == "按钮弹起") {
button.innerHTML = "按钮按下";
} else if (button.innerHTML == "按钮按下") {
button.innerHTML = "按钮弹起";
}
}
</script>
innerHTML和innerText区别:
下面代码发现innerHTML 不光能获取到页面的 html 结构, 同时也能修改结构. 并且获取到的内容保留的空 格和换行.
innerHTML 用的场景比 innerText 更多.
<div class="light">
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
</div>
<script>
let div = document.querySelector("div");
console.log(div.innerHTML);
console.log();
console.log(div.innerText);
</script>
2.获取/修改元素属性
图片的切换:通过修改img.src属性值即可
<img src="1.png" alt="这是一朵玫瑰花" title="好看吗">
<script>
let img = document.querySelector("img");
img.onclick = function () {
img.src = "2.png"
}
</script>
点击后修改图片
主要是用到 img.src
3.获取/修改表单元素属性
密码的显示和隐藏:通过修改type属性值即可
<input type="password" id="input">
<input type="button" id="button">
<script>
let intput = document.querySelector("#input");
let button = document.querySelector("#button");
button.onclick = function () {
if (input.type == "text") {
input.type = "password";
button.value="显示密码"
} else if (input.type == "password") {
input.type = "text";
button.value="隐藏密码";
}
}
</script>
自增按钮:通过修改input.value属性值即可
<input type="text" id="number" value="0">
<input type="button" id="button" value="自增">
<script>
let button = document.querySelector("#button");
button.onclick = function () {
let number=document.querySelector("#number");
let value = parseInt(number.value);
number.value = ++value;
}
</script>
全选/取消全选按钮
- 点击全选按钮, 则选中所有选项
- 只要某个选项取消, 则自动取消全选按钮的勾选状态.
<input type="checkbox" id="all"><label for="all">我全都要</label><br />
<input type="checkbox" class="femal">貂蝉<br />
<input type="checkbox" class="femal">小乔<br />
<input type="checkbox" class="femal">妲己<br />
<input type="checkbox" class="femal">安琪拉<br />
<script>
// 1.获取到所有元素
let all = document.querySelector("#all");
let femals = document.querySelectorAll(".femal");
// 2. 给 all 注册点击事件, 选中/取消所有选项
all.onclick = function () {
for (let i = 0; i < femals.length; ++i) {
femals[i].checked = all.checked;
}
}
// 3.给femals注册点击事件
for(let i=0; i<femals.length; ++i){
femals.onclick=function(){
all.checked=checkFemals(femal);
}
}
// 4.中都没找到反例, 结果就是全选中
function checkFemals(femal) {
for (let i = 0; i < femals.length; ++i) {
if (!femals.checked) {
return false;
}
}
return true;
}
</script>
4.获取/修改样式属性
修改元素的 CSS 类名. 适用于要修改的样式很多的情况.
由于 class 是 JS 的保留字, 所以名字叫做 className
点击文字,文字会放大
<div style="font-size: 20px;">这是一行字</div>
<script>
let div = document.querySelector("div");
div.onclick = function () {
let fontSize = parseInt(div.style.fontSize);
fontSize += 5;
div.style.fontSize = fontSize + "px";
}
</script>
fontSize的由来
CSS属性:font-size<–>JS属性:fontSize【由于js命名规范不能有
-
所以就用大驼峰的形式来代替】
font-size --> fontSize; background-color --> backgroundColor
为何要加px
?
因为fontSize的属性值是一个字符串类型,所以需要经过parseInt转换为整形之后在进行
+
拼接构成字符串才能设置属性值
5.案例:实现切换夜间模式的效果
<style>
.light {
background-color: #fff;
color: #000;
}
.dark {
background-color: #666;
color: #eee;
}
</style>
<div class="light">
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
这是一段话<br />
</div>
<script>
let div = document.querySelector("div");
div.onclick = function () {
if (div.className == "light") {
div.className = "dark";
} else if (div.className == "dark") {
div.className = "light";
}
}
</script>
5.操作节点
元素操作指的是针对当前的已经存在的DOM对象进行一些属性上的操作(都是针对一个元素进行操作)
节点操作不一定是已经存在的DOM对象,也可以新增/删除DOM对象,这里的操作往往是需要针对多个元素进行的
1.新增节点
<div class="container"></div>
<script>
let div = document.createElement("div");
div.innerHTML="这是一个div";
div.style.fontSize="30px";
console.log(div);
</script>
这里就需要通过**createElement(“标签名”)**先创建出一个对象
通过这个方法创建出的元素并不会显示出来,页面上显示的内容是DOM树的内容,新创建的这个元素没有挂到DOM树上,也就不会显示
2.如何把节点插入到dom树上
appendChild:把元素放到父元素的所有子节点最后
insertBefore:把新的元素放到指定元素的前面
<div class="container">
<div class="one">第一个子元素</div>
<div class="two">第二个子元素</div>
</div>
<script>
let div = document.createElement("div");
div.innerHTML="这是一个div";
div.style.fontSize="30px";
console.log(div);
// 把新构建的 div 插入到第二个子元素之前
let container=document.querySelector(".container");
// 通过 .childern[1] 获取 class="two" 的子元素
let two=container.children[1];
// div 放在 two 之前
container.insertBefore(div, two);
// 把新构建的 div 插入到第一个子元素之前
let one=container.children[0];
container.insertBefore(div, one);
</script>
简要说明
- 获取子元素也还可以通过 .children 的方式获取
- 通过 createElement 创建出的标签属于对象,无论如何操作,都是针对的一个对象。因此虽然第一次插入在第二个子元素之前,但是由于后续更改为插入到第一个子元素之前,所以第一次的操作会被第二次的操作覆盖而非是重复插入
3.删除节点
使用 父标签.removeChild(“新建的标签”) 删除子节点
<div class="container">
<div class="one">第一个子元素</div>
<div class="two">第二个子元素</div>
</div>
8
<script>
let div = document.createElement("div");
div.innerHTML="这是一个div";
div.style.fontSize="30px";
console.log(div);
let container=document.querySelector(".container");
// 通过 .childern[1] 获取 class="two" 的子元素
let two=container.children[1];
// div 放在 two 之前
container.insertBefore(div, two);
let one=container.children[0];
container.insertBefore(div, one);
// 删除
container.removeChild(div);
</script>
6.综合运用
1.猜数字
<input type="button" value="重新开始一局游戏" id="reset">
<div>
<span>请输入要猜的数字:</span>
<input type="text" id="num">
<input type="button" value="猜" id="guess">
</div>
<div>
<span>已经猜的次数:</span>
<span id="count">0</span>
</div>
<div>
<span>结果</span>
<span id="result"></span>
</div>
<script>
// 1.获取标签
let resetBtn = document.querySelector("#reset");
let numE = document.querySelector("#num");
let guessBtn = document.querySelector("#guess");
let countE = document.querySelector("#count");
let resultE = document.querySelector("#result");
// 2.产生随机数:[1,100]
let guessNumber = Math.floor(Math.random() * 100) + 1;
let count = 0;
guessBtn.onclick = function () {
++count;
countE.innerHTML = count;
let userGuess = parseInt(numE.value);
if (userGuess == guessNumber) {
resultE.innerHTML = "猜对了";
resultE.style = "color:green";
} else if (userGuess < guessNumber) {
resultE.innerHTML = "猜小了";
resultE.style = "color:grey";
} else {
resultE.innerHTML = "猜大了";
resultE.style = "color:red";
}
}
resetBtn.onclick=function(){
guessNumber = Math.floor(Math.random()*100)+1;
numE.value="";
countE.innerHTML="";
resultE.innerHTML="";
}
</script>
2.表白墙
<style>
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
.container {
width: 600px;
margin: 0 auto;
}
h1 {
text-align: center;
padding: 20px 0px;
}
p {
font-size: 12px;
color: grey;
padding: 10px 0px;
text-align: center;
}
.row {
display: flex;
height: 40px;
justify-content: center;
align-items: center;
}
.row span {
width: 100px;
}
.row .edit {
width: 200px;
height: 38px;
}
.row .submit {
width: 300px;
height: 40px;
background-color: orange;
/* 清除边框线条 */
border: none;
color: white;
}
.row .submit:active {
background-color: grey;
}
</style>
<div class="container">
<h1>表白墙</h1>
<p>输入后点击提交,将会吧信息显示在表格中</p>
<div class="row">
<span>谁:</span>
<input type="text" class="edit">
</div>
<div class="row">
<span>对谁:</span>
<input type="text" class="edit">
</div>
<div class="row">
<span>说什么:</span>
<input type="text" class="edit">
</div>
<div class="row">
<input type="button" value="提交" class="submit">
</div>
</div>
<script>
let submitButton = document.querySelector(".submit");
submitButton.onclick = function () {
// 1.现获取到输入边框里的内容
let edits = document.querySelectorAll(".edit");
let from = edits[0].value, to = edits[1].value, message = edits[2].value;
if (!(from == "" || to == "" | message == "")) {
console.log(from + "对" + to + ":" + message);
// 2.根据输入的内容,构造HTML元素,添加到页面中
let row = document.createElement("div");
row.className = "row";
row.innerHTML = from + "对" + to + "说:" + message;
let container = document.querySelector(".container");
container.appendChild(row);
// 3.把上次输入的内容清空;
for (let i = 0; i < edits.length; ++i) {
edits[i].value = "";
}
}
}
</script>
3.待办事项
<style>
* {
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
.nav {
width: 600px;
margin: 0 auto;
display: flex;
justify-content: center;
background-color: black;
}
.nav input {
width: 450px;
height: 50px;
font-size: 25px;
padding-left: 10px;
}
.nav button {
width: 150px;
height: 50px;
border: none;
background-color: orange;
color: white;
font-size: 18px;
}
.nav button:active {
background-color: grey;
}
.container {
width: 600px;
margin: 0 auto;
display: flex;
justify-content: center;
margin-top: 10px;
}
.container .left,
.container .right {
width: 50%;
}
.container .left h3,
.container .right h3 {
text-align: center;
line-height: 50px;
background-color: black;
color: white;
}
.container .row {
height: 50px;
display: flex;
align-items: center;
justify-content: flex-start;
}
.container .row span {
width: 240px;
}
.container .row button {
width: 40px;
height: 30px;
}
.container .row input {
margin-right: 5px;
}
</style>
<!-- 表示上方的 div,里面放输入框和按钮 -->
<div class="nav">
<input type="text">
<button>新建任务</button>
</div>
<!-- 这个是下方的 div,里面分成左右两栏 -->
<div class="container">
<div class="left">
<h3>未完成</h3>
<div class="row">
<!-- <input type="checkbox" name="" id="">
<span>吃饭</span>
<button>删除</button> -->
</div>
</div>
<div class="right">
<h3>已完成</h3>
</div>
</div>
<script>
let addTaskBtn = document.querySelector(".nav button");
addTaskBtn.onclick = function () {
// 1.获取到输入框的内容
let input = document.querySelector(".nav input");
let taskContent = input.value;
if (taskContent != "") {
// 2.创建一个 div.row 里面设置上需要的 复选框,文本,删除按钮
let row = document.createElement("div");
row.className = "row";
let checkBox = document.createElement("input");
checkBox.type = "checkbox";
let span = document.createElement("span");
span.innerHTML = taskContent;
let deleteBtn = document.createElement("button");
deleteBtn.innerHTML = "删除";
row.appendChild(checkBox);
row.appendChild(span);
row.appendChild(deleteBtn);
// 3.把 div.row 添加到 .left 中
let left = document.querySelector(".left");
left.append(row);
// 4.添加完成后清空
input.value = "";
// 5.给 checkBox 增加一个点击处理函数,点击之后就能够移动任务
checkBox.onclick = function () {
/*
当前用户点击的时候,就获取到当前的这个 row 这个元素
把 row 这个元素给添加到另外一侧
当前 row 如果在 left,就添加到 right;如果实在 right 就添加到 left【也可以根据 checkBox 的选择状态来确定它是在 left 还是在 right】
*/
let target = null;
if (checkBox.checked) {
// 已经是选中的状态:就把这个元素放在右边
target = document.querySelector(".right");
} else {
// 如果是未选中状态:就把这个元素放在左边
target = document.querySelector(".left");
}
target.appendChild(row);
}
// 6.实现删除效果,给删除按钮新增一个删除操作
deleteBtn.onclick = function () {
// 要想删除 row,就需要知道 row 父亲
let parent = row.parentNode;
parent.removeChild(row);
}
}
}
</script>