JS可以分成三个部分
API是一个更广义的概念,而WebAPI是一个更具体的概念,特指DOM+BOM
所谓的API本质上就是一些现成的函数/对象,让程序员拿来就用,方便开发。
相当于一个工具箱,只不过程序员用的工具箱数目繁多,功能复杂。
W3C标准给我们提供了一系列的函数,让我们可以操作:
一个页面的结构是一个树形结构,称为DOM树
树形结构在数据结构阶段会介绍,既可以简单理解成类似于“家谱”这种结构
重要概念:
- 文档:一个页面就是一个文档,使用document表示
- 元素:页面中所有的标签都可以称为元素,使用element表示
- 节点:网页中所有的内容都可以称为节点(标签节点、注释节点、文本节点、属性节点等)。使用node表示
这些文档等概念在JS代码中就对应一个个的对象, 所以才叫做“文档对象模型”。
这部分工作类似于CSS选择器的功能
let element = document.querySelector(selectors);
选择器
类选择器(.className)
ID选择器(.ID)
全局选择器(*)
关系选择器
子代关系选择器(article > p)
邻接兄弟(p+img)
通用兄弟(p~img)
符合关系选择器(ul > li[class=“a”])
伪类选择器(:hover :acitive)
具体使用可以参照下面代码:
使用querySelectorAll用法和上面类似
<div class="box">abcdiv>
<div id="id">defdiv>
<script>
let elems = document.querySelectorAll('div');
console.log(elems)
script>
JS要构建动态页面,就需要感知到用户的行为
用户对于页面的一些操作(点击、选择、修改)操作都会在浏览器中产生一个个事件,被JS获取到,从而进行更复杂的交互操作
浏览器就是一个哨兵,在侦查敌情·(用户行为),一旦用户有反应(触发具体动作),哨兵就会点燃烽火 台的狼烟(时间),后方就可以根据狼烟来决定下一步的对敌策略。
HTML DOM事件
onclick事件
<button id="btn">点我一下div>
<script>
let btn = document.querySelector('#btn')
btn.onclick=function(){
alert("hello world");
}
script>
onkeydown事件
<input type="text">
<script>
//事件源
let input = document.querySelector('input')
input.onkeydown=function(event){
console.log('键盘正在按下');
let a = event.keyCode;
let b = String.fromCharCode(a);
console.log(b)
}
script>
可以看到运行结果不能区分大小写,所以我们的onkeypress就是为了解决这个问题
onkeypress事件
<input type="text">
<script>
//事件源
let input = document.querySelector('input')
input.onkeypress=function(event){
console.log('键盘正在按下');
let a = event.keyCode;
let b = String.fromCharCode(a);
console.log(b)
}
script>
<input type="text" onkeyup="myOnKeyUp()">
<script>
//事件源
let input = document.querySelector('input')
input.onkeypress=function(event){
console.log('键盘正在按下');
let a = event.keyCode;
let b = String.fromCharCode(a);
console.log(b)
}
function myOnKeyUp(){
console.log('按键被抬起')
}
</script>
onkeydown
<input type="text">
<script>
//事件源
let input = document.querySelector('input')
input.onkeydown=function(event){
if(event.shiftKey)
{
console.log('shift按键被按下')
}
if(event.altKey)
{
console.log('alt按键被按下')
}
}
</script>
表单(主要是指input标签)的以下属性都可以通过DOM来修改
<input class="btn" type="button" value="播放" onclick="onClick()">
<script>
let btn = document.querySelector('.btn')
//判断按钮的值为播放,就变成暂停;暂停就变成播放
function onClick()
{
if(btn.value == "播放"){
btn.value = "暂停"
}
else{
btn.value = "播放"
}
}
</script>
点击计数
<input class='input' type="text" value="0">
<input class='add' type="button" value="+1" onclick="ADD()">
<input class='sub' type="button" value="-1" onclick="SUB()">
</body>
<script>
let btn = document.querySelector('.input')
let input = document.querySelector('.input')
//判断按钮的值为播放,就变成暂停;暂停就变成播放
function ADD(){
let input=document.querySelector(".input")
input.value=parseInt(input.value)+1
}
function SUB(){
let input=document.querySelector(".input")
input.value=parseInt(input.value)-1
}
复选框的应用
<input class='all' type="checkbox" onclick='selectAll()'> 选中全部<br>
<input class='select' type="checkbox">选项1<br>
<input class='select' type="checkbox">选项2<br>
<input class='select' type="checkbox">选项3<br>
<input class='select' type="checkbox">选项4<br>
</body>
<script>
// let btn = document.querySelector('.input')
// let input = document.querySelector('.input')
// //判断按钮的值为播放,就变成暂停;暂停就变成播放
// function ADD(){
// let input=document.querySelector(".input")
// input.value=parseInt(input.value)+1
// }
// function SUB(){
// let input=document.querySelector(".input")
// input.value=parseInt(input.value)-1
// }
let all=document.querySelector('.all')
let select=document.querySelectorAll('.select')
function selectAll(){
for(i=0;i<select.length;i++)
{
select[i].checked = all.checked;
}
}
for(i=0;i<select.length;i++)
{
select[i].onclick=function(){
all.checked=isSelectAll(select)
}
}
function isSelectAll(select){
for(i=0;i<select.length;i++){
if(select[i].checked==false){
return false
}
}
return true
}
</script>
CSS中指定元素的属性,都可以通过JS来修改
element.style.[属性名]=[属性值];
element.style.cssText=[属性名+属性值]
“行内样式”,通过style直接在标签上制定的样式,优先级很高
适用与改的样式少的情况
element.className=[css 类名]
点击文字就放大字体
这种方式修改只影响到特定样式,其他内联样式的值不变
<div style="font-size: 10px;">哈哈哈div>
body>
<script>
let element=document.querySelector('div');
element.onclick=function(){
let size=parseInt(element.style.fontSize);
size+=10;
// element.style.fontSize =size +'px';
element.style.cssText="font-size:"+size+'px'
}
script>
黑夜模式&&白天模式切换
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
.light{
background-color: white;
color:black;
width:100%;
height:100%;
}
.dark{
background-color: black;
color:white;
width:100%;
height:100%;
}
*{
width:100%;
height:100%;
}
style>
head>
<body>
<div class="light" onclick="changeStyle()">
这是一段话<br>
这是一段话<br>
这是一段话<br>
这是一段话<br>
这是一段话<br>
这是一段话<br>
这是一段话<br>
这是一段话<br>
div>
body>
<script>
function changeStyle(){
let element=document.querySelector('div')
if(element.className=='light'){
element.className="dark"
}
else{
element.className="light";
}
}
script>
html>
分成两个步骤
使用createElement方法创建一个元素,option参数暂不关注
let element=document.createElement(tagName[,option]);
1)使用appendChild将节点插入到指定节点的最后一个孩子之后
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div>
<p>这是一个p标签p>
<p>这是一个p标签p>
<p>这是一个p标签p>
<p>这是一个p标签p>
div>
body>
<script>
let element=document.createElement("h3")
element.innerHTML="这是我们创建的一个新节点"
let div=document.querySelector("div")
div.appendChild(element)
script>
html>
2)使用InsertBefore将节点插入到指定节点之前
let insertNode=parentNode.insertBefore(newnode,referenceNode);
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div>
<p class="p1">这是一个p标签p>
<p class="p2">这是一个p标签p>
<p class="p3">这是一个p标签p>
<p class="p4">这是一个p标签p>
div>
body>
<script>
let element=document.createElement("h3")
element.innerHTML="这是我们创建的一个新节点"
let div=document.querySelector("div")
div.appendChild(element)
let newNode=document.createElement('h3')
newNode.innerHTML="这是我们创建的另一个新节点"
div.insertBefore(newNode,document.querySelector('.p1'))
div.insertBefore(newNode,document.querySelector('.p2'))
div.insertBefore(newNode,document.querySelector('.p3'))
div.insertBefore(newNode,document.querySelector('.p4'))
script>
html>
注意2:一旦一个节点插入完毕,在针对刚刚的节点对象进行修改,能够同步影响到DOM树中的内容
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div>
<p class="p1">这是一个p标签p>
<p class="p2">这是一个p标签p>
<p class="p3">这是一个p标签p>
<p class="p4">这是一个p标签p>
div>
body>
<script>
let element=document.createElement("h3")
element.innerHTML="这是我们创建的一个新节点"
let div=document.querySelector("div")
div.appendChild(element)
let newNode=document.createElement('h3')
newNode.innerHTML="这是我们创建的另一个新节点"
div.insertBefore(newNode,document.querySelector('.p1'))
div.insertBefore(newNode,document.querySelector('.p2'))
div.insertBefore(newNode,document.querySelector('.p3'))
div.insertBefore(newNode,document.querySelector('.p4'))
// element.innerHTML="我在修改这个标签"
script>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
*{
margin:0px;
padding:0px;
box-sizing: border-box;
}
.nav{
width:800px;
height:100px;
margin:0 auto;
display:flex;
align-items: center;
}
.nav input{
width:600px;
height:60px;
border-radius: 5px 0 0 5px;
}
.nav button{
width:200px;
height:60px;
background-color: orange;
color:white;
font-size:20px;
border:orange;
border-radius: 0 5px 5px 0;
}
.nav button:active{
background-color: grey;
}
.container{
width:800px;
display: flex;
margin:0px auto;
}
h3{
background-color: grey;
color:white;
text-align: center;
width:400px;
height:60px;
padding-top:15px;
}
.row{
width:400px;
display:flex;
align-items: center;
}
.row span{
width:200px;
font-size:20px;
margin-left:5px;
}
.row button{
width:50px;
height:40px;
font-size:20px;
margin-top:10px;
}
.done{
width:50%;
height:100%;
}
span{
width:100px;
}
style>
head>
<body>
<div class="nav">
<input type="text"><button onclick="newJob()">新建任务button>
div>
<div class="container">
<div class="todo">
<h3>未完成h3>
<div class="row">
<input type="checkbox" name="" i="">
<span>吃饭span><button>删除button>
div>
div>
<div class="done">
<h3>已完成h3>
div>
div>
body>
<script>
function newJob(){
//获取数据
let input=document.querySelector('.nav input')
let input_info=input.value
if(input_info==''){
return
}
//获取todo
let todo=document.querySelector('.todo')
//创建一个div
let div=document.createElement('div')
//创建一个checkbox
let checkbox=document.createElement('input')
checkbox.type="checkbox"
//创建一个span(文本内容是刚才输入的信息)
let span=document.createElement('span')
span.innerHTML=input_info
//创建一个button
let button=document.createElement('button')
button.innerHTML="删除"
div.appendChild(checkbox)
div.appendChild(span)
div.appendChild(button)
//更新样式
div.className='row'
//将div插入到todo这个div中
todo.appendChild(div)
let deleteButtons=document.querySelectorAll('.row button')
for(i=0;i<deleteButtons.length;i++)
{
deleteButtons[i].onclick=function(){
let parent=this.parentNode;
let grandParent=parent.parentNode;
grandParent.removeChild(parent);
}
}
let checkbox_buttons=document.querySelectorAll('.row input')
//绑定点击事件
for(i=0;i<checkbox_buttons.length;i++)
{
let row=document.querySelector('.row')
let done;
checkbox_buttons[i].onclick=function(){
if(this.checked==true){
done=document.querySelector('.done')
done.appendChild(row)
}else{
done=document.querySelector('.todo')
}
// console.log(typeof(row))
}
}
}
script>
html>