Липкий навигатор не работает, что происходит?

#javascript #html #css #nav #sticky

Вопрос:

Поэтому я пытаюсь заставить свою навигационную панель прилипать к верхней части страницы, когда люди прокручивают, но она не хочет работать. По какой-то причине консоль продолжает выдавать ошибку, в которой говорится classList.remove() , что атрибуты не определены. Но в то же время, когда я их удаляю, навигационные панели не прилипают.

Если это поможет, я построил две навигационные панели. Один для мобильных устройств/планшетов, а другой для настольных компьютеров.

Что с этим происходит?

 // ---------------------------------------- GLOBAL VARIABLES
const mobileNavbar = document.getElementsByClassName("mobile-navbar");
const desktopNavbar = document.getElementsByClassName("desktop-navbar");
const stickyDesktop = desktopNavbar.offsetTop;
const stickyMobile = mobileNavbar.offsetTop;

window.onscroll = function () {
    stickyNav()
};

function stickyNav() {
    if (window.pageYOffset >= stickyDesktop || window.pageYOffset >= stickyMobile) {
        desktopNavbar.classList.add("sticky");
        mobileNavbar.classList.add("sticky");
    }
    else {
        desktopNavbar.classList.remove("sticky");
        mobileNavbar.classList.remove("sticky");
    }
}


// ---------------------------------------- DESKTOP NAVBAR
document.addEventListener('click', e => {
    const isDropdownButton = e.target.matches("[data-dropdown-button]")
    if (!isDropdownButton amp;amp; e.target.closest('[data-dropdown]') != null) return

    let currentDropdown
    if (isDropdownButton) {
        currentDropdown = e.target.closest('[data-dropdown]')
        currentDropdown.classList.toggle('active')
    }

    document.querySelectorAll('[data-dropdown].active').forEach(dropdown => {
        if (dropdown === currentDropdown) return
        dropdown.classList.remove('active')
    })
})


// ---------------------------------------- MOBILE NAVBAR
const toggleButton = document.getElementsByClassName('fa-bars')[0]
const mobileNavBar = document.getElementsByClassName('mobile-navbar-links')[0]

toggleButton.addEventListener('click', () => {
    mobileNavBar.classList.toggle('active')
}) 
 * {
    box-sizing: border-box;
}

a {
    text-decoration: none;
    color: #000;
}

body {
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
}

.sticky {
    position: fixed;
    top: 0;
    width: 100%;
}

.sticky   body {
    padding-top: 60px;
}

.scrollDown {
    position: absolute;
    top: 93%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;

}

.scrollDown a {
    text-decoration: none;
}

.scrollDown p {
    margin: 0;
    font-family: 'Nunito', sans-serif;
    font-size: 20px;
    color: #fff;
}

.fa-chevron-down,
.fa-chevron-up {
    width: 50px;
    height: 50px;
    font-size: 32px;
    color: #fff;
    ;
}

.scrollDown:hover {
    transition: .2s ease;
}


@media screen and (max-width: 600px) {
    /* ------------------------------- MOBILE NAVBAR */
    .desktop-navbar {
        display: none;
    }
    
    .mobile-navbar {
        display: flex;
        overflow: hidden;
        justify-content: space-between;
        align-items: center;
        background-color: #333;
        color: #fff;
    }

    .mobile-brand-title {
        font-size: 1.5rem;
        margin: .5rem;
    }

    .mobile-navbar-links ul {
        margin: 0;
        padding: 0;
        display: flex;
    }

    .mobile-navbar-links li {
        list-style: none;
    }

    .mobile-navbar-links li a {
        color: #fff;
        padding: 1rem;
        display: block;
    }

    .mobile-navbar-links li:hover {
        background-color: #555;
    }

    .mobile-navbar .fa-bars {
        position: absolute;
        display: none;
        flex-direction: column;
        justify-content: space-between;
        top: .75rem;
        right: 1rem;
        color: #fff;
        width: 1rem;
        height: 1rem;
        cursor: pointer;
    }

    .mobile-navbar .fa-bars {
        display: flex;
    }

    .mobile-navbar-links {
        display: none;
        width: 100%;
    }

    .mobile-navbar {
        flex-direction: column;
        align-items: flex-start;
    }

    .mobile-navbar-links ul {
        width: 100%;
        flex-direction: column;
    }

    .mobile-navbar-links li {
        text-align: center;
    }

    .mobile-navbar-links.active {
        display: flex;
    }

    

}

@media screen and (min-width: 601px) {
    /* ------------------------------- DESKTOP NAVBAR */
    .mobile-navbar {
        display: none;
    }
    
    .desktop-navbar {
        background-color: #f3f3f3;
        overflow: hidden;
        display: flex;
        align-items: baseline;
        padding: .5rem;
        gap: 1rem;
    }

    .link {
        background: none;
        border: none;
        text-decoration: none;
        color: #777;
        font-family: inherit;
        font-size: inherit;
        cursor: pointer;
        padding: 0;
    }

    .dropdown.active .link,
    .link:hover {
        color: #000;
    }

    .dropdown {
        position: relative;
    }

    .dropdown-menu {
        position: absolute;
        left: 0;
        top: calc(100%   .25rem);
        background-color: #fff;
        padding: .75rem;
        border-radius: .25rem;
        box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.3);
        z-index: 1000;
        opacity: 0;
        pointer-events: none;
        transition: opacity 150ms ease, transform 150ms ease;
        transform: translateY(-10px);
    }

    .dropdown.active>.link .dropdown-menu {
        opacity: 1;
        transform: translateY(0px);
        pointer-events: auto;
    }

    .information-grid {
        display: grid;
        grid-template-columns: repeat(2, max-content);
        gap: 2rem;
    }

    .dropdown-links {
        display: flex;
        flex-direction: column;
        gap: .25rem;
    }
} 
 <!DOCTYPE html>
<html>
    <head>
        <title>Fox Bank</title>

        <!-- Meta tags -->
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Links/Styles -->
        <link rel="stylesheet" href="styles/styles.css">
        <link rel="stylesheet" href="styles/normalize.css">
        <link rel="stylesheet" href="styles/responsive.css">
        <link rel="stylesheet" href="styles/flickity.min.css" media="screen">
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link href="https://fonts.googleapis.com/css2?family=Nunitoamp;display=swap" rel="stylesheet">
        
        <!-- Javascript -->
        <script src="https://kit.fontawesome.com/8821130486.js" crossorigin="anonymous"></script>
        <script src="js/jquery.js" defer></script>
        <script src="js/app.js" async defer></script>
        <script src="js/flickity.min.js" defer></script>

    </head>

    <body>
        <!--------------------- DESKTOP NAVBAR -->
        <!--------------------------------------->
        <div class="desktop-navbar">
            <div>
                <a href="#">
                    <h1>Big Bank</h1>
                </a>
            </div>
            <div class="dropdown" data-dropdown>
                <button class="link" data-dropdown-button>About</button>
                <div class="dropdown-menu information-grid">
                    <div>
                        <div class="dropdown-heading">Meet Our Team</div>
                        <div class="dropdown-links">
                            <a href="#" class="link">Staff</a>
                            <a href="#" class="link">Board of Directors</a>
                        </div>
                    </div>
                    <div>
                        <div class="dropdown-heading">Our History</div>
                        <div class="dropdown-links">
                            <a href="#" class="link">Overview</a>
                            <a href="#" class="link">Future</a>
                        </div>
                    </div>
                    <div>
                        <div class="dropdown-heading">Blog</div>
                        <div class="dropdown-links">
                            <a href="#" class="link">Latest Posts</a>
                            <a href="#" class="link">In The Community</a>
                            <a href="#" class="link">Security amp; Fraud Prevention</a>
                            <a href="#" class="link">National amp; International Money</a>
                        </div>
                    </div>
                    <div>
                        <div class="dropdown-heading">Contact Us</div>
                        <div class="dropdown-links">
                            <a href="#" class="link">Support Center</a>
                            <a href="#" class="link">Phone amp; Mailing Information</a>
                            <a href="#" class="link">Social Media</a>
                        </div>
                    </div>
                </div>
            </div>
            <div class="dropdown" data-dropdown>
                <button class="link" data-dropdown-button>Products</button>
                <div class="dropdown-menu information-grid">
                    <div>
                        <div class="dropdown-heading">Checking</div>
                        <div class="dropdown-links">
                            <a href="#" class="link">Basic Checking</a>
                            <a href="#" class="link">Teens Checking</a>
                            <a href="#" class="link">Prime Checking</a>
                            <a href="#" class="link">Elite Checking</a>
                        </div>
                    </div>
                    <div>
                        <div class="dropdown-heading">Savings</div>
                        <div class="dropdown-links">
                            <a href="#" class="link">Basic Savings</a>
                            <a href="#" class="link">Teens Savings</a>
                            <a href="#" class="link">Prime Savings</a>
                            <a href="#" class="link">Elite Savings</a>
                        </div>
                    </div>
                    <div>
                        <div class="dropdown-heading">Borrow</div>
                        <div class="dropdown-links">
                            <a href="#" class="link">Personal Loans</a>
                            <a href="#" class="link">Auto Loans</a>
                            <a href="#" class="link">Credit Cards</a>
                            <a href="#" class="link">Mortgage</a>
                            <a href="#" class="link">Shark Loans</a>
                        </div>
                    </div>
                    <div>
                        <div class="dropdown-heading">Retirement</div>
                        <div class="dropdown-links">
                            <a href="#" class="link">Traditional IRA</a>
                            <a href="#" class="link">Roth IRA</a>
                            <a href="#" class="link">Self Employment IRA</a>
                        </div>
                    </div>
                </div>
            </div>
            <a href="#"><button>Login</button></a>
        </div>


        <!---------------------- MOBILE NAVBAR -->
        <!--------------------------------------->
        <nav class="mobile-navbar">
            <div class="mobile-brand-title">Fox Bank</div>
            <i class="fa-solid fa-bars"></i>
            <div class="mobile-navbar-links">
                <ul>
                    <li><a href="#">About</a></li>
                    <li><a href="#">Products</a></li>
                    <li><a href="#">Login</a></li>
                </ul>
            </div>
        </nav>

<div>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>CONTENT GOES HERE</p>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>

</div>

        
    </body>
</html> 

Комментарии:

1. Есть ли какая-то особая причина, по которой вы пытаетесь добавить/удалить класс «.sticky», а не просто оставлять элементы навигационной панели липкими все время?

2. О_о я понятия не имею, почему я просто не сделал этого с самого начала. Наверное, мне следует сделать перерыв.

3. Лолол, удачи тебе!

Ответ №1:

Переменные панели навигации содержат списки узлов, а не элементы панели навигации, и, следовательно, не имеют classList свойства.

Попробуйте заменить

 const mobileNavbar = document.getElementsByClassName("mobile-navbar");
const desktopNavbar = document.getElementsByClassName("desktop-navbar");
 

с

 const mobileNavbar = document.querySelector(".mobile-navbar");
const desktopNavbar = document.querySelector(".desktop-navbar");
 

или добавьте [0] значения в список после узла, чтобы выбрать первый элемент в каждом списке.

Комментарии:

1. Это, кажется, делает свое дело, но теперь он выдает новую ошибку консоли: «Ошибка типа не обнаружена: Не удается прочитать свойства null (чтение «offsetTop»)»

2. Я только что исправил опечатку — добавил точку ( » .») перед именами классов в document.querySelector аргументах.

3. фейспалм , я не могу поверить, что пропустил это. Спасибо, теперь это работает! 🙂