BOM+DOM
一、BOM介绍
概述:BOM 是Browser Object Model的缩写,简称浏览器对象模型, 提供了独立于内容而与浏览器窗口进行交互的对象,用于访问浏览器的功能。也就意味他可以获取浏览器上的所有内容及相关的操作。BOM缺乏规范的,存在共有对象来解决这个问题,但是共有对象也存在兼容问题(ie10以后)
window
window对象是BOM的核心, window对象表示浏览器窗口的一个对象, 每个浏览器窗口都有一个window对象与之对应. window对象是BOM的顶层(核心)对象,所有对象都是通过它延伸出来的.
二、BOM中的对象和方法
1、window
(1)window对象的属性对象
- document(核心): 文档对象,让我们可以在js脚本中直接访问页面元素(DOM)
- history(重要): 历史对象,包含窗口的浏览历史,可以实现后退
- location(重要): 包含浏览器当前的地址信息,可以用来刷新本页面或跳转到新页面
- frames: 框架对象,可以获取页面框架内容
- screen: 包含有关客户端显示屏幕的信息
- navigator: 导航对象, 包含所有有关访问者浏览器的信息
相关属性
innerHeight和innerWidth
(2)相关方法
(2.1)打印方法
// window对象
console.log(window);//window对象 Window的构造函数
// 常用的弹窗方法及打印方法
window.console.log('hello')//console.log() window可以省略
console.log('日志');//控制台 log日志 以日志的形式打印
console.error('错误');//以错误的形式打印
console.warn('警告');//以警告的形式打印
(2.2)弹窗方法
// 弹窗
window.alert('hello')//弹窗提醒
var isTrue = confirm('你确认要删除吗')//交互窗 true确认 false取消 返回
console.log(isTrue);
var str = prompt()//输入框 有个输入框让你输入 返回对应的string类型的内容
console.log(str);
(2.3)打开关闭方法
//打开 open 关闭 close
// 第一个参数是url地址 第二个参数为title target(打开方式 _blank _self _parent) 第三个参
数为设置的参数(窗口的高度 宽度等等)
window.open('http://www.baidu.com','_blank','width=300,height=100,top=0,left=0')
// height=100 窗⼝⾼度;
// width=400 窗⼝宽度;
// top=0 窗⼝距离屏幕上⽅的象素值;
// left=0 窗⼝距离屏幕左侧的象素值;
// toolbar=no 是否显⽰⼯具栏,yes为显⽰;
// menubar,scrollbars 表⽰菜单栏和滚动栏。
// resizable=no 是否允许改变窗⼝⼤⼩,yes为允许;
// location=no 是否显⽰地址栏,yes为允许;
// status=no 是否显⽰状态栏内的信息(通常是⽂件已经打开),yes为允许;
window.close() //关闭当前的窗口 (关闭浏览器只能有一个页面)
(2.4)改变位置的方法
//moveBy 一个是x轴的距离 y轴的距离
window.moveBy(100,100) //X+100 Y+100
//moveTo 一个x轴 一个y轴
window.moveTo(200,200) //X=200 Y=200
(2.5)改变大小的方法
//改变对应的窗口大小
window.resizeBy(200,200) //width+200 height+200
//resizeTo
window.resizeTo(200,200) //width=200 height=200
(2.6)打印方法
//print打印方法
window.print()
(2.7)聚焦和失焦的方法
//focus 聚焦 blur 失去焦点
window.focus()
window.blur()
(2.8)查找方法
//find查找 ctrl+f
window.find()
(2.9)滚动栏位置改变
//滚动栏位置改变 初始位置 x:0,y:0
window.scrollBy(100,100) //原本的位置 x+100,y+100
window.scrollTo(500,500) //到达位置 x=500 y=500 //回到顶部
2、
console.log(location.hash) //哈希 #后面带的值 *
console.log(location.host) //主机 域名 ip地址+端口号
console.log(location.hostname) //主机名 ip地址 (127.0.0.1表示本机地址和localhost是一
样的)
console.log(location.protocol) //协议 用于通信 (基于tcp/ip)http(明文传输)
https(安全)(加密过)
console.log(location.port) //端口号 1--65525 (1-100的端口电脑占用了)http默认的端口
80 https默认端口443
console.log(location.href) //链接的地址 也可以设置
console.log(location.search); //?后面带的值 一般是get请求传输数据的时候 *
console.log(location.origin); //跨域
console.log(location.pathname); //路径名 获取的除了协议和ip地址加端口号后面的东西
(2)方法
(2.1)assign跳转页面
location.assign('http://www.baidu.com')
(2.2)replace替换页面
location.replace('http://www.weibo.com')
(2.3)reload重新加载页面
location.reload()
//参数 boolean类型的值 true(从服务器加载 慢) false (从缓存中加载 快)
3、
- length 历史页面个数
- state 状态存储的对象
- scrollRestoration 滚动栏恢复
(2)方法
(2.1)forwad 前进
function fn(){
history.forward() //前进
}
(2.2)back 后退
function fn1(){
history.back() //后退
}
(2.3)go 去任意的历史页面
function fn2(){
history.go(-1) //去任意页面 0就是自己 小于0 后退 大于0前进
}
(2.4)pushState
//spa 单页应用
function fn3(){
//添加state的值 数据 "" 地址(会产生跨域问题)
history.pushState('hello','','./index.html') //会改地址 但是不会刷新 推一个历史页
面到历史区 state设置进去
}
(2.5)replaceState
function fn4(){
//替换state
history.replaceState('world','','/location对象讲解.html') //会改地址 但是不会刷新
在历史区直接修改当前这个历史页面 state设置进去
}
4、
- avaliHeight 可占用的最大高度
- avaliWidth 可占用的最大宽度
- avaliLeft 离屏幕左侧的距离
- avaliTop 离屏幕上方的距离
5、
根据对应的接口地址来访问不同的功能 (后端路由 restful风格(接口的风格))
(2)前端路由
根据不同的访问路径 (path)来渲染不同的内容(组件)
- location.href
- location.assign()
- location.replace()
- history.back()
- history.forward()
- 等这系列的操作都会导致页面进行跳转,重新加载页面(刷新)
(2.2)hash路由 (使用hash来实现 后面必须要带上# 不会刷新页面)
通过hash的改变来改变的对应的渲染内容 (事件监听 onhashchange)
window.onhashchange = function(){
console.log('hash值变了')
}
(2.3)H5路由 (history里面state进行监听)(常用SPA (单页应用程序))
-
-
history.replaceState() 替换历史页面 (地址变量 不会刷新)
-
-
window.onpopstate = function(){ console.log('路由改变了') }
在对应的框架学习中 我们里面的路由的写法底层主要采用hash以及h5的方式(vue react)默认是路由模式为hash
问题:vue中路由有几种模式 (面试题)
答案:俩种模式(hash模式和history模式)
三、DOM
1、DOM概述:
DOM 全称(document object model)文档对象模型(文档指定为对应html文档),对应的DOM就
是操作HTML文档的(增删改查)
2、DOM结构
3、document文档对象
方法
(1)获取全局的内容
- document.getElementById() //通过id属性来获取元素,返回的是一个元素 (Element)
/通过id获取对应的元素
var box = document.getElementById('box')
console.log(box);
- document.getElementsByClassName() //通过class属性名来获取元素 ,返回是一个伪数组
(HTMLCollection)
// (length 下标) 所有的伪数组都具备的
//通过class属性获取
var content = document.getElementsByClassName('content')
console.log(content);
console.log(content[0]); //访问第一个获取的元素
- document.getElementsByTagName() //通过标签名获取元素
(HTMLCollection)
//通过标签名获取
var div = document.getElementsByTagName('div')
console.log(div);
- document.getElementsByName() //通过name属性来获取元素
(NodeList)
//通过name属性获取
var jack = document.getElementsByName('jack')
console.log(jack);
console.log(jack[0]);
- document.querySeletorAll() //通过对应的选择器进行获取,返回的是一个伪数组 (NodeList)
//通过选择器获取
var divs = document.querySelectorAll('div') //传入的选择器为div
console.log(divs);
- document.querySeletor() //通过选择器获取元素 ,返回的是第一个查找到的元素 (Element)
//通过选择器获取第一个元素
var first = document.querySelector('div')
console.log(first);
- document.getRootNode() //获取根节点
console.log(document.getRootNode()); //获取根节点
(2)创建全局的内容
- 创建元素 document.createElement() 返回的是一个元素
//创建的方法
var p = document.createElement('p') //传入的是一个对应的标签名
console.log(p);
- 创建属性节点 document.createAttribute() 返回的是一个属性对象
//创建属性的方法
var attr = document.createAttribute('password') //创建的是一个属性 默认为空值
//给属性对象赋属性值的操作
attr.value = '123456'
console.log(attr);
- 创建文本节点 document.createTextNode() 返回的是一个文本节点对象
//创建文本
var text = document.createTextNode('显示内容') //创建一个文本节点对象
console.log(text);
//后面带NS表示的是命名空间 内声明或获取
属性
- document.head //获取head标签
- document.body //获取body标签
- document.forms //获取所有的表单标签 返回的是一个HTMLCollection
4、Element元素对象
方法
(1).获取元素 (document的相关方法 element也可以使用)
var element = document.getElementById('box')
console.log(element.getElementsByTagName('img'));
(2)替换元素(replace)
- replaceChild (用一个新的元素来替换里面的子元素)
- replaceChildren (用一个元素来替换里面所有的子元素)
div.replaceChildren("hello") //替换所有的子节点 用传入的节点替换里面所有的子节点 var content = document.createElement('div') div.replaceChildren(content) //替换所有的子节点 用传入的节点替换里面所有的子节点 //replaceChild 用前面的替代后面的(一定是属于我们本身的儿子元素) var a = document.createElement('a') div.replaceChild(a,div.children[0]) //使用新的节点来替换对应的子节点 使用a这个元素来替代 对应的content这个子元素
(3)插入元素(插入对应的子元素)
- append 插入任意的子元素到对应的父元素内 插入到后面
- appendChild 插入一个子元素到对应的父元素内容 插入到后面
- insertBefore 插入一个元素到另一个子元素的前面
// 插入元素 append inster
div.append("hello",content) //追加内容到当前元素里面的最后一个元素的后面 追加多个
// appendChild 追加子元素
var b= document.createElement('b')
div.appendChild(content) //追一个元素在当前元素的里面 (同一个元素只能允许加一次 里面存在
是不可以添加的)
div.appendChild(b) //追一个元素在当前元素的里面
//insertBefore
var span = document.createElement('span')
//参数1 当前需要插入的元素 参数2 对应的子元素
div.insertBefore(span,div.children[0]) //插入到哪个子元素的前面
(4)删除元素
div.remove() //全部删除 包括自己
// 清空所有的内容 使用replaceChildren('')
(5)cloneNode方法
var cloneDiv = div.cloneNode() //进行元素克隆
console.log(cloneDiv); //只会克隆自己 并不会克隆里面包含对应的内容
var div1 = div.cloneNode(true) //里面是true的情况表示深度克隆 他会考虑所有的内容包括事件
console.log(div1);
(6)对于的属性的操作方法
- setAttribute
//element.setAttribute(name,value)
//不仅可以操作 后续定义的属性 也可以操作本身就有的属性
var box = document.querySelector('div')
box.setAttribute('width','100px')
- getAttribute
//element.getAttribute(name)
box.setAttribute('username','tom')
console.log(box.getAttribute('width'));//返回对应的值 一般都是string
console.log(box.getAttribute('username'));//返回对应的值 一般都是string
- removeAttribute
//element.removeAttribute(name)
box.removeAttribute('width')
属性
A、只读属性
(1)获取父元素
// 相关属性
var div = document.getElementsByTagName('div')[0]
// 获取父元素
console.log(div.parentElement);//body
(2)获取子元素
// 获取子元素
console.log(div.childElementCount); //子元素个数
console.log(div.children); //获取子元素 (伪数组)
(3)获取兄弟元素
- 前面的兄弟
// 获取兄弟元素
// 前一个兄弟 (pre表示前面的)
console.log(div.previousElementSibling);
- 后面的兄弟
// 后一个兄弟 (next表示后面)
console.log(div.nextElementSibling)
B、所有元素都具备的属性
(1)className
// className 获取对应的class名字
console.log(div.className);
div.className = 'abc'
(2)id
//id 属性 获取对应的id
console.log(div.id); //空值
div.id = "box"
(3)style
//元素的其他属性 所有元素都有的属性
console.log(div.style); //相当于获取div里面style属性 内嵌样式 对象(只能读取style里面设
置的)
console.log(div.style.width); //style里面设置的 100px
console.log(div.style.height); //"" 不是style属性设置的不能读取
// 可写的属性 style的用户 element.style.样式名 赋值就是给设置 不赋值就是获取
div.style.backgroundColor = 'red'
(4)title
//title 标题
console.log(div.title);
div.title = "hello"
(5)name
// name属性
console.log(div.name)
(6)tagName
//tagName 大写的字符串 只读属性
console.log(div.tagName);
(7)innerHTML和innerText
//innerHtml 显示的html(所有) innerText 显示的文本(所有的文本)
console.log(div.innerHTML);
console.log(div.innerText);
div.innerHTML = "<b>hello</b>" //解析html代码的
div.innerText = "<b>hello</b>" //不会解析html代码的
(8)attributes获取所有的属性节点(返回的是一个NameNodeMap)
console.log(ele.attributes);//nameNodeMap 伪数组 (key:value) 迭代器
console.log(ele.attributes.length)
//访问
console.log(ele.attributes[0]) //属性节点对象
console.log(ele.attributes['href'].nodeValue)
console.log(ele.attributes['href'].value)
for(var key in ele.attributes){ //字符串
console.log(ele.attributes[key]);
}
// nameNodeMap的方法getNameItem setNameItem removeNameItem item
//其中一个属性对象
console.log(ele.attributes.getNamedItem('hello'));
//设置
var attr1 = document.createAttribute('abc') //属性节点
attr1.value = 'bca'
ele.attributes.setNamedItem(attr1)
//remove属性
ele.attributes.removeNamedItem('href')
// item 获取属性对象
console.log(ele.attributes.item(0));
C、每个元素默认带的属性 都可以通过对应的元素直接点出来
(1)如 a标签的href的属性 input的value属性 img的src属性等
//所有元素对于本身自带属性都直接点出来
var input = document.querySelector('input')
console.log(input.placeholder);
input.placeholder = "请输入"
console.log(input.value);
console.log(input.type);
var a = document.querySelector('#a')
console.log(a.href);
var img = document.querySelector('img')
console.log(img.src);
5、节点操作
(1)节点分类
- 元素节点 (element)
- 属性节点 (attribute)
- 文本节点 (text)
(2)节点相关属性
- parentElement 父元素(只能是element)
- parentNode 父节点 (一般也是element)
- childNodes 子节点 (伪数组 (nodeList)文本节点及元素节点)
- children 子元素节点 (HTMLCollection element)
- previousElementSibling 上一个兄弟元素节点 (element 元素节点)
- previousSibling 上一个兄弟节点(文本节点 元素节点)
- nextElementSibling 下一个兄弟元素节点 (element 元素节点)
- nextSibling 下一个兄弟节点 (文本节点 元素节点)
- lastChild 最后一个子节点 (文本节点 元素节点)
- firstChild 第一子节点 (文本节点 元素节点)
(3)一般形式下 只有删了空文本节点才进行第一个和最后一个的获取
var ul = document.querySelector('ul')
for(var i=0;i<ul.childNodes.length;i++){
if(ul.childNodes[i].nodeType == 3 &&
/^\s+$/.test(ul.childNodes[i].nodeValue)){
//删除子节点
ul.removeChild(ul.childNodes[i])
}
}
console.log(document.querySelector('ul').firstChild);
console.log(document.querySelector('ul').lastChild);
空文本 空格换行及制表符都是空文本节点
(4)节点分类的区分属性
- nodeType 节点类型 (1表示元素节点 2表示属性节点 3表示文本节点)
- nodeValue 节点值 (元素节点的节点值获取不到(null)属性节点的节点值 属性值文本节点 文本内容)
- nodeName 节点名 (元素节点的节点就是标签名属性节点的节点名就是属性名 文本节点 #text)
var tagA = document.createElement('a') //元素节点
tagA.innerHTML = "hello"
var attr = document.createAttribute('name') //属性节点
attr.value = '张三'
var text = document.createTextNode('你好') //文本节点
//nodeName 节点名 元素的节点名是大写的 属性节点节点名小写 文本节点都是#text (只读属性)
console.log(tagA.nodeName,attr.nodeName,text.nodeName);// A name #text
console.log(tagA.nodeType,attr.nodeType,text.nodeType);// 1 2 3
console.log(tagA.nodeValue,attr.nodeValue,text.nodeValue);// null 张三 你好
(5)相关的方法
- cloneNode 方法 (克隆所有节点)
- append 添加节点
- appendChild 添加节点
- replaceChild 替换节点
- replaceChildren 替换所有的子节点
- insertBefore 插入节点
- removeChild 移除子节点
(6)属性节点操作的相关方法
- setAttributeNode 设置属性节点
- getAttributeNode 获取属性节点
- removeAttributeNode 删除属性节点
this 调用者是谁就指向谁
//setAttributeNode getAttributeNode removeAttributeNode
console.log(ele.getAttributeNode('abc')); //返回属性节点对象
var attr2 = document.createAttribute('abc') //属性节点
attr2.value = '123456'
ele.setAttributeNode(attr2) //同样的属性名会被覆盖
var attr3 = document.createAttribute('abc') //属性节点
attr3.value = '123456' //由于attr3和attr2不是一个对象 所有他的地址不一样 所以比对不成功所
以不能被删除
// var attr3 = attr2 //attr3的地址和attr2的是一样这个时候就可以删除了
ele.removeAttributeNode(attr3) //删除对于的属性节点
(7)this 调用者是谁就指向谁
//生成对应的元素 加入某个地方
//个数 标签名 父元素
var arr = [0,1,2,3,4,5,6,7,8,9,'+',"-","*",'/']
function initElement(tagName,parent,valueArr){
for(var i=0;i<valueArr.length;i++){
var element = document.createElement(tagName)
element.innerText = valueArr[i]
parent.appendChild(element)
}
}
var box = document.querySelector('div')
initElement('button',box,arr)
//dom操作会影响页面的渲染速度(重复多次的渲染)(重绘和回流)
//获取所有的按钮
var btns = document.querySelectorAll('button')
//遍历这个按钮组
for(var i=0;i<btns.length;i++){
btns[i].onclick = function(){
// console.log(i); 14
// console.log(btns[i].innerText);
console.log(this.innerText); //指向对应的点击的按钮
}
}
//点击事件是异步 先走同步 再走异步
四、练习
1, 有一个装有颜色的数组 ["red", "blue", "yellow", "green", "black", "orange"]; 点击button 启动定时器,每一秒给它换一次色, 按顺序循环换色
<style>
div{
width: 500px;
height: 500px;
}
</style>
<body>
<div id="box"></div>
<button onclick="action()">更换颜色</button>
<script>
var colors =["red", "blue", "yellow", "green", "black", "orange"]
var box = document.getElementById('box')
var i=0
var timer
function action(){
clearInterval(timer)
timer = setInterval(function(){
box.style.backgroundColor = colors[i]
if(i==colors.length-1){
i=0
}
i++
},1000)
}
</script>
</body>
2, 实现一个个人信息页面 姓名 年龄 学历 专业, 可以获取到输入的信息, 点击保存按钮以后, 输出信息(信息显示形式: 姓名:张三,年龄:33,学历:本科,专业:计算机) 要求: 分别使用通过id, tagName, name三种获取节点的方式实现
<style>
#box{
width: 350px;
height: 100px;
}
</style>
<body>
<div id="box">
<input type="text" placeholder="姓名" id="uname">
<input type="text" placeholder="年龄" id="age">
<input type="text" placeholder="学历" id="degree">
<input type="text" placeholder="专业">
<button>保存</button>
</div>
<script>
var uname = document.getElementById('uname')
var age = document.getElementById('age')
var degree = document.getElementById('degree')
var magor = document.getElementsByTagName('input')[3]
document.getElementsByTagName('button')[0].onclick = function(){
console.log(`姓名:${uname.value} 年龄:${age.value} 学历:${degree.value} 专业:${magor.value}`);
}
</script>
</body>
3, 写一个定时器, 每隔0.1秒修改一次div内文字颜色和文字大小. 最开始这个文字是默认大小, 开启定时器后文字大小开始增大, 当增大了6次以后, 文字大小开始缩小, 缩小6次, 文字再开始增大…效果如下图:
<style>
div{
width: 600px;
height: 500px;
background-color: purple;
margin: 0 auto;
color: green;
}
</style>
<body>
<div>
看我72变
</div>
<script>
// 2, 写一个定时器, 每隔0.1秒修改一次div内文字颜色和文字大小. 最开始这个文字是默认大小, 开启定时器后文字大小开始增大, 当增大了6次以后, 文字大小开始缩小, 缩小6次, 文字再开始增大…效果如下图:
function randomColor(){
var r = parseInt(Math.random()*255)
var g = parseInt(Math.random()*255)
var b = parseInt(Math.random()*255)
return `rgb(${r},${g},${b})`
}
// 获取div
// 改大小
var defaultSize = 16
var i=0
var div = document.querySelector('div')
// 定时器
setInterval(function(){
div.style.color = randomColor()
// 每一次去加4
i++
if(Math.ceil(i/6)%2==0){//--
defaultSize-=4
}else{//++
defaultSize+=4
}
div.style.fontSize = defaultSize+'px'
},100)
</script>
</body>
4, 网页换肤, 点击皮肤1, 切换到第一张图的效果, 点击皮肤2切换到第二张图的效果
<style>
*{
margin: 0;
padding: 0;
}
body{
background-repeat: no-repeat;
background-size: 100%;
}
#box{
width: 600px;
height: 400px;
margin:0 auto;
border: 1px solid red;
}
</style>
<body>
<div id="box">
<button onclick="fn()">皮肤1</button>
<button onclick="fn1()">皮肤2</button>
</div>
<script>
// 3, 网页换肤, 点击皮肤1, 切换到第一张图的效果, 点击皮肤2切换到第二张图的效果
var box= document.getElementById('box')
function fn(){
box.style.backgroundColor = 'pink'
var father = box.parentElement
father.style.backgroundImage="url(./1.webp)"
}
function fn1(){
box.style.backgroundColor = 'gold'
var father = box.parentElement
father.style.backgroundImage="url(./2.webp)"
}
</script>
</body>
5、隔行变色
<style>
#box{
width: 1000px;
height: 300px;
}
</style>
<body>
<ul id="box">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
<script>
// 4, 隔行变色
var list = document.getElementsByTagName('li')
for(var i=0;i<list.length;i++){
if(i%2==0){
list[i].style.backgroundColor='pink'
}else{
list[i].style.backgroundColor='skyblue'
}
}
</script>
</body>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律