1.背景知识:
1 文档:一个页面就是一个文档,用document来表示;
2 元素:页面中的所有标签都可以成为元素,用element来表示;
3 节点:网页中的所有部分都可以成为节点
4 DOM树:本质上提供了一组一系列的函数,让我们可以操作网页内容,网页结构,网页样式,所以一个页面的结构是一个树形结构,称为DOM树;
所以说DOMAPI**就是为了操作HTML页面中的各种元素,这里面有属性和方法;一个DOM树上有很多的对象,所以我们要先选中这个对象,然后再进行操作 **
2.获取元素:
获取元素:这两个类中的参数都是字符串类型,这个字符串是一个CSS选择器,对于他们的区别,例如在参数中加一个div
1)querySelector:就会返回多个被选元素中的第一个,也就是说第一个出现的div
2) querySelectorAll:就会把选中的所有带div的多个,以数组的形式全部返回回来
这两个方法都是基于document这个实例来调用的,得到的效果是相当于是在当前页面的全局中来查找符合要求的元素;
举个例子:
<body>
<div class="father">
<div class="child1">child1</div>
<div class="child2">child2</div>
<div class="child3">child3</div>
</div>
<script>
//选中的结果是一个元素
let a=document.querySelector("div");
console.log(a);
let b=document.querySelectorAll("div");
console.log(b);
</script>
事件:一些复杂的程序,往往要涉及到一些组件之间的通信,事件机制就是一种非常典型,也是一种非常非常常见的组件之间通信的机制;
时件也是用户和程序之间交互的桥梁,当用户进行了某些操作时也会引发事件,例如鼠标点击,鼠标拖动,键盘按下,滑动屏幕
事件源:男个元素触发的;
事件类型:是点击选中还是修改?
事件处理程序:进一步如何进行处理,往往是一个回调函数;
<input type="button" value="我是一个按钮">
<script>
let a=document.querySelector("input");
//事件的注册,绑定一个事件
//on 在xxx的时候
a.onclick=function()
{
alert("hello");
}
</script>
所以当我们点击这个按钮的时候,就会触发这个点击事件,就会触发显示hello
这里面的button就是事件源,click就是事件的类型
通过onclick属性就可以关联到一个具体的事件处理函数,当button触发了click事件,就会自动调用onclick对应的函数
3.操作元素
1 获取/修改元素的内容,最里面的,可能是一个文本,一个图片,还可能是一个链接,还可能是一个HTML片段;
就会用到innerHTNL
1>>举个例子:文本转换,文本转换成超链接
<div class="one">hello</div>
<input type="button" value="点击按钮,修改文本">
<script>
//选中button元素,和字体的元素,因为我们要点击的是按钮,我们就可以为按钮注册一个点击事件
let button=document.querySelector('input');
//这里面的内容只可以写input,不可以写成button,因为这里面这可以是选择器
button.onclick=function(){
let text=document.querySelector('.one');
text.innerHTML="我想有个家";
}
</script>
当我们点击按钮的时候,字体就会发生变化
<div class="one">hello</div>
<input type="button" value="点击按钮,修改文本">
<script>
//选中button元素,和字体的元素,因为我们要点击的是按钮,我们就可以为按钮注册一个点击事件
let button=document.querySelector('input');
//这里面的内容只可以写input,不可以写成button,因为这里面这可以是选择器
button.onclick=function(){
let text=document.querySelector('.one');
text.innerHTML='<a href="http://www.sougou.com">我是一个超链接</a>';
}
</script>
当我们点击hello的时候,文本就会转化成一个超链接了
2>>下面我们来实现一个自加计数器 :
<style>
/* justfy-content和align-items必须在display:flex的搭配情况下使用,他的写法一般放到父亲级别的元素中使用 */
.father{
background-color:grey;
width:400px;
height:300px;
margin:0 auto;
/* align-items:center; */
/* 父类元素是整个浏览器,子元素是.parent margin是控制整个.father在浏览器水平方向上居中 */
}
.number{
/* background-color:green; */
height:150px;
width:150px;
/* 父亲元素是.father这个是控制number控制的背景元素在在水平上居中 */
margin:0 auto;
text-align:center;
font-size:150px;
line-height:150px;
}
/* 这时把+和-全部放到一个背景颜色中进行操作 */
.ctrl{
/* 让这个背景区中的元素变成行内块元素,既可以水平排列,又可以调制大小 */
display:flex;
/* 控制它在水平方向上之间来一个打空格 */
justify-content:space-between;
align-items:center;
/* 控制它在垂直方向上居中 */
margin:0 auto;
/* 让这个加号和减号操作的背景水平居中 */
background-color:blue;
width:200px;
height:150px;
}
.add,.sub{
height:50px;
width:50px;
font-size:50px;
text-align: center;
line-height:50px;
}
</style>
</head>
<body>
<div class="father">
<div class="number">0</div>
<div class="ctrl">
<button class="add">+</button>
<button class="sub">-</button>
</div>
<script>
let addbutton=document.querySelector(".add");
let subbutton=document.querySelector(".sub");
let number=document.querySelector(".number");
addbutton.onclick=function(){
let count=number.innerHTML;
count++;
number.innerHTML=count;
}
subbutton.onclick=function(){
count=number.innerHTML;
count--;
number.innerHTML=count;
}
</script>
<body>
显示的结果是:
2)修改操作元素属性
HTML中的指定的属性,最终都会体现在JS中,所以说HTML中的元素在JS中会有一个对应的对象,通过queryselector()可以把这个对象获取出来,这个对象包含了很多很多的属性,通过.就可以访问这里面的属性;如果直接修改JS中的属性,就会影响到HTML页面中的展示效果;
判断一下如果当前的img是男孩子的图片,就把他转换成女孩子,反之则把它转换成男孩子;在JS中,如果想要比较两个字符串是否相等,就用==号;
<img src="郭宇泽.png" title="这是个傻逼" alt="这是个傻逼">
<script>
let img=document.querySelector("img");
//打印这个元素具体的属性
console.dir(img);
console.log(img.src);
console.log(img.title);
console.log(img.alt);
</script>
<body>
<img src="郭宇泽.png" title="这是个傻逼" alt="这是个傻逼">
<script>
let img=document.querySelector("img");
img.onclick=function(){
if(img.alt=="这是个傻逼")
{
img.src="张智超.png";
img.title="这是个聪明人";
img.alt="这是个聪明人";
}else{
img.src="郭宇泽.png";
img.alt="这是个傻逼";
img.title="这是个傻逼";
}
}
</script>
获取修改表单元素属性:
1)value:input的值;
2)disabled:禁止使用;
3)checked:复选框会使用;
4)selected:下拉框会进行使用;
5)type:input的文本类型,文本,密码,按钮,文件
实例1:对一个按钮实现暂停和播放操作;
<input type="button" value="播放">
<script>
let button=document.querySelector("input");
button.onclick=function(){
if(button.value=="播放")
{
button.value="暂停";
}else{
button.value="播放";
}
}
</script>
实例2:全选复选框按钮;
<body>
<div class="father">
<h3>你想要哪个人来给你当老婆</h3>
<input type="checkbox" class="person" id="1"><label for="1">妲己</label><br>
<input type="checkbox" class="person" id="2"><label for="2">安琪拉</label><br>
<input type="checkbox" class="person" id="3"><label for="3">小乔</label><br>
<input type="checkbox" class="person" id="4"><label for="4">阿轲</label><br>
<input type="checkbox" class="person" id="5"><label for="5">西施</label><br>
<input type="checkbox" class="all" id="6"><label for="6">我全都要</label>
</div>
<script>
//1 先把要用到的元素全部取出来
let persons=document.querySelectorAll(".person");
let all=document.querySelector(".all");
//2当我全都要这个选项被点击后,就要把所有的选框都要自动勾选
all.onclick=function(){
for(let i=0;i<persons.length;i++)
{
persons[i].checked=all.checked;
}
//3根据person的各种元素的状态来选中all的值,当所有的persons的值都被选中之后,就会把all.checked的值设成true
//只要有一个person没有被选中,那么就把all.checked设成false
//没当我们点击一个事件时,就要检查所有的元素的点击情况
}
for(let j=0;j<persons.length;j++)
{
persons[j].onclick=function()
{
all.checked=checkperson();
}
}
function checkperson()
{
//遍历所有的person超看他们的checked状态
//如果所有的checked都是true,那么最终返回true,也就是把all.checked设成true
//只要有一个person checked是false,namejoufanhuifalse
for(i=0;i<persons.length;i++)
{
if(!persons[i].checked)
{
return false;
}
}
return true;
}
</script>
</body>
3)获取修改样式属性
相关的属性有两个:1))style属性,影响了行内样式,他是直接嵌入到html元素中的样式;
2))className属性,给元素设置一个CSS类名;
注意:CSS中的属性,是带有-的,但是我们在JS中获取元素时可以用驼峰命名法;例如background-color可以转换成backgroundColor
示例一: 我们设定:每次点击文字的时候,就让他的字体进行放大
<body>
<div style="font-size:20px">李佳伟真帅</div>
<script>
let div=document.querySelector("div");
div.onclick=function()
{ //先获取他的字体大小
console.log(div.style.fontSize);
//这样得到的div.style.fontSize是一个字符串,首先要把他转化成整数
//parseInt有一个特点,当她遇到px的时候,就不会进行转化
let number=parseInt(div.style.fontSize);
number+=10;
div.style.fontSize=number+"px";
}
</script>
</body>
示例二: 夜间模式的切换
*{
margin:0;
padding:0;
box-sizing:border-box;
}
.light{
background-color:black;
color:red;
}
.dack{
background-color:green;
color:blue;
}
.father{
height:300px;
width:300px;
margin:0 auto;
text-align:center;
line-height:300px;
}
.one{
display:flex;
/* padding也需要放在父亲元素里面 */
padding:10px;
}
button{
margin:0 auto;
height:50px;
width:100px;
border-radius:20px;
}
button:active{
background-color:blue;
}
</style>
</head>
<body>
<div class="father light">
你敢点我吗
</div>
<div class="one">
<button>点我切换模式</button>
</div>
<script>
let div=document.querySelector("div");
let button=document.querySelector("button");
button.onclick=function(){
if(div.className.indexOf("light")!==-1)
{
div.className="father dack";
div.innerHTML="你在点一个试试";
}else{
div.className="father light";
div.innerHTML="你敢点我吗";
}
}
</script>
4)节点操作:
一.新增节点:
1 创建出一个节点,调用document.createElement(标签名),接下来还可以对这个标签对象设置多个属性;
2 把这个节点给挂到DOM树上
1))parent.append(child),创建出child元素,选中页面中已有的parent,把child加到parent里面,如果parent已经有了一组child,就把新的child放到最后面;
2))parent.insertBefore(newchild,oldchild),这是就把新的newchild插入到parent的子元素中,oldchild的前面;
二:删除节点:
oldchild=element.removeChild(child);
注意:这里面被删除的节点只是从dom树里面被剔除了,但是此时仍然在内存中,可以随时加到dom树中的其他位置
那么什么时候他被彻底的删除了呢?
当没有这个引用指向这个对象的时候,JS中也是有垃圾回收机制的;
<div class="father">
<div class="one">我叫李家伟</div>
<div class="two">我拿到了字节的offer</div>
</div>
<script>
let div=document.createElement("div");
div.id="MYDIV";
div.className="box";
div.innerHTML="helloworld";
console.log(div);
//第一种插入方式
//先获取到父类的元素
//再调用appendchild()方法把最新的元素放在最后面;
let father=document.querySelector(".father");
father.appendChild(div);
//第二种插入方式
//先获取到父类的元素;和要插入在那个元素后面的元素
father=document.querySelector(".father");
let oldchild=document.querySelector(".one");
father.insertBefore(div,oldchild);
</script>
示例一:正常的页面上显示:李佳伟真帅,然后有一个按钮,里面的内容是请说实话,点击后,显示为李佳伟确实很帅;
<div class="father">
<div class="one">李佳伟</div>
<div class="two">是真的帅</div>
<input type="button" value="请说实话">
</div>
<script>
let button=document.querySelector("input");
button.onclick=function(){
let father=document.querySelector(".father");
let one=document.querySelector(".one");
let two=document.querySelector(".two")
let dele=father.removeChild(two);
//先删除是真的帅
let newchild=document.createElement("div");
//在创建出一个新的元素,并添加到DOM树上
newchild.innerHTML="确实很帅";
father.insertBefore(newchild,button);
}
</script>
示例二:猜数字界面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.father1{
display:flex;
}
.father2{
display:flex;
}
.father3{
display:flex;
}
</style>
</head>
<body>
<input type="button" value="请点击重新开始一局游戏" class="resetbutton">
<div class="father1">
<div>请输入你想要猜的数字:</div><input type="text" class="number">
<input type="button" value="点击按钮请开猜" class="start">
</div>
<div class="father2">
<div>已经猜的次数:</div>
<div class="count">0</div>
</div>
<div class="father3">
<div>结果是:</div>
<div class="result"></div>
</div>
<script>
//1先把用的元素获取到
let resetbutton=document.querySelector(".resetbutton");
let inputnumber=document.querySelector(".number");
let result=document.querySelector(".result");
let inputcount=document.querySelector(".count");
let startbutton=document.querySelector(".start");
//2 生成一个随机的整数,范围是1-100;
let guessnumber=Math.floor(Math.random()*100)+1;
console.log(guessnumber);
//3给startbutton注册一个点击事件
startbutton.onclick=function(){
//4 点击之后,先更新猜的次数的显示
let count=inputcount.innerHTML;
count++;
inputcount.innerHTML=count;
//5再进行比较,将用和输入框中的内容和生成的随机数进行比较,最后返回结果是猜大了还是猜小了
let number=parseInt(inputnumber.value);
//注意input标签中的内容是用元素.value来获取到的
if(number>guessnumber)
{
result.innerHTML="你猜大了";
result.style.color="red";
}else if(number==guessnumber)
{
result.innerHTML="你猜对了";
result.style.color="blue"
}else{
result.innerHTML="你猜小了";
result.style.color="green";
}
}
resetbutton.onclick=function()
{
//1重新生成随机数
//2把猜的次数设回0
//3把输入框的内容清空
//4把菜的结果的情况删除
guessnumber=Math.floor(Math.random()*100)+1;
result.innerHTML="";
inputnumber.value="";
inputcount.innerHTML=0;
//或者这么写,location和document一样,都是JS提供的全局变量
//document是控制DOM树上的操作的,location是控制页面跳转的
location.reload();
}
</script>
</body>
</html>
示例三:表白墙:
显示结果:
每一行中的标签都用div标签来包裹,况且类名都是line,而每一行的div标签用整体包含在一个大的div标签中;把每一行中的元素全部变成行内块元素,来实现水平布局和调控大小
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="father">
<h1>表白墙</h1>
<p>输入点击后提交,结果将显示在墙上</p>
<div class="line">
<span>谁</span><input type="text">
</div>
<div class="line">
<span>对谁说</span><input type="text">
</div>
<div class="line">
<span>说什么</span>
<input type="text">
</div>
<div class="but">
<button>提交</button>
</div>
</body>
<style>
.father{
background-color:green;
width:60%;
margin:0 auto;
box-sizing:border-box;
}
h1{
/* 这里把h2标签当成一个字体,让字体水平居中,就要用到text-align */
text-align: center;
/* 这是设置内边距,也就是说设置字体和背景颜色顶部的距离 */
padding:5px 0;
}
p{
/* 控制P标签里面的字水平居中 */
text-align:center;
padding:5px 0;
}
.line{
/* 设置每一行的元素,水平居中,垂直居中 */
height:50px;
display:flex;
justify-content:center;
align-items:center;
}
span{
font-size:25px;
width:120px;
}
input{
height:25px;
}
.but{
display:flex;
}
button{
margin:0 auto;
width:200px;
}
</style>
<script>
let button=document.querySelector(".but");
button.onclick=function()
{
//1 先获取到框内元素,每一个输入框里面的内容是一个edits的元素;
let arr1=document.querySelectorAll("input");
console.log(arr1);
//2 把谁说的话具体分出来,然后再具体进行字符串的拼接
let from=arr1[0].value;
let to=arr1[1].value;
let message=arr1[2].value;
console.log(from+"对"+to+"说"+message);
//3 判断输入框内容是否合法
if(from==""||to==""||message==""){
return;
}
//4创建出一个新的节点
let newnode=document.createElement("div");
newnode.className="line";
newnode.innerHTML=from+"对"+to+"说"+message;
console.log(newnode);
//5添加到DOM树上
let father=document.querySelector(".father");
father.appendChild(newnode);
//6 清空输入框
for(let i=0;i<arr1.length;i++)
{
arr1[i].value="";
console.log(1);
}
}
</script>
</body>
</html>
注意:表白墙这样的程序,所提交的数据,只是暂时保存在当前的网页中,一旦数据刷新/关闭了,存的东西就啥也不在了;这样的数据不具有持久性;核心办法就是把这些数据提交到服务器上面,然后服务器把这些数据存到文件里或者是数据库中;
示例四:任务编辑框:这题的大致的页面形式是这样的:
先写一部分代码:这页面有2个部分,最大的边框是一个浏览器的背景,最上面是一块背景区域,下面有是一块背景区域,下面的背景区域再次分成两部分;一部分存放未完成的工作,一部分存放完成的工作;
这个页面一共有三个部分
<body>
<!-- 最上面的部分,输入框+新建任务按钮 -->
<div class="header1">
<input type="text">
<input type="button" value="点击我新建一个任务">
</div>
<!-- 下面包含了左右两部分的区域 -->
左右两个部分各占下面总区域的一半一半
<div class="container">
<div class="left"> </div>
<div class="right"> </div>
</div>
<style>
.header1{
background-color:red;
height:200px;
}
.container{
background-color:blue;
height:400px;
display:flex;
}
.left{
background-color:brown;
width:50%;
height:400px;
}
.right{
background-color:black;
width:50%;
height:400px;
}
</style>
</body>
完整代码是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 最上面的部分,输入框+新建任务按钮 -->
<div class="header1">
<input type="text" class="child1">
<input type="button" value="点击我新建一个任务" class="child2">
</div>
<!-- 下面包含了左右两部分的区域 -->
<div class="container">
<div class="left">
<h3>未完成</h3>
<!-- 左右两部分都包含两行,上部分是完成未完成 下部分是待办事项 -->
<div class="father1">
<!-- 添加具体的日志和删除按钮 -->
<input type="checkbox" class="box">
<span>吃饭</span>
<!-- span不会独占一行,而div会独占一行 -->
<input type="button" value="删除" class="button">
</div>
</div>
<div class="right">
<h3>已完成</h3>
</div>
</div>
<style>
.father1
{
/* 给第一个部分设置背景色,改变它的布局方式,让他水平居中和垂直方向上居中 */
height:50px;
display:flex;
align-items:center;
}
*{
margin:0;
padding:0;
box-sizing:border-box;
}
.header1{
/* background-color:red; */
height:150px;
display:flex;
align-items:center;
}
.container{
/* background-color:blue; */
height:400px;
display:flex;
}
.left{
/* background-color:brown; */
width:50%;
height:400px;
}
.right{
/* background-color:yellow; */
width:50%;
height:400px;
}
h3{
/*设置已完成未完成和已完成两个字的展示效果的的那个界面,这两个字用一个大的背景颜色来搞*/
background-color:grey;
height:100px;
font-size:50px;
color:azure;
text-align:center;
line-height:100px;
/* 这是主要设置字体大小的颜色,以及控制文字在我们指定的背景颜色中水平垂直居中 */
}
.father1 .box{
margin:0 10px;
}
span{
width:300px;
/* 这里通过给字体吃饭设置一个背景宽度,把按钮挤到边界去了 */
}
.father1 .button{
height:30px;
width:40px;
background-color:blue;
}
/* 任务中的输入框 */
.header1 .child1{
height:50px;
width:300px;
font-size:25px;
}
.header1 .child2{
height:50px;
width:200px;
background-color:orange;
/* button元素会默认实现一个小的黑色边框 如果想要去除就写上border:none */
}
</style>
<script>
//新建任务
//1.1实现新建任务功能,首先获取到新增按钮
let startbutton=document.querySelector(".child2");
//1.2给新增按钮设置一个点击事件
startbutton.onclick=function(){
//1.3获取到输入框中的内容,首先获取到输入框,在获取到内容
let inputbox=document.querySelector(".child1");
let text=inputbox.value;
if(text=="")
{
alert("当前输入框里面的内容为空,不可以新创建元素");
return;
}
//1.4根据输入框中的内容,创建元素,里面要包含一个button,span标签
let father1 =document.createElement("div");
father1.className="father1";
let box=document.createElement("input");
box.type="checkbox";
box.className="box"
let spantext=document.createElement("span");
spantext.innerHTML=text;
let deletebutton=document.createElement("input");
deletebutton.type="button";
deletebutton.value="删除";
deletebutton.className="button";
//1.5把这些元素挂到DOM树上
father1.appendChild(box);
father1.appendChild(spantext);
father1.appendChild(deletebutton);
let left=document.querySelector(".left");
let right=document.querySelector(".right");
left.appendChild(father1);
//1.6把输入框顺便清空了
inputbox.value=null;
//2 实现已完成功能
box.onclick=function()
{
//操作.father1这个对象,看他是把这个任务放到已完成里面还是未完成里面,可以根据方框的选中状态进行判断
if(!box.checked)
{ right.appendChild(father1);
//选中状态,放到right里面
}else{
right.appendChild(father1);
//没选中,放到左边
}
}//3 实现删除功能,针对删除按钮增加一个点击事件,但是首先要知道她的父元素是谁
//他的父元素left,也有可能是right
deletebutton.onclick=function()
{ let parent=father1.parentNode;
parent.removeChild(father1);
}
}
</script>
</body>
</html>
显示效果为:
版权归原作者 学不会二叉树的小比特 所有, 如有侵权,请联系我们删除。