BOM
- Browser Object Model,浏览器对象模型,js代码操作浏览器
结构图:
#1、DOM对象也是BOM的一部分
#2、window对象是BOM的顶层(核心)对象
# 需要注意的是
1、在调用window对象的方法和属性时,可以省略window,例如:window.document.location可以简写为
document.location
2、全局变量也是windows对象的属性,全局的函数时window对象的方法
1、内置对象
-window
- 查看窗口尺寸
window.innerHeight //当前窗口高度
165
window.innerWidth //当前窗口宽度
722
- 新建窗口,可指定尺寸
# 新建窗口打开页面 第二个参数写空 第三个参数写窗口的大小和位置
//默认屏幕左上角打开
window.open('https://pixivic.com/?VNK=5f2695f6','','height=500px,width=500px')
Window {parent: Window, opener: Window, top: Window, length: 0, frames: Window, …}
//指定打开位置
open('https://pixivic.com/?VNK=5f2695f6','','height=500px,width=500px,top=400px,left=600px')
# 扩展父子页面通信 window.opener()
- 关闭当前的页面
window.close()
2、window子对象
window.
可以点出来很多对象
-navigator
1)
window.navigator.appName //浏览器名字
"Netscape"
2)
window.navigator.appVersion //浏览器版本
"5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36 Edg/85.0.564.51"
3)#重要:标识是否是浏览器
window.navigator.userAgent
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36 Edg/85.0.564.51"
/*
扩展:防爬措施
1.最简单常用的一个就是校验当前请求的发起者是否是一个浏览器
请求头中:
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/85.0.4183.102 Safari/537.36 Edg/85.0.564.51
破解措施:
代码中加上上面的user-agent配置
*/
4)
window.navigator.platform //平台
"Win32"
-history
window.history.back() // 回退到上一页
window.history.forword() //前进到下一页
window.history.go(0) //刷新
window.history.go(n) //前进到第n页 ,正数前进,负数后退
-location
1)
window.location // 拿到当前地址信息
//包括本地连接href、orgin源地址...
Location {href: "https://pixivic.com/?VNK=5f2695f6", ancestorOrigins: DOMStringList,
origin: "https://pixivic.com", protocol: "https:", host: "pixivic.com", …}
2)
window.location.href //获取当前地址
"https://pixivic.com/?VNK=5f2695f6"
window.location.href = url //也可以赋值,跳转到连接地址
如:window.location.href = "https://www.baidu.com/"
3)//刷新
window.location.reload()
//window.history.go(0)
链接跳转练习:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>location对象练习</title>
</head>
<body>
<div>点我去百度</div>
<script>
var divEle = document.getElementsByTagName("div")[0]
divEle.onclick = function () {
//onclick 给对象添加点击后功能
window.location.href = "https://www.baidu.com/";
}
</script>
</body>
</html>
3、弹出框
- 只能在自己写的页面上操作,别人的页面会禁止弹窗
-警告框&确认框&提示框
#警告框
//window.alert()的简写,因为它是window的子方法
alert('stop!!!')
undefined
#确认框,兼容不好
confirm('are you sure ?')
false //点了取消是False
confirm('are you sure ?')
true
#提示框,不推荐使用
prompt('请在此输入')
null //点取消返回null
undefined
prompt('请在此输入:','默认内容') //可设置默认输入参数
"用户输入的内容" //确认即返回用户输入内容
prompt 英: [prɒmpt] n. 提示;提示符
4、计时器
-过一段时间后触发(一次性)
# body内script
1)定时
<script>
function func1() {
alert(123)
}
setTimeout(func1,3000) // 毫秒为单位 3秒后执行func1
</script>
2)清除定时
<script>
function func1() {
alert(123)
}
let t = setTimeout(func1,3000);
// 给定时任务指定变量名
clearTimeout(t)
//取消定时任务,如果要清除,需要事先用变量指代定时任务
</script>
-每隔一段时间触发一次(循环触发)
interval [ˈɪntə(r)v(ə)l] n.间隔;区间;时间间隔
function func2() {
alert(123)
}
function show(){
let t = setInterval(func2,3000) //每隔3秒钟执行func2
function inner(){
clearInterval(t) //inner为清除Interval
}
setTimeout(inner,9000) //9s之后执行inner
}
show()
//每隔3秒弹窗一次,弹3次后结束
-p.s.
1)setTimeout:
<!--注意,若写到html文件中,每次刷新都会重新执行代码-->
<script>
setTimeout(function (){
location.reload
},3000) //依旧有循环刷新的效果
</script>
2)setInterval:
<script>
setInterval(function (){
location.href = "https://www.baidu.com/"
},3000) //默认当前页打开,新页面不会再执行原来页面的代码
</script>
DOM
-
Document Object Model,文档对象模型,js代码操作标签
-
当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model),DOM标准规定HTML文档中的每个成员都是一个节点(node),HTML DOM树如下图
# 所有标签都可以称之为节点 # JavaScript 可以通过DOM创建动态的 HTML: JavaScript 能改变页面中所有HTML元素 JavaScript 能改变页面中所有HTML属性 JavaScript 能改变页面中所有CSS样式 JavaScript 能对页面中所有事件做出反应 # DOM操作的是标签 1.先会查找标签 2.再操作标签 # DOM操作必须用document起手
p.s. 节点&元素区别
- node 节点:不止元素,还包括文本(
空格
、换行<br>
等也算文本) - 元素:即 标签
//如:childNodes,结果含text
var res = document.getElementById('d1').childNodes
undefined
console.log(res)
VM175:1 NodeList(6) [text, p#d2, text, span, text, div]
1、查找节点
- 准备
<!--html定义标签-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>dom标签查找</title>
</head>
<body>
<div>div上面的div</div>
<div>div上面的div</div>
<div id="d1">div d1
<div>div下div</div>
<p class="c1">div下p
<span>div下p下span</span>
</p>
<p>div下2p</p>
</div>
<div>div下div</div>
<div>div下div</div>
</body>
</html>
-直接查找(重点)
id查找
# getElementById 单数的element
id是独一无二的,直接返回了值
类查找
# getElementsByClassName 复数的elements
拿到的是数组
标签查找
# getElementsByTagName 复数的elements
返回数组
document.getElementById('d1')
<div id="d1">…</div>
//没有返回null
document.getElementsByClassName('c1')
HTMLCollection [p.c1]0: p.c1length: 1__proto__: HTMLCollection
document.getElementsByTagName('div')
HTMLCollection(6) [div, div, div#d1, div, div, div, d1: div#d1]
-标签对象的赋值
# 当用变量名指代标签对象的时候,一般情况下都书写成:
xxxEle:
divEle
pEle
aEle
# 除了id直接取到了值,其他需要索引取值:
let pEle = document.getElementsByClassName('c1')
undefined
pEle.parentElement
undefined
pEle
HTMLCollection [p.c1] //结果是数组
let pEle = document.getElementsByClassName('c1')[0]
//若想进一步处理,一定要取值
undefined
pEle
<p class="c1">"div下p
"<span>div下p下span</span></p>
-间接查找
语法 | 含义 |
---|---|
childNodes | 获取所有的子节点,除了元素还有文本等 |
children | 获取所有元素子节点,不包含文本 |
parentNode | 获取父节点 |
previousSibling | 获取上一个兄弟节点,包含文本 |
previousElementSibling | 获取上一个兄弟元素节点,不包含文本 |
nextSibling | 获取下一个兄弟节点,包含文本 |
nextElementSibling | 获取下一个兄弟元素节点,不包含文本 |
firstChild | 获取第一个子节点,包含文本 |
firstElementChild | 获取第一个子节点,不包含文本 |
lastChild | 获取最后一个子节点,包含文本 |
lastElementChild | 获取父元素最后一个元素节点。不包含文本 |
# 找父级标签 .parentElement
let pELe = document.getElementsByClassName('c1')[0]
pEle.parentElement
<div id="d1">…</div>
//可以一级级一直点下去,直到null
pEle.parentElement.parentElement
<body>…</body>
pEle.parentElement.parentElement.parentElement
<html lang="en"><head>…</head><body>…</body></html>
pEle.parentElement.parentElement.parentElement.parentElement
null
# 找子级标签 .children
let divEle=document.getElementById('d1')
undefined
divEle
<div id="d1">…</div>
divEle.children //所有子标签
HTMLCollection(3) [div, p.c1, p]0: div1: p.c12: plength: 3__proto__: HTMLCollection
divEle.childElementCount //子标签个数
3
divEle.firstElementChild //大儿子
<div>div下div</div>
divEle.lastElementChild //小儿子
<p>div下2p</p>
# 找毗邻标签(下同级别第一个)
divEle.nextElementSibling
<div>div下div</div>
# 找哥哥标签(上同级别第一个)
divEle.previousElementSibling
<div>div上面的div</div>
divEle.previousSibling
#text
2、节点操作
- 若不写入html文件中,在console控制台直接修改的,都是临时操作
2.1 增加节点
#1、创建新节点
var divEle = document.createElement('div');
#2、追加一个子节点(放到最后)
somenode.appendChild(新的子节点);
#3、插入一个子节点(插入到某个节点前)
somenode.insertBefore(新的子节点,某个节点);
2.2 删除、替换节点
somenode.removeChild(要删除的子节点);
somenode.replaceChild(新的子节点, 某个子节点);
2.3 修改/设置节点属性
#1、获取文本节点的值:
var divEle = document.getElementById("d1")
divEle.innerText
divEle.innerHTML
#2、设置文本节点的值:
var divEle = document.getElementById("d1")
divEle.innerText="1"
divEle.innerHTML="<p>2</p>"
#3、attribute操作
var divEle = document.getElementById("d1");
divEle.setAttribute("age","18")
divEle.getAttribute("age")
divEle.removeAttribute("age")
#4、自带的属性还可以直接.属性名来获取和设置
imgEle.src
imgEle.src="..."
2.4 获取元素的值
#适用于input、select、textarea标签
var x=document.getElementById('input')
var y=document.getElementById('select')
var z=document.getElementById('textarea')
x.value
y.value
z.value
2.5 class操作
- classlist 批量修改样式
#拿到属性列表
var x=document.getElementById('div1')
x.classList.remove('oldClassName') //移除已经存在的类名;
x.classList.add('newClassName') //添加新的类名,如已经存在,取消添加
x.classList.contains('oldClassName') //确定元素中是否包含指定的类名,返回值为true 、false;
x.classList.toggle('className') //如果classList中存在给定的值,删除它,否则,添加它;
x.classList.replace('oldClassName,newClassName');//类名替换
toggle 英: [ˈtɒɡ(ə)l] n.套索扣;转换键;切换键
示例:
var divEle = document.getElementsByTagName('div')[0];
//注意取值
var x = divEle.classList
//将classList赋值给变量x
x
DOMTokenList(3) ["d1", "d2", "d3", value: "d1 d2 d3"]
x.add('d4'); //加类名
undefined
x
DOMTokenList(4) ["d1", "d2", "d3", "d4", value: "d1 d2 d3 d4"]
x.remove('d1'); //移除
undefined
x
DOMTokenList(3) ["d2", "d3", "d4", value: "d2 d3 d4"]
#toggle
x.toggle('d2'); //存在返回f并移除
false
x
DOMTokenList(2) ["d3", "d4", value: "d3 d4"]
x.toggle('d5'); //不存在返回t并添加
true
x
DOMTokenList(3) ["d3", "d4", "d5", value: "d3 d4 d5"]
2.6 css操作
obj.style.backgroundColor="red"
JS操作CSS属性的规律:
1.对于没有中横线的CSS属性一般直接使用style.属性名即可。如:
obj.style.margin
obj.style.width
obj.style.left
obj.style.position
2.对含有中横线的CSS属性,将中横线后面的第一个字母换成大写即可。如:
obj.style.marginTop //CSS中:margin-top
obj.style.borderLeftWidth
obj.style.zIndex
obj.style.fontFamily
-
准备
<!--html下定义标签--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>DOM节点操作</title> </head> <body> <div id = 'd1'>div <p id="d2">div>p</p> <span>div>span</span> </div> </body> </html>
-动态创建标签且给标签添加属性
//通过DOM操作动态地创建img标签,并且给标签创建属性
第一步:创建标签并设置属性
#1 定义标签
let imgEle = document.createElement('img')
undefined
imgEle
<img>
#2 给标签添加属性方式一:.属性名='属性值'
imgEle.src = 'worldtrigger1.jpg'
"worldtrigger1.jpg"
imgEle
<img src="worldtrigger1.jpg">
#2 方式二:.setAttribute('属性名','属性值')
//设置自定义属性:.setAttribute('属性名','属性值')
imgEle.setAttribute('username','UMA')
undefined
imgEle
<img src="worldtrigger1.jpg" title="KUGA" username="UMA">
//此方法也可设置默认属性,但是.操作有提示
undefined
imgEle.setAttribute('title','KUGA')
undefined
imgEle
<img src="worldtrigger1.jpg" title="KUGA">
第二步:找到要添加的位置标签,创建标签对象
let divEle = document.getElementById('d1')
undefined
divEle
<div id="d1">…</div>
第三步:标签内部追加元素(数组appendChild)
divEle.appendChild(imgEle) //临时添加渲染,非永久
<img src="worldtrigger1.jpg" title="KUGA">
//刷新之后就没有了
-动态创建标签并添加文本
第一步:创建要添加的a标签
let aEle = document.createElement('a')
undefined
aEle
<a></a>
aEle.href = 'https://www.baidu.com/'
"https://www.baidu.com/"
aEle
<a href="https://www.baidu.com/"></a>
aEle.innerText = '点我去百度'
"点我去百度"
aEle
<a href="https://www.baidu.com/">点我去百度</a>
第二步:拿到定位位置的标签
//添加到指定的标签的‘上面’
let divEle=document.getElementById('d1')
undefined
let pEle = document.getElementById('d2')
undefined
第三步:insertBefore插入
//标签内部.insertBefore(插入的标签,在谁的前面)
divEle.insertBefore(aEle,pEle)
<a href="https://www.baidu.com/">点我去百度</a>
-其他操作
removeChild()
replaceChild()
setAttribute() # 设置属性
getAttribute() # 获取属性
removeAttribute() # 移除属性
-innerText & innerHTML
#1 innerText
divEle.innerText //拿到文本内容
"div 点我去百度
div>p
div>span"
#1 innerHTML
divEle.innerHTML //文本标签都拿到
"div
<a href="https://www.baidu.com/">点我去百度</a><p id="d2">div>p</p>
<span>div>span</span>
"
#2 给innerText结果赋值 (不识别标签)
divEle.innerText = "hahaha"
"hahaha"
//查看元素Element,发现里面的代码中,div只留下了文本"hahaha"
divEle.innerText = "<h1>ohohoh</h1>"
"<h1>ohohoh</h1>"
//查看元素中代码,发现就是文本,写什么是什么
//<div id="d1"><h1>ohohoh</h1></div>
#2 给innerHTML结果赋值 (识别标签)
divEle.innerHTML = "<h1>ohohoh</h1>"
"<h1>ohohoh</h1>"
//发现变成了标签
<div id="d1"><h1>ohohoh</h1></div>
小结:
innerText 只应用于修改那些纯文本的标签
innerHTML 存在覆盖效果,对于有子标签的元素要慎用
习题:
Q:1000元存到银行,年利率5%,求多少年之后本利和达到5000元
# javascript 实现
var n = 0
undefined
var money = 1000
undefined
while (money<=5000){
money*=1.05
++n
}
33
console.log(n)
VM632:1 33
''' python 实现 '''
# 1)while循环
n = 0
money = 1000
while True:
money *= 1.05
print(money)
n += 1
if money >= 5000:
break
print(n)
# 2)递归
def year_count(n,money):
if money >= 5000:
return # 注意return的位置,一定要结果超过5000
money *= 1.05
n += 1
print(money, n)
year_count(n,money)
year_count(0,1000) # 从第0年开始,已有本金1000元
>>>
...
5003.18854203379 33
# 或者<=5000
def year_count(n, money):
if money <= 5000:
money *= 1.05
n += 1
print(money, n)
year_count(n, money)
return
year_count(0, 1000)
>>>
...
5003.18854203379 33
1000
undefined
while (money<=5000){
money*=1.05
++n
}
33
console.log(n)
VM632:1 33
''' python 实现 '''
# 1)while循环
n = 0
money = 1000
while True:
money *= 1.05
print(money)
n += 1
if money >= 5000:
break
print(n)
# 2)递归
def year_count(n,money):
if money >= 5000:
return # 注意return的位置,一定要结果超过5000
money *= 1.05
n += 1
print(money, n)
year_count(n,money)
year_count(0,1000) # 从第0年开始,已有本金1000元
>>>
...
5003.18854203379 33
# 或者<=5000
def year_count(n, money):
if money <= 5000:
money *= 1.05
n += 1
print(money, n)
year_count(n, money)
return
year_count(0, 1000)
>>>
...
5003.18854203379 33