JavaScript学习笔记 07、BOM元素

举报
长路 发表于 2022/11/28 20:48:37 2022/11/28
【摘要】 文章目录前言一、认识BOM二、介绍window对象2.1、全局变量是window的属性(以及一些内置函数)2.2、窗口尺寸相关属性2.3、窗口改变大小事件(onresize)2.4、卷动高度与卷动事件(onscroll)三、document相关事件3.1、切换屏幕(onvisibilitychange)四、navigator对象五、history对象六、location(含案例)七、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>

image-20210613212723493


示例

测试一个小案例:看看在一个页面中的多个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>

image-20210613212117207



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>

image-20210613214312782



2.3、窗口改变大小事件(onresize)

在窗口大小改变之后,就会触发resize事件。(window.onresizewindow.addEventListener('resize'))

示例

GIF

<script>
    //绑定onresize事件
    window.onresize = function () {
        console.log(window.document.documentElement.clientWidth);
    }
</script>


2.4、卷动高度与卷动事件(onscroll)

卷动高度

通常若是页面有一定的高度时,可通过使用window.scrollYdocument.documentElement.scrollTop来获取到。

image-20210613220420046

注意:其中window.scrollY是只读的,而document.documentElement.scrollTop是可读可写的表示可以修改!

应用场景:可通过使用该属性来检测浏览器此时处于的位置,或者说来进行定位浏览器的卷动位置,实现自定义!


卷动事件

语法window.scroll

示例

<style>
    body {
        height: 1000px;
    }
</style>

<body>
    <script>
        window.onscroll = function () {
            console.log(window.scrollY);
        };
    </script>
</body>

GIF



三、document相关事件

3.1、切换屏幕(onvisibilitychange)

<script>
    //切换屏幕事件
    document.onvisibilitychange = function () {
        alert("不允许切换屏幕,警告一次!");
        document.onvisibilitychange = null;
    };
</script>

image-20210613215645869



四、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>

image-20210613224001088


五、history对象

window.history:该对象提供了操作浏览器会话历史的接口。常用操作就是模拟浏览器回退按钮。

常用方法:介绍两个模拟浏览器回退方法

  1. history.back()
  2. 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>

GIF



六、location(含案例)

查看location对象

window.location:标识当前所在网址,包含网址相关信息。

<script>
    console.log(window.location);
</script>

image-20210613230753143


实际小案例

①跳转网址:两种方式

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>

image-20210613231426248



七、BOM制作特效

7.1、认识offsetTop属性

offsetTop:DOM元素都有该睡醒,表示其元素的顶部到==定位祖先元素==的垂直距离。

  • 定位祖先元素:在祖先节点中,离自己最近的且拥有定位属性的元素。

注意点:若是在项目想要确定某个楼层在页面中的位置就可以使用该属性来定位,但是需要确保祖先节点中没有定位元素。

image-20210614094130954

image-20210614094311524

测试源码:

<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属性来进行回到顶部。

GIF

<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:当前屏幕移动的高度。可进行修改设置。

实现效果说明

  1. 点击右边的导航栏,点击哪个专栏屏幕就会到达指定位置。
    • 效果第一部分思路:使用事件委托来给ul来添加单击事件,在对应li以及section的标签中存储了data-n="栏目信息"的键值对,用于点击时使用样式选择器来查找对应的section。接着来对屏幕当前高度进行指定值(通过对应section的距离顶部高度)就能够到达指定位置了。
  2. 鼠标向页面下面进行滚动,右边的小导航栏也会有效果表示在哪个区域。
    • 效果第二部分思路:用一个数组来保存每个专栏的距底部位置,数组末尾再添加一个无限大。绑定页面滚动事件,通过滚动事件触发时获取到当前屏幕高度,遍历数组比对来得到是哪个栏目(cur_movfloor_pos保存第n个),原本使用样式效果的第n个楼层存储到nav_bkred_pos,将原本导航栏目指定的样式去除,为当前到达的新栏目添加样式效果。

GIF

源码:

<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>
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。