html响应式菜单实现

63 阅读1分钟

思路

js监听window宽度变化,根据宽度大小决定显示桌面版还是移动版。

另一种思路

简单的页面,可以通过CSS + @media媒体查询实现,然而复杂的交互逻辑还是需要js。

实现效果

注:Logo来自搜到的某网站,权侵删。

  • 桌面版

image.png

  • 移动端-点击菜单前

image.png

  • 移动端-点击菜单后

image.png

源码实现

<!DOCTYPE html>
<html>
    <head>
        <title>Jerry's Magic House</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://kit.fontawesome.com/72db785f48.js" crossorigin="anonymous"></script>
    </head>
    <body>
        <div class="app">
            <div class="top-nav-bar-wrapper">
                <div class="top-nav-bar">
                    <div class="nav-left">
                        <i class="fa-solid fa-bars nav-left-bar disable"></i>
                        <img src="img/logo.svg"/>
                    </div>
                    <div class="nav-right">
                        <div class="nav-right-big">
                            <a href="#">Features</a>
                            <a href="#">Pricing</a>
                            <a href="#">Help</a>
                            <a href="#">Log in</a>
                            <a href="#" class="register-btn">Register</a>
                        </div>
                        <div class="nav-right-small disable">
                            <a href="#" class="register-btn">Register</a>
                        </div>
                    </div>
                </div>
                <div class="top-nav-bar-mobile disable">
                    <a href="#">Features</a>
                    <a href="#">Pricing</a>
                    <a href="#">Help</a>
                    <a href="#">Log in</a>
                    <a href="#" class="register-btn">Register</a>
                </div>
            </div>
            <div class="main">
                <div class="section1">
                    <h1>Jerry's Magic House</h1>
                    <p>I have been thinking about it long long time ago!!!</p>
                    <p>Let's party!</p>
                </div>
            </div>
        </div>
        <script>
            let mobile = false
            let desktop = true
            let preMobile = false;
            let preDesktop = false;
            let mobileMenu = false;

            function detectDevice() {
                preDesktop = desktop;
                preMobile = mobile;
                if (window.innerWidth > 900) {
                    desktop = true
                    mobile = false
                } else {
                    desktop = false
                    mobile = true
                }
            }

            function display() {
                if (mobile && !preMobile) {
                    //changed
                    document.querySelector('.nav-right-big').classList.add('disable')
                    document.querySelector('.nav-right-small').classList.remove('disable')
                    document.querySelector('.nav-left-bar').classList.remove('disable')
                }
                if (desktop && !preDesktop) {
                    //changed
                    console.log('changed')
                    document.querySelector('.nav-right-big').classList.remove('disable')
                    document.querySelector('.nav-right-small').classList.add('disable')
                    document.querySelector('.nav-left-bar').classList.add('disable')
                    if (mobileMenu) {
                        toggleMobileMenu()
                    }
                }
            }

            function toggleMobileMenu() {
                mobileMenu = !mobileMenu;
                if (mobileMenu) {
                    document.querySelector('.top-nav-bar-mobile').classList.remove('disable')
                } else {
                    document.querySelector('.top-nav-bar-mobile').classList.add('disable')
                }
            }

            window.onload = () => {
                detectDevice()
                display()
                document.querySelector('.nav-left-bar').addEventListener('click', function() {
                    toggleMobileMenu()
                })
            }

            window.onresize = () => {
                detectDevice()
                display()
            }
        </script>
        <style>
            :root {
                --nav-height: 80px;
                --nav-bg-color: #1d1d1f;
            }

            body {
                margin: 0;
                padding: 0;
                background-color: #F1F4F6;
            }

            .top-nav-bar-wrapper {
                background-color: #1d1d1f;
            }
            .top-nav-bar {
                height: var(--nav-height);
                display: flex;
                justify-content: space-between;
                align-items: center;
                background-color: #1d1d1f;
                color: white;
            }

            .nav-right-big {
                display: flex;
                justify-content: flex-end;
                align-items: center;
            }

            .nav-right a {
                color: white;
                text-decoration: none;
                margin: 0 20px;
            }

            .register-btn {
                padding: 5px 10px;
                border: 1px solid white;
                border-radius: 2px;
            }

            .main {
                width: 100%;
                background-color: #F1F4F6;
            }

            .section1 {
                display: flex;
                align-items: center;
                justify-content: center;
                flex-wrap: wrap;
            }

            .section1 * {
                width: 100%;
                text-align: center;
            }

            .nav-left {
                margin-left: 5px;
            }

            .nav-left-bar {
                font-size: 25px;
                margin-right: 5px;
                margin-left: 5px;
                cursor: pointer;
            }

            .top-nav-bar-mobile {
                position: fixed;
                top: var(--nav-height);
                left: 0;
                height: calc(100vh - var(--nav-height));
                display: flex;
                flex-direction: column;
                justify-content: flex-start;
                align-items: center;
                width: 100%;
                background-color: var(--nav-bg-color);
            }

            .top-nav-bar-mobile a {
                color: white;
                margin: 30px 0;
                text-decoration: none;
            }

            .top-nav-bar-mobile .register-btn {
                width: 90%;
                height: 30px;
                line-height: 30px;
                text-align: center;
            }

            @media screen and (min-width: 900px) {
                .top-nav-bar {
                    width: 80%;
                    margin: 0 auto;
                    flex-direction: row;
                }
            }

            .disable {
                display: none;
            }

        </style>
    </body>
</html>