BOM
BOM
BOM(Browser Object Model,浏览器对象模型)是JavaScript中用于与浏览器窗口及其元素进行交互的API。
BOM提供了一系列对象,这些对象代表了浏览器的不同部分,使得开发者能够控制浏览器的各种功能,如窗口大小调整、导航、定时器等。
BOM的核心是 window 对象,表示浏览器的实例。window对象在浏览器中有两重身份,一个是 ECMAScript 中的 Global 对象,另一个就是浏览器窗口的 JavaScript 接口。
实例说明一切:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html {
height: 3000px;
}
</style>
</head>
<body>
<script>
// var age = 20;
// var sayAge = ()=> alert(this.age);
// alert(window.age);
// sayAge();
/* 如果在这里使用 let 或 const 替代 var,则不会把变量添加给全局对象*/
// let age = 29;
// const sayAge = ()=> alert(this.age);
// sayAge();
// window.sayAge();
// console.log(window);
// console.dir(window);
/*
窗口大小
innerWidth 和 innerHeight 返回浏览器窗口中页面视口的大小(不包含浏览器边框和工具栏, 包括滚动条)。
outerWidth 和 outerHeight 返回浏览器窗口自身的大小
document.documentElement.clientWidth 和 document.documentElement.clientHeight 返回页面视口的宽度和高度
*/
// console.log(window.innerWidth);
// console.log(window.innerHeight);
// console.log(window.outerWidth);
// console.log(window.outerHeight);
// console.log(document.documentElement.clientWidth);
// console.log(document.documentElement.clientHeight);
/*
视口位置
浏览器窗口尺寸通常无法满足完整显示整个页面,为此用户可以通过滚动在有限的视口中查看文档。
度量文档相对于视口滚动距离的属性有两对,返回相等的值:window.pageXoffset/window.scrollX 和 window.pageYoffset/window.scrollY。
可以使用 scroll()、scrollTo()和 scrollBy()方法滚动页面。这3个方法都接收表示相对视口距离的X和Y坐标。
- scroolBy() 相对于当前视口滚动
- scrollTo() 滚动到指定位置
- scroll() 与上一个一样
*/
// 相对于当前视口向下滚动 100 像素
// window.scrollTo(0, 1000);
/*
导航与打开新窗口
window.open() 这个方法有四个参数
window.close() 关闭新打开的窗口 这个方法只能用于 window.open()创建的弹出窗口
*/
/*
定时器
JavaScript 在浏览器中是单线程执行的,但允许使用定时器指定在某个时间之后或每隔一段时间就执行相应的代码。setTimeout()用于指定在若干毫秒后执行某些代码,而 setInterval()用于指定每隔一段时间执行某些代码。
调用 setTimeout()时,会返回一个表示该超时排期的数值ID。这个超时 ID 是被排期执行代码的唯一标识符,可用于取消该任务。要取消等待中的排期任务,可以调用 clearTimeout()方法并传入超时ID。
*/
// setTimeout(function(){alert('hello world!');}, 1000);
// setTimeout(() => {
// alert('hello world again');
// }, 2000);
// let id = setTimeout(() => {
// alert('hello world!');
// }, 3000);
// clearTimeout(id);
/*
系统对话框
alert()、confirm()和 prompt()
*/
// 确认框
// confirm('Are you OK?');
// // 提示框
// let result = prompt("What is your name? ", "");
// if (result !== null) {
// alert("Welcome, " + result);
// }
/*
location对象
location 是最有用的BOM对象之一,提供了当前窗口中加载文档的信息,以及通常的导航功能。
这个对象独特的地方在于,它既是 window 的属性,也是 document 的属性。也就是说, window.location 和 document.location 指向同一个对象。
location 对象不仅保存着当前加载文档的信息,也保存着把 URL 解析为离散片段后能够通过属性访问的信息。
location.hash "#contents" URL 散列值(井号后跟零或多个字符),如果没有则 为空字符串
location.host "www.wrox.com:80" 服务器名及端口号
location.hostname "www.wrox.com" 服务器名
location.href "http://www.wrox.com:80/WileyCDA/?q=javascript#contents" 当前加载页面的完整 URL。location的toString()方法返回这个值
location.pathname "/WileyCDA/" URL 中的路径和(或)文件名
location.port "80" 请求的端口。如果URL中没有端口,则返回空字符串
location.protocol "http:" 页面使用的协议。通常是"http:"或"https:"
location.search "?q=javascript" URL的查询字符串。这个字符串以问号开头
location.username "foouser" 域名前指定的用户名
location.password "barpassword" 域名前指定的密码
location.origin "http://www.wrox.com" URL的源地址。只读
*/
console.log(location.host);
/*
navigator对象
Navigator 对象包含有关浏览器的信息。
Navigator 对象是窗口对象的属性。
appCodeName 返回浏览器代码名称。
appName 返回浏览器名称。
appVersion 返回浏览器版本。
cookieEnabled 如果启用了浏览器 cookie,则返回 true。
geolocation 返回用户位置的 geolocation 对象。
language 返回浏览器语言。
onLine 如果浏览器在线,则返回 true。
platform 返回浏览器平台。
product 返回浏览器引擎名称。
userAgent 返回浏览器用户代理标头。
*/
console.log(navigator.appVersion);
/*
screen对象
屏幕对象包含有关访问者屏幕的信息。
availHeight 返回屏幕高度(不包括 Windows 任务栏)。
availWidth 返回屏幕宽度(不包括 Windows 任务栏)。
colorDepth 返回用于显示图像的调色板的位深度。
height 返回屏幕的总高度。
pixelDepth 返回屏幕的颜色分辨率(每像素位数)。
width 返回屏幕的总宽度。
*/
console.log(screen.width);
/*
history对象
history对象包含用户(在浏览器窗口中)访问过的 URL。
back() 加载历史列表中的上一个 URL(页面)。
forward() 加载历史列表中的下一个 URL(页面)。
go() 从历史列表中加载特定的 URL(页面)。
length 返回历史列表中的 URL(页面)数量。
*/
history.go(-1); //后退1页
history.go(1); //前进1页
</script>
</body>
</html>
DOM
什么是DOM
文档对象模型(DOM,Document Object Model)是 HTML 和 XML 文档的编程接口。
它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,
样式和内容。
DOM是一个接口规范,可以用各种语言实现。
结点
网页中的所有内容都是节点(标签、属性、文本、注释等),DOM 中使用 node 表示。
结点类型有七种
Document:整个文档树的根节点
DocumentType:doctype标签
Element:网页的各种HTML标签
Attribute:网页元素的属性(比如class="right")
Text:标签之间或标签包含的文本
Comment:注释
DocumentFragment:文档的片段
节点关系:
父节点关系(parentNode):直接的上级节点
子节点关系(childNode):直接的下级节点
同级节点关系(sibling):拥有共同父节点的节点
依然还是:实例决定一切:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: yellowgreen;
}
.box {
width: 300px;
height: 300px;
background-color: palevioletred;
}
.font {
font-size: 22px;
color: red;
}
</style>
</head>
<body>
nodeType
每个节点都有 nodeType 属性,表示该节点的类型。节点类型由定义在 Node 类型上的 12 个数值 常量表示:
Node.ELEMENT_NODE(1)
Node.ATTRIBUTE_NODE(2)
Node.TEXT_NODE(3)
Node.CDATA_SECTION_NODE(4)
Node.ENTITY_REFERENCE_NODE(5)
Node.ENTITY_NODE(6)
Node.PROCESSING_INSTRUCTION_NODE(7)
Node.COMMENT_NODE(8)
Node.DOCUMENT_NODE(9)
Node.DOCUMENT_TYPE_NODE(10)
Node.DOCUMENT_FRAGMENT_NODE(11)
Node.NOTATION_NODE(12)
-->
<script>
const node = document.querySelector('body');
console.log(node.nodeType);
</script>
<!--
获取DOM元素
1 根据css选择器来获取DOM元素
document.querySelector('css选择器')
返回的是CSS选择器匹配的第一个元素,一个HTMLElement对象
document.querySelectorAll('css选择器')
返回CSS选择器匹配的NodeList对象集合
如果选择器无效,则 querySelector() 和 querySelectorAll() 都会抛出 SYNTAX_ERR 异常。
2 其它获取DOM元素的方法
document.getElementById();
下面的方法返回的是一个数组
document.getElementsByClassName();
document.getElementsByName();
document.getElementsByTagName();
-->
<div>div1</div>
<div class="box">div2</div>
<!-- <ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul> -->
<script>
let div = document.querySelector("div.box");
console.log(div);
const li = document.querySelector('li');
console.log(li);
const lis = document.querySelectorAll('li')
console.log(lis);
for (const li of lis) {
console.log(li);
}
</script>
<!--
操作元素内容
1、对象.innerText 属性
将文本内容添加/更新到任意标签位置
显示纯文本,不解析标签
2、对象.innerHTML 属性
将文本内容添加/更新到任意位置
会解析标签,多标签建议使用模板字符串
-->
<script>
const divBox = document.querySelector("div.box");
// divBox.innerText = "box Div";
divBox.innerHTML = "<b>我加粗了</b>"
</script>
<!-- <img src="https://img0.baidu.com/it/u=1604010673,2427861166&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889" alt=""> -->
<script>
/*
操作元素属性
常见的属性
对象.属性 = 值
*/
// const img = document.querySelector("img");
// img.src = "https://img2.baidu.com/it/u=1361506290,4036378790&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500";
/*
操作元素样式属性
1 通过style属性操作class
2 操作类名(className)修改样式
3 通过classList修改样式
*/
divBox.style = "background-color: yellow; width: 300px";
divBox.style.backgroundColor = "blue";
divBox.style.height = "250px";
// 通过className会把原来的class名字替换掉
divBox.className = "box";
divBox.classList.add("font");
divBox.classList.remove("box");
// toggle 有就删除 没有就添加
divBox.classList.toggle('font');
</script>
<input type="text" value="电脑">
<button>提交</button>
<script>
// 表单操作
const uname = document.querySelector("input");
console.log(uname.value);
uname.value = "computer";
uname.type = "password";
uname.type = "checkbox";
uname.checked = !uname.checked;
const button = document.querySelector("button");
button.disabled = true;
</script>
<div data-id="1" data-user-name="zhangsan" class="custom">1</div>
<script>
/*
自定义属性
在html5中推出来专门的‘data-’自定义属性。
在标签上一律以data-开头
在DOM对象上一律以dataset对象方式获取
*/
const custom = document.querySelector(".custom");
console.log(custom.dataset.userName);
</script>
</body>
</html>
事件
事件监听
什么是事件?
事件是在编程系统内发生的动作或者发生的事情。比如用户在网页上单机一个按钮。
什么是事件监听?
就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为绑定事件或者注册事件。比如鼠标悬浮显示下拉菜单等
语法
元素对象.addEventListener('事件类型', 要执行的函数)
事件监听三要素
事件源:哪个DOM元素被事件触发了,要获取DOM元素
事件类型:用什么方式触发,比如鼠标单击click,鼠标经过mouseover等
事件调用的函数:要做什么
事件处理分为:
HTML事件处理
DOM0级事件处理
DOM2级事件处理
接下来:实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- DOM2级事件处理 -->
<button>点击</button>
<script>
const button = document.querySelector("button");
//click 鼠标点击事件 需要记住
button.addEventListener("click", ()=>{
alert("手下留情!");
});
button.addEventListener("click", ()=>{
alert("别打了!");
})
</script>
<!-- HTML事件处理 -->
<div onclick="clickMe()">我是按钮</div>
<script>
function clickMe() {
alert("Hello World")
}
</script>
<!-- DOM0级事件处理 -->
<button class="button">点击</button>
<script>
const btn = document.querySelector(".button");
btn.onclick = function() {
alert("DOM0级事件");
}
btn.onclick = function() {
alert('我覆盖了之前的事件');
}
</script>
<!--
区别:
HTML事件:缺点 HTML与Js不分离
DOM0事件:优点 HTML与Js分离 缺点:事件会被覆盖
DOM2事件:优点事件不会被覆盖 推荐使用
-->
</body>
</html>
事件类型
事件类型
鼠标事件
- click 鼠标点击事件
- dblclick 双击鼠标事件
- mousedown 鼠标按下时
- mouseup 释放按下的鼠标时
- mousemove 当鼠标在节点内部移动时触发。当鼠标持续移动时,该事件会连续触发
- mouseenter 鼠标进入一个节点时触发,进入子节点不会触发
- mouseleave 鼠标离开一个节点时触发,离开父节点不会触发
- mouseover 鼠标进入一个节点时触发,进入子节点会再一次触发
- mouseout 鼠标离开一个节点是触发,离开父节点也会触发
- wheel 鼠标滚轮滚动时触发
焦点事件
- focus 获得焦点
- blur 失去焦点
键盘事件
- keydown 键盘按下触发
- keyup 键盘抬起触发
文本事件
- input 文本输入框内容改变时触发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: goldenrod;
}
.son {
width: 100px;
height: 100px;
margin-left: 50px;
margin-top: 50px;
background-color: cyan;
}
</style>
</head>
<body>
<div>
<div class="son"></div>
</div>
<input type="text">
<script>
const div = document.querySelector("div");
div.addEventListener('mouseover', ()=>{
console.log('你已进入危险区域,请快速离开!!');
});
div.addEventListener('mouseout',()=>{console.log("送你离开!");})
const input = document.querySelector("input");
input.addEventListener("focus", function(){
console.log("你碰到我了");
});
input.addEventListener("blur", function(){
console.log("丢失焦点");
});
input.addEventListener("input", function() {
console.log(input.value.length);
})
</script>
</body>
</html>
事件对象
什么是事件对象
在触发 DOM 上的某个事件时,会产生一个事件对象(Event Object),这个对象中包含着所有与事件有关的属性和方法。
该对象会作为第一个参数传递给监听函数。
event事件常用属性和方法
- type 获取当前事件类型
- target:获取事件目标,事件发出者(触发事件的元素)
- currentTarget 事件监听者(被绑定事件的元素)
- stopPropagation():阻止事件冒泡
- preventDefault():阻止默认行为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>点击</button>
<input type="text">
<a href="https://www.baidu.com">百度</a>
<script>
// const button = document.querySelector("button");
// button.addEventListener("click", (event)=> {
// console.log(event);
// });
// const input = document.querySelector('input');
// input.addEventListener("keyup", function(e) {
// console.log(e);
// console.log(e.key);
// });
const a = document.querySelector('a');
a.addEventListener('click', function(e) {
e.preventDefault();
});
</script>
</body>
</html>
事件流
事件流
事件流又称为事件传播,描述的是从页面中接收事件的顺序。DOM2 级事件规定事件流包括三个阶段: 事件捕获(capturing phase)、目标事件(target phase)、事件冒泡(bubbling phase)。
发生的顺序是:事件捕获阶段 -> 目标事件阶段 -> 事件冒泡阶段
事件捕获的顺序
事件按 window -> document -> html -> body -> ... -> 目标元素 的方向向下层元素传递。
事件冒泡的顺序
点击的元素 -> body -> html -> document -> window
事件捕获的方法
DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
addEventListener的第三个参数true表示是捕获阶段触发,若是flase代表冒泡阶段触发,默认是flase。
L0级事件监听,只有冒泡阶段,没有捕获阶段。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.father {
width: 500px;
height: 500px;
background-color: blueviolet;
}
.son {
width: 200px;
height: 200px;
background-color: lawngreen;
}
.dad {
width: 200px;
height: 400px;
background-color: magenta;
}
.baby {
width: 100px;
height: 200px;
background-color: mediumspringgreen;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<br>
<button>点击</button>
<script>
const father = document.querySelector('.father');
const son = document.querySelector(".son");
// document.addEventListener('click', function(){
// alert('我是祖宗');
// }, false);
father.addEventListener('click', function(){
alert('我是父亲');
}, false);
son.addEventListener('click', function(){
alert('我是儿子');
}, false);
// 阻止事件冒泡
// stopPropagation()
son.addEventListener('click', function(e){
e.stopPropagation();
alert('我是儿子');
});
// // 解除绑定事件
// // L0 事件解除
const btn = document.querySelector('button');
// btn.onclick = () => {
// alert('点击了button');
// };
// btn.onclick = null;
// // L2 事件解除
function btnClick () {
alert('listener 事件 点击');
}
btn.addEventListener('click', btnClick);
btn.removeEventListener('click', btnClick);
</script>
<!--
鼠标经过事件:
mouseover和mouseout 会有冒泡效果
mouseenter和mouseleave没有冒泡效果(推荐)
-->
<div class="dad">
<div class="baby"></div>
</div>
<script>
const dad = document.querySelector('.dad');
dad.addEventListener('mouseenter', function(){
console.log('鼠标经过dad');
});
dad.addEventListener('mouseleave', function(){
console.log('鼠标离开dad');
});
</script>
</body>
</html>
页面其他事件
1 – 页面加载事件
加载外部资源(图片、外联CSS和Js等)加载完毕时触发的事件。
事件名:load
注意:不光可以监听整个页面加载完毕,可以等待某个元素加载完毕。
当初始的HTML文档被完全加载和解析完成之后,DOMContentLoaded事件被触发,无需等待其它外链资源完全加载。
事件名:DOMContentLoaded
2 -- 元素滚动事件
滚动条滚动的时候持续触发的事件
事件名:scroll
监听整个页面的滚动:window
3 -- 页面尺寸事件
窗口尺寸改变的时候触发事件
事件名:resize
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
height: 3000px;
}
div {
width: 200px;
height: 200px;
background-color: aqua;
/* position: relative; */
}
p {
margin-left: 150px;
width: 50px;
height: 50px;
background-color: yellow;
}
</style>
<script>
window.addEventListener('load', function() {
// alert('我加载完毕!')
const button = document.querySelector('button');
button.addEventListener('click', function() {
alert('点击事件');
})
});
document.addEventListener('DOMContentLoaded', ()=> {
});
</script>
</head>
<body>
<button>点击</button>
<script>
window.addEventListener('scroll', function() {
console.log('我滚动了');
console.log(document.documentElement.scrollTop);
// scrollTo 参数是2个值
// document.documentElement.scrollTo(x,y);
});
// 其它元素获取滚动距离
// const div = document.querySelector('div');
// div.addEventListener('scroll', function() {
// div.scrollTop;
// });
// 页面尺寸事件
window.addEventListener('resize', function() {
console.log(1);
});
</script>
<div>
<p></p>
</div>
<script>
// 获取元素的宽高
// 获取元素的可见部分宽高(不包含边框,margin,滚动条等)
// clientWidth和clientHeight
const div = document.querySelector('div');
console.log(div.clientHeight);
console.log(div.clientWidth);
// 获取元素自身宽高,包含元素自身的宽高、padding、border
// offsetWidth和offsetHeight
// 注意:获取的是可视宽高,如果盒子是隐藏的,获取的结果是0
console.log(div.offsetWidth);
console.log(div.offsetHeight);
// 获取元素距离自己"定位"父级元素的左、上距离
// offsetLeft和offsetTop 这两个是只读属性
console.log('div的上边距离' + div.offsetTop);
const p = document.querySelector('p');
console.log(p.offsetLeft);
</script>
</body>
</html>
节点操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<li>1</li>
<li class="name">2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
// 查找节点
const ul = document.querySelector("ul");
// 查找一个元素的父节点
// console.log(ul.parentNode);
// 查找资源子元素
// console.log(ul.childNodes);
console.log(ul.children);
const li = document.querySelector('li.name');
// 获取下一个兄弟元素
li.nextElementSibling.style.color = 'red';
// 获取上一个兄弟元素
li.previousElementSibling.style.color = 'blue';
// 新增节点
// 1 创建节点
const newLi = document.createElement('li');
newLi.innerHTML = '<strong>6</strong>';
// 2 追加节点 插入到父元素的末尾
// ul.appendChild(newLi);
// 追加一个节点到元素的某个子元素之前
ul.insertBefore(newLi, li);
// 复制节点
/*
cloneNode(布尔值)
-- 参数为true,代表克隆时会包含后代节点一起克隆
-- 参数为false,代表克隆时不包含后代节点。(默认值)
*/
// console.log();
const newUl = ul.cloneNode(true);
ul.appendChild(newUl);
// // 删除节点
// // 只能通过父元素删除子节点
ul.removeChild(newLi);
</script>
</body>
</html>
到这里简单的JavaScript操作就讲解完毕