前端进阶之--JavaScript--DOM--BOM操作

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 节点:不止元素,还包括文本(空格&nbsp;换行<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&gt;p</p>
    <span>div&gt;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
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页