JavaScript学习笔记 07、BOM元素
@[toc]
前言
本篇博客是关于javascript中BOM元素,若文章中出现相关问题,请指出!
所有博客文件目录索引:博客目录索引(持续更新)
一、认识BOM
BOM
(Browser Object Model,浏览器对象模型):是js和浏览器窗口交互的接口。
应用场景:一些与浏览器改变尺寸,滚动条相关的特效,都要借助BOM技术。
二、介绍window对象
window
对象是当前js脚本运行所处的窗口,而这个窗口中包含DOM
结构,window.document
属性就是document
对象。
标签页与window关系:在有标签页功能的浏览器中,每个标签都拥有自己的window对象,标签与标签之间的window互不干扰!
2.1、全局变量是window的属性(以及一些内置函数)
全局变量会成为window
对象的属性,这也就意味着多个应用于同一页面中的js文件是共享全局作用域的,即js文件没有作用域隔离功能!
<script>
var a = 100;
//全局变量属于window的变量
console.log(window.a == a);
//window内置函数
console.log(window.alert == alert);
console.log(window.hasOwnProperty('setInterval'));//测试是否包含属性(或对象)
//window.alert() 与之前写的 alert()实际上效果一致,这些函数默认都是window对象
window.alert("123");
</script>
示例
测试一个小案例:看看在一个页面中的多个js文件里作用域同一个window
1.js
var a = 111;
2.js
a++;
console.log(a);
准备两个js文件之后引入到一个HTML中来测试:
<body>
<script src="./1.js"></script>
<script src="./2.js"></script>
</body>
2.2、窗口尺寸相关属性
属性 | 意义 |
---|---|
innerHeight | 浏览器窗口的内容区域高度,包含水平滚动条(若是有) |
innerWidth | 浏览器窗口的内容区域宽度,包含垂直滚动条(若是有) |
outerHeight | 浏览器窗口的外部高度(含浏览器) |
outerWidth | 浏览器窗口外部宽度 |
若是想要获得不包含滚动条的窗口宽度,使用:document.documentElement.clientWidth
测试:
<style>
body {
/* 让浏览器有宽度 */
height: 1000px;
}
</style>
<body>
<script>
console.log(window.innerWidth);//浏览器内部宽度+水平滚动条
console.log(window.outerWidth);//浏览器内部宽度+水平滚动条+浏览器外部线条宽度
console.log(window.document.documentElement.clientWidth);//浏览器内部宽度
</script>
</body>
2.3、窗口改变大小事件(onresize)
在窗口大小改变之后,就会触发resize
事件。(window.onresize
或window.addEventListener('resize')
)
示例:
<script>
//绑定onresize事件
window.onresize = function () {
console.log(window.document.documentElement.clientWidth);
}
</script>
2.4、卷动高度与卷动事件(onscroll)
卷动高度
通常若是页面有一定的高度时,可通过使用window.scrollY
或document.documentElement.scrollTop
来获取到。
注意:其中window.scrollY
是只读的,而document.documentElement.scrollTop
是可读可写的表示可以修改!
应用场景:可通过使用该属性来检测浏览器此时处于的位置,或者说来进行定位浏览器的卷动位置,实现自定义!
卷动事件
语法:window.scroll
。
示例:
<style>
body {
height: 1000px;
}
</style>
<body>
<script>
window.onscroll = function () {
console.log(window.scrollY);
};
</script>
</body>
三、document相关事件
3.1、切换屏幕(onvisibilitychange)
<script>
//切换屏幕事件
document.onvisibilitychange = function () {
alert("不允许切换屏幕,警告一次!");
document.onvisibilitychange = null;
};
</script>
四、navigator对象
window.navigator
:该对象包含了用户此次活动的浏览器相关属性和标识。
属性 | 意义 |
---|---|
appName | 浏览器官方名称 |
appVersion | 浏览器版本 |
userAgent | 浏览器的用户代理(含有内核信息和封装壳信息) |
platform | 用户操作系统 |
测试:
<script>
console.log(window.navigator.appName);
console.log(window.navigator.appVersion);
console.log(window.navigator.userAgent);
console.log(window.navigator.platform);
</script>
五、history对象
window.history
:该对象提供了操作浏览器会话历史的接口。常用操作就是模拟浏览器回退按钮。
常用方法:介绍两个模拟浏览器回退方法
history.back()
。history.go(-1)
。
测试:
第一个页面:usuallyexer.html
<a href="./u2.html">跳转u2网页</a>
第二个页面:u2.html
,提供了两种方式来进行回退
<body>
<h1>我是u2网页</h1>
<!-- 方式一:按钮绑定点击事件 -->
<button>点我回退网页</button>
<!-- 方式二:通过链接中编写js脚本进行回退 -->
<a href="javascript:history.go(-1);">点我回退</a>
<script>
var m_button = document.getElementsByTagName("button")[0];
// 绑定单击事件
m_button.onclick = function () {
//window.history.back();//等同于history.go(-1);
window.history.go(-1);
}
</script>
</body>
六、location(含案例)
查看location对象
window.location
:标识当前所在网址,包含网址相关信息。
<script>
console.log(window.location);
</script>
实际小案例
①跳转网址:两种方式
window.location="https://www.baidu.com"
window.location.href="https://www.baidu.com"
②重新加载当前页面(使用函数)
window.location.reload(true);
③获取get请求查询参数:window.location.search
<body>
<button id="mybutton">点我</button>
<script>
var m_button = document.getElementById("mybutton");
m_button.onclick = function () {
console.log(window.location.search);
}
</script>
</body>
七、BOM制作特效
7.1、认识offsetTop属性
offsetTop
:DOM元素都有该睡醒,表示其元素的顶部到==定位祖先元素==的垂直距离。
定位祖先元素
:在祖先节点中,离自己最近的且拥有定位属性的元素。
注意点:若是在项目想要确定某个楼层在页面中的位置就可以使用该属性来定位,但是需要确保祖先节点中没有定位元素。
测试源码:
<style>
* {
margin: 0;
padding: 0;
}
div.box {
width: 100px;
height: 100px;
border: 1px solid #000;
padding: 40px;
}
div.box1 {
position: relative;
width: 100px;
height: 100px;
border: 1px solid #000;
}
p {
background-color: red;
}
</style>
<body>
<div class="box">
<div class="box1">
<p id="mp">123</p>
</div>
</div>
<script>
var ele = document.getElementById("mp");
console.log(ele.offsetTop)
</script>
</body>
案例1:返回顶部按钮
预期效果:点击回到顶部,浏览器页面自动向上。
思路分析:利用定时器来进行动画效果的制作,控制scrollTop
属性来进行回到顶部。
<style>
body {
font-size: 18px;
height: 3000px;
background-image: linear-gradient(145deg, red, orange, blue, gold);
}
a.scrollTop {
position: fixed;
bottom: 40px;
right: 40px;
width: 50px;
height: 50px;
border: 1px solid #000;
background-color: grey;
line-height: 25px;
text-align: center;
cursor: pointer;
}
</style>
<body>
<a class="scrollTop">回到顶部</a>
<script>
var m_box = document.getElementsByTagName("a")[0];
var myinterval;
m_box.onclick = function () {
clearInterval(myinterval);
myinterval = setInterval(function () {
document.documentElement.scrollTop -= 50;
//到达最顶部需要清除定时器
if (document.documentElement.scrollTop < 2) {
clearInterval(myinterval);
}
}, 20);
}
</script>
</body>
案例2:楼层导航小效果
相关属性:
offsetTop
:某个元素距离顶部的位置document.documentElement.scrollTop
:当前屏幕移动的高度。可进行修改设置。
实现效果说明:
- 点击右边的导航栏,点击哪个专栏屏幕就会到达指定位置。
- 效果第一部分思路:使用事件委托来给ul来添加单击事件,在对应li以及section的标签中存储了
data-n="栏目信息"
的键值对,用于点击时使用样式选择器来查找对应的section。接着来对屏幕当前高度进行指定值(通过对应section的距离顶部高度)就能够到达指定位置了。
- 效果第一部分思路:使用事件委托来给ul来添加单击事件,在对应li以及section的标签中存储了
- 鼠标向页面下面进行滚动,右边的小导航栏也会有效果表示在哪个区域。
- 效果第二部分思路:用一个数组来保存每个专栏的距底部位置,数组末尾再添加一个无限大。绑定页面滚动事件,通过滚动事件触发时获取到当前屏幕高度,遍历数组比对来得到是哪个栏目(
cur_movfloor_pos
保存第n个),原本使用样式效果的第n个楼层存储到nav_bkred_pos
,将原本导航栏目指定的样式去除,为当前到达的新栏目添加样式效果。
- 效果第二部分思路:用一个数组来保存每个专栏的距底部位置,数组末尾再添加一个无限大。绑定页面滚动事件,通过滚动事件触发时获取到当前屏幕高度,遍历数组比对来得到是哪个栏目(
源码:
<style>
* {
margin: 0;
padding: 0;
height: 5000px;
}
div.box {
width: 802px;
overflow: hidden;
border: 1px solid #000;
margin: 10px auto;
}
div.box section {
width: 800px;
height: 600px;
/* border: 1px solid #000; */
margin-bottom: 30px;
background-color: rgb(134, 98, 98);
}
nav.navigater {
position: fixed;
top: 50%;
right: 30px;
margin-top: -90px;
}
nav.navigater ul {
list-style: none;
}
nav.navigater ul li {
width: 75px;
height: 28px;
border: 1px solid #000;
text-align: center;
line-height: 28px;
background-color: yellow;
}
nav.navigater ul li.current {
background-color: red;
color: white;
}
</style>
<body>
<!-- 本案例位于:07的BOM元素中特效案例2 -->
<div class="box">
<section data-n="体育">体育财经</section>
<section data-n="动漫">动漫专区</section>
<section data-n="电影">电影专区</section>
<section data-n="小说">小说大全</section>
<section data-n="影视">影视全集</section>
<section data-n="纪录片">记录片</section>
</div>
<nav class="navigater">
<ul id="navlists">
<li data-n="体育" class="current">体育财经</li>
<li data-n="动漫">动漫专区</li>
<li data-n="电影">电影专区</li>
<li data-n="小说">小说大全</li>
<li data-n="影视">影视全集</li>
<li data-n="纪录片">记录片</li>
</ul>
</nav>
<script>
var sec_lists = document.getElementsByTagName("section");
//js实现指定位置到指定位置的屏幕动态移动(有一些像素的偏差)
// var myinterval;//定时器变量
// function scrollAtoB(current, target) {
// if (current == target)
// return;
// var pos = 1;//1表示向下移动,-1表示向上移动
// if (current > target) {
// pos = -1;
// }
// //设置定时器来进行动画移动
// myinterval = setInterval(() => {
// current += pos * 8;
// document.documentElement.scrollTop = current;//实际页面进行定位
// console.log(current);
// if (Math.abs(current - target) <= 7) {
// clearInterval(myinterval);
// }
// }, 1);
// }
//完成导航栏的点击效果
var nav_lists = document.getElementById("navlists");
//事件委托到ul元素
nav_lists.onclick = function (e) {
///确定li为源目标
if ((e.target.tagName).toLowerCase() == "li") {
var targetSubName = e.target.getAttribute("data-n");
//根据导航栏中的data-n使用样式器找到指定section
var targetSection = document.querySelector("div.box section[data-n='" + targetSubName + "']");
//直接让页面卷动到指定楼层的位置
document.documentElement.scrollTop = targetSection.offsetTop;
//优化:到达指定楼层效果(暂时没做到)
// scrollAtoB(document.documentElement.scrollTop, targetSection.offsetTop);
}
};
//数组中存储所有栏目的data-n
var floorHeightArr = [];
for (let i = 0; i < sec_lists.length; i++) {
floorHeightArr.push(sec_lists[i].offsetTop - 1);//微调一些差错
//再推入一个无穷大(因为后面要对屏幕卷动高度进行比较在哪个楼层)
if (i == sec_lists.length - 1) {
floorHeightArr.push(Infinity);
}
}
// alert(floorHeightArr);
var nav_bkred_pos = 0;//原本导航栏为红的楼层,0表示第一个
var currnetScrollY;//当前页面滚动的高度
var cur_movfloor_pos;//当前页面移动到的位置
//页面滚动事件绑定
window.onscroll = function () {
currnetScrollY = window.scrollY;//获取到当前屏幕的所处的高度
//比较当前屏幕处于的楼层位置
for (let i = 0; i < floorHeightArr.length - 1; i++) {
if (currnetScrollY >= floorHeightArr[i] && currnetScrollY < floorHeightArr[i + 1]) {
cur_movfloor_pos = i;
//测试当前楼层的高度以及其应该在指定楼层的哪个区间
//console.log("currnetScrollY:" + currnetScrollY + " " + sec_lists[i].getAttribute("data-n") + ":" + floorHeightArr[i] + " " + (i == floorHeightArr.length - 2 ? "底楼:" : sec_lists[i + 1].getAttribute("data-n")) + ":" + floorHeightArr[i + 1]);
break;
}
}
// console.log("当前楼层:" + cur_movfloor_pos);
//判断将要设置的楼层与现有的楼层是否一致,一致不需要设置,不一致要将原本楼层的样式删除,为新楼层添加
if (nav_bkred_pos != cur_movfloor_pos) {
nav_lists.children[nav_bkred_pos].className = "";//原本指定楼层去除样式
nav_bkred_pos = cur_movfloor_pos;//重新赋值楼层
nav_lists.children[cur_movfloor_pos].className = "current";//为当前楼层设置指定样式
}
}
</script>
</body>
- 点赞
- 收藏
- 关注作者
评论(0)