BOM/DOM
- 67初始BOM
- 68浏览器可视窗口的尺寸
- 69 浏览器的弹出层
- 70浏览器的地址栏
- 71 浏览器常见事件
- 72浏览器滚动距离
- 73浏览器打开标签
- 74浏览器的历史记录
- 75浏览器本地存储
- 77DOM![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ea884252dfec5cb2fee9eaed1d4db9bf.png)
- 78获取元素的方法
- 79 操作元素属性
- 82操作文本元素内容
- 83案例 渲染页面
- 84操作元素样式
- 85操作元素类名className
- 88 -DOM节点
- 89获取节点的方式
- 90节点操作
- 91 案例动态删除
- 92节点属性
- 93获取元素尺寸
- 94获取元素偏移量
- 95获取可视窗口的尺寸
- 96案例 懒加载
- 97 初识事件
- 98事件解绑
- 99事件类型
- 100事件对象
- 104 标准的DOM事件流
- 105stopPropagation阻止事件传播
- 106阻止默认行为
- 108事件委托
67初始BOM
68浏览器可视窗口的尺寸
window只获取窗口的宽高
69 浏览器的弹出层
alert
<body>
<div>
<button id="btn">点击</button>
</div>
<script>
btn.onclick=function(){
alert("一条提示信息")
}
</script>
</body>
输入框prompt
<body>
<div>
<button id="btn">点击弹出输入框</button>
</div>
<script>
btn.onclick=function(){
let a=prompt("请输入信息")
document.write(a)
}
</script>
</body>
js是单线程,同一时间只能干一件事
70浏览器的地址栏
地址可读可写
<button id="btn">点击跳转</button>
<script>
documen.write(locat.href)
btn.onclick=function(){
location.href="https://editor.csdn.net/md?not_checkout=1?not_checkout&articleId=128621371"
}
</script>
location.reload
刷新
71 浏览器常见事件
load
resize
大小改变时执行
window.onresize=function(){
document.write("resize")
}
窗口大小每次改变时,执行函数,打印resize
scroll
window.onresize=function(){
document.write("resize")
}
每次滚动滚动条时,执行函数,打印resize,
72浏览器滚动距离
<style>
body{
height: 2000px;
}
</style>
<script>
window.onscroll=function()
{console.log(document.documentElement.scrollTop)
//若水平方向也有滚动条,可写为
window.onscroll=function()
{console.log(document.documentElement.scrollTop||document.documentElement.scrollLeft)
}
</script>
通过if语句,显示一个东西什么时候出来
回到顶部
btn.onclick=function(){
window.scrollTo(0,0)
}
btn.onclick=function(){
window.scrollTo({
left:0,
top:0
})
}
73浏览器打开标签
window.open
window.close
<body>
<button id="btn1">打开</button>
<button id="btn2">关闭</button>
<script>
btn1.onclick=function(){
window.open=("https://editor.csdn.net/md?not_checkout=1?not_checkout&articleId=128621371")
}
btn2.onclick=function(){
window.close=("https://mp.csdn.net/mp_blog/manage/article?spm=1000.2115.3001.5448")
}
</script>
</body>
74浏览器的历史记录
history.go(正数)前进
history.go(负数)后退
数字表示跳转的网页的个数
75浏览器本地存储
localStorage永久存储
<script>
存
//只能存字符串类型,其他类型会强行转换为字符串
//可以通过
//JSON.stringify
//JSON.parse使用
localStorage.setItem("name","lucy")
取
localStorage.getItem("name")
删
localStorage.removeItem("name")
清空
localStorage.clear()
</script>
sessionStorage会话存储
页面关闭就丢失
<script>
增加
sessionStorage.setItem("name","lucy")
取
sessionStorage.getItem("name")
删
sessionStorage.removeItem("name")
清空
sessionStorage.clear()
</script>
76案例
用户名<input type="text" id="username">
密码<input type="password" id="password">
<div id="login">
<button>登录</button>
</div>
<script>
let uservalue=localStorage.getItem("username")
let passvalue=localStorage.getItem("password")
login.onclick=function(){
localStorage.setItem("username",username.value)
localStorage.setItem("password",password.value)
}
</script>
77DOM![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ea884252dfec5cb2fee9eaed1d4db9bf.png)
78获取元素的方法
或者box.属性?
非常规
- html对应document.documentElement
- head对应document.head
- body对应document.body
常规
getElementById
若有两个一样的id名,则只能获取到第一个
document.getElementsByClassName
可以获取多个
伪数组,有length属性
getElementsBYTagName
getElementsByName
多用于input标签
<body>
<div id="one"></div>
<div class="two"></div>
<div class="two"></div>
<div class="two">
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<input type="text" name="three">
<script>
let a=document.getElementById("one")
a.innerHTML="第一条内容"
//innerHTML改变标签的内容
let b=document.getElementsByClassName("two")
b[0].innerHTML="第二条内容"
b[1].innerHTML="第二条内容(2)"
let c=document.getElementsByTagName("li")
c[1].innerHTML="列表"
let d=document.getElementsByName("three")
d.innerHTML="abcdef"
</script>
</body>
querySelector
什么都可找
只能返回一个对象
but 只可找到第一个
querySelectorAll
<body>
<div id="one"></div>
<div class="two"></div>
<div class="two">
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<script>
let a=document.querySelector("div")
a.innerHTML="第一条内容"
let b=document.querySelectorAll(".two ul li")
b[2].innerHTML="hha"
</script>
79 操作元素属性
元素的原生属性
- 拿到节点
- 选择要改的属性
节点.属性=“ ”
可以更改表单的类型
<input type="text" id="one">
<script>
one.type="password"
</script>
自定义属性
setAttribute
<div fang="abc" id="one"></div>
<script>
document.write(one.getAttribute("fang"))
</script>
输出结果为abc
getAttribute
<div fang="abc" id="one"></div>
<script>
one.setAttribute("hai",123)
</script>
removeAttribute
data-****
新规范用它来写自定义的标签,虽然用上面的也可
<div id="one" ></div>
<script>
one.dataset.fang="123"
one.dataset.hai="abc"
delete one.dataset.hai
</script>
80案例-密码可视
<input type="password" id="put">
<button id="btn">小眼睛</button>
<script>
let b=document.getElementById("put")
let a=document.getElementById("btn")
a.onclick=function(){
if(b.type==="password"){
b.type="text"
}else{
b.type="password"
}
}
</script>
82操作文本元素内容
innerHTML
<div id="a">
<div>hhh</div>
</div>
<script>
console.log(a.innerHTML)
</script>
<div id="a">
<div>hhh</div>
</div>
<script>
console.log(a.innerText)
</script>
innerText
只能获取文本
<div id="a">
<div>hhh</div>
</div>
<script>
a.innerText="<h1>ggg</h1>"
document.write(a.innerText)
</script>
<div id="a">
<div>hhh</div>
</div>
<script>
a.innerHTML="<h1>ggg</h1>"
document.write(a.innerText)
</script>
value
多用于表单
83案例 渲染页面
bug
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
li img{
float: left;
}
</style>
</head>
<body>
<ul>
<!-- <li>
<img src="" alt="">
<h3></h3>
<p></p>
</li> -->
</ul>
<script>
let arr=[
{
url:"D:\乱七八糟\Users\fff36\Desktop\前端\练习\练习\pic-3.png",
title:"第一",
grade:6
},
{
url:"D:\乱七八糟\Users\fff36\Desktop\前端\练习\练习\pic-3.png",
title:"第二",
grade:9.3
},
{
url:"D:\乱七八糟\Users\fff36\Desktop\前端\练习\练习\tup.png",
title:"第三",
grade:7
}
]
let b=arr.map(function(item){
return ` <li>
<img src="${item.url}" alt="">
<h3>${item.title}</h3>
<p>观众评分 7.8分</p>
</li>`
})
console.log(arr.join(""))
//数组转字符串
let alul=document.querySelectorAll("ul")
alul.innerHTML=arr.join("")
</script>
</body>
84操作元素样式
行内样式style
可读可写
当样式写在外链时,不可获取
背景颜色要写成这样backgroundColor或者[“background-color”]
<div id="box" style="width: 200px;height:100px;background-color:lightpink;"></div>
<script>
document.write(box.style.width,"<br>",box.style.backgroundColor)
//读取
box.style.backgroundColor="lightblue"
//添加或改变元素的css样式
</script>
getComputedStyle
内部,外部样式,行内样式都可获取
但是不能赋值
非IE使用(高版本)
低版本只能用currenStyle
<style>
div{
width: 200px;
height:100px;
background-color:lightpink;
}
</style>
</head>
<body>
<div id="box" ></div>
<script>
let a=document.getElementById("box")
let b=getComputedStyle(a).height
document.write(b)
</script>
</body>
85操作元素类名className
批量控制样式
可以读取类名
<div id="box" class="a b c"></div>
<script>
document.write(box.className)
</script>
直接命名即为修改
如下
box.className="a b"
classList
add
可以自动去重
比如原来有a,则再添加a无效
box.classList.add("d")
remove
toggle切换
若原来有类名a,再写
box.classList.toggle
则原来类名去除,反之若原来没有,则添加这个类名
86案例 简易选项卡
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
ul{
display: flex;
}
li{
height: 50px;
line-height: 50px;
text-align: center;
flex:1
}
.active{
color: red;
border-bottom: 1px solid red;
}
</style>
</head>
<body>
<ul>
<li class="active" id="item1">one</li>
<li id="item2">two</li>
</ul>
<script>
item1.onclick=function(){
item1.classList.add("active")
item2.classList.remove("active")
}
item2.onclick=function(){
item2.classList.add("active")
item1.classList.remove("active")
}
</script>
</body>
87案例 选项卡
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
.header{
display: flex;
width: 500px;
}
.header li{
height: 50px;
line-height: 50px;
text-align: center;
flex:1;
border:1px solid black;
}
.header .active{
background-color: red;
color: aliceblue;
}
.box{
position: relative;
}
.box .active{
display: block;
}
.box li{
position: absolute;
top: 0;
left: 0;
width: 500px;
height: 200px;
background-color: pink;
display: none;
}
.active{
color: red;
border-bottom: 1px solid red;
}
</style>
</head>
<body>
<ul class="header">
<li class="active">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<ul class="box">
<li class="active">a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
<script>
//头部分析谁有active谁高亮
let oheaderItems=document.querySelectorAll(".header li")
let oboxItems=document.querySelectorAll(".box li")
for(let i=0;i<oheaderItems.length;i++){
//for循环一瞬间完成,js为单线程,点之前已经执行完,此时i已经等于4
//所以不能使用document.log[i]
//所以设置自定义属性 以下相当于有了个 类data-mine=“i”
oheaderItems[i].dataset.mine=i
oheaderItems[i].onclick=function(){
//console.log(this.dataset.mine)
//this表示当前这个i
let mine=this.dataset.mine
//获取这个属性?
for(let m=0;m<oheaderItems.length;m++){
oheaderItems[m].classList.remove("active")
oboxItems[m].classList.remove("active")
//排他(全部清零思想)
}
oheaderItems[mine].classList.add("active")
oboxItems[mine].classList.add("active")
//给点到的添加active属性
}
}
</script>
</body>
88 -DOM节点
元素节点
文本节点
属性节点
注释节点
根节点
根元素节点
89获取节点的方式
childnode
获取某一个节点下所有的子一级节点
child
获取某一个节点下所有的子一级元素节点
attributes
获取某一个 元素节点 的所有 属性节点
以下都不再是伪数组,都只获取一个节点
firstchild
获取某一个节点下 子一级的 第一个节点
firstElementChild
获取某一节点下子一级 第一个元素节点
lastchild
lastElementchild
nextSibling
获取某一个节点的 下一个兄弟节点
previousSibling
获取某一个节点的 上一个兄弟节点
nextElementSibling
获取某一个节点的 下一个元素节点
previousElementSibling
获取某一个节点的 上一个元素节点
nextElementSibling
获取某一个节点的 下一个元素节点
parentNode
获取某一个节点的 父节点
<body>
<ul>
<li id="a">hello</li>
<li id="b">world</li>
<li id="c">!!!</li>
</ul>
<script>
// 这个 oLi 获取的是页面中的 li 元素,就是一个元素节点
let oLi = document.querySelector('#b')
console.log(oLi.parentNode)
//输出结果为 <ul>...</ul>
</script>
</body>
获取的是当前这个 li 的父元素节点,因为这个 li 的父亲就是 ul ,所以获取到的就是 ul ,是一个元素节点
90节点操作
这些操作的括号里都是对象
odiv表示objectdiv对象div
createElement创建节点
var oDiv = document.createElement('div')
console.log(oDiv)
// 输出<div></div>
还可 odiv.innerHTML="我是新创建的"
console.log(odiv)
//输出<div>我是新创建的</div>
创建出来的就是一个可以使用的 div 元素
appendChild
是向一个元素节点的末尾追加一个节点!!
<body>
<div id="box">111
<div id="child1">aaa</div>
<div id="child2">bbb</div>
</div>
<script>
let odiv=document.createElement("div")
odiv.innerHTML="我是新创建的1"
box.append(odiv)
//上面这个记不清l
odiv.id="new"
let odiv2=document.createElement("div")
odiv2.innerHTML="我是新创建的2"
child1.append(odiv2)
odiv2.className="new2"
</script>
</body>
insertBefore (a,b)
向某一个节点前插入一个节点
a表示要插入的节点
b表示在谁的前面插入
removeChild
移除某一节点下的某一个节点
<body>
<div>
<p>我是一个 p 标签</p>
</div>
<script>
var oDiv = document.querySelector('div')
var oP = oDiv.querySelector('p')
// 移除 div 下面的 p 标签
oDiv.removeChild(oP)
console.log(oDiv) // <div></div>
</script>
</body>
odiv。remove()表示删除自己以及后代
replaceChild
将页面中的某一个节点替换掉
<body>
<div>
<p>我是一个 p 标签</p>
</div>
<script>
var oDiv = document.querySelector('div')
var oP = oDiv.querySelector('p')
// 创建一个 span 节点
var oSpan = document.createElement('span')
// 向 span 元素中加点文字
oSpan.innerHTML = '我是新创建的 span 标签'
// 用创建的 span 标签替换原先 div 下的 p 标签
oDiv.replaceChild(oSpan, oP)
console.log(oDiv)
/*
<div>
<span>我是新创建的 span 标签</span>
</div>
*/
</script>
</body>
cloneNode()克隆节点
默认false不克隆后代
true克隆
不知对不对
<body>
<div id="box">111
<div id="child1">aaa</div>
<div id="child2">bbb</div>
</div>
<script>
let oClone=box.cloneNode(true)
oClone.innerHTML="hhh"
console.log(oClone)
document.write(oClone)
//显示英文object什么
</script>
</body>
<body>
<div id="box">111
<div id="child1">aaa</div>
<div id="child2">bbb</div>
</div>
<script>
let oClone=box.cloneNode(true)
console.log(oClone)
document.body.appendChild(oClone)
//用这个否则不正确显示
</script>
</body>
91 案例动态删除
<ul id="list">
</ul>
<script>
let arr=["a","b","c"]
for(let i=0;i<arr.length;i++){
let oli=document.createElement("li")
oli.innerHTML=arr[i]
let obutton=document.createElement("button")
obutton.innerHTMl="delete"
obutton.onclick=handler
oli.appendchild(obutton)
list.appendchild(oli)
}
function handler(){
console.log(this.parentNode)
this.parentNode.remove()
}
</script>
92节点属性
93获取元素尺寸
offsetWidth
获取的是元素 内容 + padding + border 的宽度
offsetHeight
获取的是元素 内容 + padding + border 的高度
有box-sizing时,会挤压内容,计算方式没有影响
display:none拿不到
获取到的尺寸是没有单位的数字
clientWidth
获取的是元素 内容 + padding 的宽度
clientHeight
获取的是元素 内容 + padding 的高度
94获取元素偏移量
就是元素在页面上相对于参考父级的左边和上边的距离 若父级都没有定位,则相对于body
相对于父级
- offsetparent
- offsetLeft
- offsetTop
相对于自己的边框 - clientLeft
- clientTop
95获取可视窗口的尺寸
innerWidth 和 innerHeight,他们获取到的是窗口包含滚动条的尺寸
document.documentElement.clientWidth
可视窗口的宽度
document.documentElement.clientHeight
可视窗口的高度
个不包含滚动条的尺寸
96案例 懒加载
97 初识事件
var oDiv = document.querySelector('div')
oDiv.onclick = function () {}
// 谁来触发事件 => oDiv => 这个事件的事件源就是 oDiv
// 触发什么事件 => onclick => 这个事件类型就是 click
// 触发之后做什么 => function () {} => 这个事件的处理函数
以on为前缀(dom0绑定方式)
这个方式不是很好,只能给一个元素注册一个事件,一旦写了第二个事件,那么第一个就被覆盖了
<body>
<button id="btn" >抽奖</button>
<script>
btn.onclick=function(){
this.disabled="disabled"
}
</script>
</body>
点完按钮禁用
addEventListener监听(dom2)
绑定多个事件处理函数,按照顺序执行
此方法不兼容,在 IE 里面要使用 attachEvent
oDiv.addEventListener('click', function () {
console.log('第一个事件')})
oDiv.addEventListener('click', function () {
console.log('第二个事件')})
点击 div 的时候,两个函数都会执行,并且会按照注册的顺序执行
98事件解绑
btn.onclick=function(){
this.onclick=null
//解绑
}
法二
<body>
<button id="btn" >抽奖</button>
<script>
function handler(){
this.removeEventListener("click",handler)
}
btn.addEventListener("click",handler)
</script>
</body>
99事件类型
浏览器事件
load : 页面全部资源加载完毕
scroll : 浏览器滚动的时候触发
鼠标事件
click :点击事件
dblclick :双击事件
contextmenu : 右键单击事件
mousedown :鼠标左键按下事件
mouseup :鼠标左键抬起事件
mousemove :鼠标移动
mouseover :鼠标移入事件
mouseout :鼠标移出事件
mouseenter :鼠标移入事件
mouseleave :鼠标移出事件
键盘事件
keyup : 键盘抬起事件
keydown : 键盘按下事件
keypress : 键盘按下再抬起事件
表单事件
focus获取焦点
blur失去焦点
change : 表单内容改变事件
input : 表单内容输入事件
submit : 表单提交事件
reset:重置
触摸事件
针对移动端
touchstart : 触摸开始事件
touchend : 触摸结束事件
touchmove : 触摸移动事件
…
100事件对象
形参
触发了一个事件以后,对该事件的一些描述信息
比如:你触发一个点击事件的时候,你点在哪个位置了,坐标是多少
每一个事件都会有一个对应的对象来描述这些信息,我们就把这个对象叫做 事件对象
101鼠标事件
距离可视窗口的,移动滚动条,值会改变
相对于页面(文档流),不随滚动条改变
触碰点距离触发元素的左上角的坐标值
102鼠标跟随
<style>
*{
margin: 0;
padding: 0;
}
#box{
width: 200px;
height: 50px;
margin: 100px;
background-color: yellow;
position: relative;
}
#box p{
width: 300px;
height: 200px;
background-color: lightpink;
position: absolute;
display: none;
pointer-events: none;
/* 穿透,鼠标碰到不影响 */
}
</style>
</head>
<body>
<div id="box">
人物
<p>
介绍
</p>
</div>
<script>
box.onmouseover=function(){
this.firstElementChild.style.display="block"
}
box.onmouseout=function(){
this.firstElementChild.style.display="none"
}
box.onmousemove=function(a){
this.firstElementChild.style.left=a.offsetX+"px"
this.firstElementChild.style.top=a.offsetY+"px"
}
</script>
</body>
103鼠标拖拽
<style>
*{
margin: 0;
padding: 0;
}
#box{
width: 100px;
height: 100px;
background-color: lightblue;
position: absolute;
}
</style>
</head>
<body>
<div id="box">
</div>
<script>
box.onmousedown=function(){
document.onmousemove=function(dist){
//box.style.left=dist.clientX+"px"
//box.style.top=dist.clientY+"px"
//此时,鼠标在块的左上角
let x=dist.clientX-box.offsetWidth/2
let y=dist.clientY-box.offsetHeight/2
//设置块运动的范围
if(y<=0)
y=0
//最高处在最顶部
if(x<=0)
x=0
//最左端做限制
if(x>=document.documentElement.clientWidth-box.offsetWidth)
x=document.documentElement.clientWidth-box.offsetWidth
//为使其最右在最右端,要使距离为窗口宽-自身宽
if(y>=document.documentElement.clientHeight-box.offsetHeight)
y=document.documentElement.clientHeight-box.offsetHeight
//下端也是
box.style.left=x+"px"
box.style.top=y+"px"
}
}
box.onmouseup=function(){
document.onmousemove=null
//解绑移动的
}
</script>
</body>
实现效果:鼠标在块的中间随鼠标移动,块最远位置就是四周贴墙走
104 标准的DOM事件流
- 目标:你是点击在哪个元素身上了,那么这个事件的 目标 就是什么
- 冒泡:就是从事件 目标 的事件处理函数开始,依次向外,直到window 的事件处理函数触发,也就是从下向上的执行事件处理函数
- 捕获:就是从 window 的事件处理函数开始,依次向内,只要事件 目标 的事件处理函数执行,也就是从上向下的执行事件处理函数
顺序:
1.捕获:从window到内
2.目标
3.冒泡:从内到外
冒泡和捕获的区别
就是在事件的传播中,多个同类型事件处理函数的执行顺序不同
默认情况,只在冒泡触发,也就是从内到外
105stopPropagation阻止事件传播
106阻止默认行为
右键取消默认菜单
dom0 return false
<script>
document.oncontextmenu=function(){
return false
}
</script>
dom2 preventDefault
<script>
document.addEventListener("contextmenu",function(a){
a.preventDefault()
})
</script>
107案例自定义右键菜单
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
ul{
width: 200px;
padding:10px;
border: 1px solid gray;
display: none;
position: absolute;
}
ul li:hover{
background-color: skyblue;
}
</style>
</head>
<body>
<ul id="list">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
</div>
<script>
document.addEventListener("contextmenu",function(a){
a.preventDefault()
list.style.display="block"
let x=a.clientX
let y=a.clientY
list.style.left=x+"px"
list.style.top=y+"px"
//跟随鼠标
})
</script>
</body>
108事件委托
减少多个函数的绑定的性能损耗
动态添加li,也会有事件处理
target
target 这个属性是事件对象里面的属性,表示你点击的目标,当你触发点击事件的时候,你点击在哪个元素上,target 就是哪个元素
<body>
<ul>
<li>
<button>add</button>
</li>
</ul>
</body>
<script>
list.onclick=function(a){
console.log(a.target)
}
</script>
点击谁触发谁