当前位置: 首页 > article >正文

〖大前端 - 基础入门三大核心之JS篇㊽〗- BOM特效开发

  • 说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费如需要项目实战或者是体系化资源,文末名片加V!
  • 作者:哈哥撩编程,十余年工作经验, 从事过全栈研发、产品经理等工作,目前在公司担任研发部门CTO。
  • 荣誉:2022年度博客之星Top4、2023年度超级个体得主、谷歌与亚马逊开发者大会特约speaker全栈领域优质创作者

  • 🏆 白宝书系列
    • 🏅 启示录 - 攻城狮的自我修养
    • 🏅 Python全栈白宝书
    • 🏅 ChatGPT实践指南白宝书
    • 🏅 产品思维训练白宝书
    • 🏅 全域运营实战白宝书
    • 🏅 大前端全栈架构白宝书


文章目录

  • ⭐ BOM特效开发
    • 🌟 返回顶部按钮制作
    • 🌟 楼层导航效果

⭐ BOM特效开发

BOM是指浏览器对象模型(Browser Object Model)。它是JavaScript与浏览器之间的接口,提供了操作浏览器窗口、文档、历史记录等功能的方法和属性。BOM包含一系列对象,如window、document、history、location等,这些对象允许开发者通过JavaScript去操作浏览器的各个部分。例如,通过BOM可以打开和关闭浏览器窗口、获取当前页面的URL、修改浏览器历史记录等。通过BOM,JavaScript可以与用户的浏览器进行交互,实现更丰富的用户体验和功能。

🌟 返回顶部按钮制作

返回顶部的原理:改变document.documentElement.scrollTop属性,通过定时器逐步改变此值,就会以动画形式返回顶部

示例代码:

<!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: 2000px;
            background-image: linear-gradient(to bottom, white, #ccc, #333);
        }
        #backtotop {
            width: 70px;
            height: 20px;
            background-color: orange;
            position: fixed;
            right: 100px;
            bottom: 100px;
            /*鼠标放上去变小手状*/
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div id="backtotop">返回顶部</div>
    <script>
        var backtotop = document.getElementById('backtotop');

        //定义定时器
        var timer;

        backtotop.onclick = function () {
            //设表先关
            clearInterval(timer);
            //设置定时器
            timer = setInterval(() => {
                document.documentElement.scrollTop -= 100;
                if (document.documentElement.scrollTop == 0) {
                    clearInterval(timer);
                };
            }, 20);
        }
    </script>
</body>
</html>

20230428_1345102023428134611

🌟 楼层导航效果

先开了解一个属性——offsetTop属性

DOM元素都有offsetTop属性,表示此元素到定位祖先元素的垂直距离

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

比如下方例子中,ul具有定位属性,则其中p节点的offset属性值是它到ul的垂直距离

<!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>
        * {
            margin: 0;
            padding: 0;
        }
        .box {
            width: 300px;
            height: 300px;
            border: 2px solid orange;
            margin: 50px auto;
        }
        .box ul {
            list-style: none;
            padding-top: 20px;
            position: relative;
        }
        .box ul li {
            margin-top: 10px;
        }
        .box ul li p{
            width: 30px;
            height: 30px;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div class="box">
        <ul>
            <li>
                <p id="para"></p>
            </li>
        </ul>
    </div>
    <script>
        var para = document.getElementById('para');
        console.log(para.offsetTop);
    </script>
</body>
</html>

image-20230428172751257

我们想要获得一个元素到页面最顶端的垂直距离(净top值),就要保证所有的祖先元素不要有定位。

下面我们来做一个简单的楼层导航效果,点击右侧的导航条,可以跳转到页面对应的位置:

20230506_100423202356106411

代码如下:

<!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>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            height: 5000px;
        }

        .content-part {
            width: 1000px;
            margin: 30px auto;
            background-color: #ccc;
            font-size: 50px;
        }

        .floornav {
            /* 固定定位 */
            position: fixed;
            top: 50%;
            margin-top: -100px;
            right: 40px;
            width: 120px;
            height: 200px;
            background-color: orange;
        }

        .floornav ul {
            list-style: none;
        }

        .floornav ul li {
            width: 120px;
            height: 40px;
            font-size: 26px;
            line-height: 40px;
            text-align: center;
            /* 小手指针 */
            cursor: pointer;
        }

        .floornav ul li.current {
            background-color: purple;
            color: white;
        }
    </style>
</head>

<body>
    <!--制作楼层导航-->
    <nav class="floornav">
        <ul id="list">
            <li data-n="热点" class="current">热点</li>
            <li data-n="体育">体育</li>
            <li data-n="财经">财经</li>
            <li data-n="科技">科技</li>
            <li data-n="娱乐">娱乐</li>
        </ul>
    </nav>
    <section class="content-part" style="height:600px;" data-n="热点">
        热点新闻
    </section>
    <section class="content-part" style="height:545px;" data-n="体育">
        体育栏目
    </section>
    <section class="content-part" style="height:467px;" data-n="财经">
        财经栏目
    </section>
    <section class="content-part" style="height:393px;" data-n="科技">
        科技栏目
    </section>
    <section class="content-part" style="height:523px;" data-n="娱乐">
        娱乐栏目
    </section>

    <script>
        //获取元素节点
        var list = document.getElementById('list');
        var lis = document.querySelectorAll('#list li');
        var contentParts = document.querySelectorAll('.content-part');

        //在页面加载好之后,将所有的content-part盒子的offsetTop值推入数组
        var offsetTopArr = [];
        for (var i = 0; i < contentParts.length; i++) {
            offsetTopArr.push(contentParts[i].offsetTop);
        }
        offsetTopArr.push(Infinity);  //为了方便在窗口卷动时判断楼层,在后面推入一个无穷大

        //点击楼层导航页面自动滚动至对应的楼层
        list.onclick = function (e) {
            if (e.target.tagName.toLowerCase() == 'li') {
                //getAttribute表示得到标签身上的某个属性值
                var n = e.target.getAttribute('data-n');

                //可以用属性选择器(方括号选择器)来寻找带有相同data-n的content-part
                var contentPart = document.querySelector('.content-part[data-n=' + n + ']');

                //让页面卷动成为这个盒子的offsetTop值
                document.documentElement.scrollTop = contentPart.offsetTop;

                //遍历offsetTopArr数组,看看当前的scrollTop的值在哪两个offsetTop之间,说明在哪两个楼层之间
                for (var i = 0; i < offsetTopArr.length; i++) {
                    if (offsetTopArr[i] == contentPart.offsetTop) {
                        //改变楼层导航的底色为紫色
                        changeLisCur(i);
                        break;
                    }
                }
            }
        };

        // 窗口的卷动
        window.onscroll = function () {
            var scrollTop = Math.ceil(document.documentElement.scrollTop);   // 向上取整,规避滚动时出现的小数误差
            //遍历offsetTopArr数组,看看当前的scrollTop的值在哪两个offsetTop之间,说明在哪两个楼层之间
            for (var i = 0; i < offsetTopArr.length; i++) {
                if (scrollTop >= offsetTopArr[i] && scrollTop < offsetTopArr[i + 1]) {
                    //改变楼层导航的底色为紫色
                    changeLisCur(i);
                    break;
                }
            }
        }

        // 当前所在楼层
        var nowfloor = -1;
        //改变li的cur
        function changeLisCur(i) {
            if (nowfloor != i) {
                //让全局变量改变为这个楼层
                nowfloor = i;
                //设置下标为i的项有current
                for (var j = 0; j < lis.length; j++) {
                    if (j == i) {
                        lis[j].className = 'current';
                    } else {
                        lis[j].className = '';
                    }
                }
            }
        }

    </script>
</body>
</html>

http://www.kler.cn/a/161835.html

相关文章:

  • Windows C++ TCP/IP 两台电脑上互相传输字符串数据
  • JavaWeb后端开发知识储备1
  • 01:(手撸HAL+CubeMX)时钟篇
  • 容器技术在DevOps中的应用
  • 【插件】多断言 插件pytest-assume
  • js 获取某日期到现在的时长 js 数字补齐2位
  • 自动驾驶:传感器初始标定
  • 对Spring源码的学习:二
  • 低代码与MES:智能制造的新篇章
  • 异步线程实现简单实现方式@Async
  • 【AIGC】prompt工程从入门到精通--图片生成专题
  • JS的变量提升ES6基础
  • 大数据项目——基于Django/协同过滤算法的房源可视化分析推荐系统的设计与实现
  • UE Websocket笔记
  • JAVA IO:NIO
  • IntelliJ IDEA 2023.3 最新变化
  • 力扣每日一题day30[226. 翻转二叉树]
  • Web server failed to start. Port 8888 was already in use.
  • 点评项目——商户查询缓存
  • 前端实现token无感刷新的原因和步骤
  • Linux Docker 安装Nginx
  • 【Linux】Java 程序员必会的 Linux 最常用的命令
  • 小纸条..
  • ubuntu源配置文件/etc/apt/sources.list不存在
  • C语言实现水仙花
  • PostgreSQL 技术内幕(十二) CloudberryDB 并行化查询之路