如何从导航栏中删除带有动画的文本

How to make remove text with animation from navbar

你好,我想为手机制作这个导航栏,当用户向下滚动时,它会剪掉文本,但我很困惑我该怎么做,因为如果我只是向上移动导航栏,它就会开始剪掉我的先上图片有人能给我一个线索,告诉我如何解决这个问题这是我的代码(注意我使用的是 tailwindcss)

代码:

<script>
    //checks if on phone
    let onPhone;
    function checkIfOnPhone() {
        let width = window.innerWidth > 0 ? window.innerWidth : screen.width;
        if (width < 426) {
            onPhone = true;
        } else {
            onPhone = false;
        }
    }
    checkIfOnPhone();
    addEventListener("resize", checkIfOnPhone);
    //user scroling page
    let phoneNavbarFull;
    document.addEventListener("scroll", scrollListener);
    let topPxSize;
    let scrollTop;
    function scrollListener() {
        scrollTop =
            window.pageYOffset ||
            (
                document.documentElement ||
                document.body.parentNode ||
                document.body
            ).scrollTop;

        if (onPhone && scrollTop < 20) {
            topPxSize = -scrollTop + "px";
        } else {
            topPxSize = "-20px";
        }
        console.log(scrollTop);
    }
    scrollListener();
</script>

<main>
    {#if onPhone}
        <nav class="navbar-background" style="--topPxSize: {topPxSize}">
            <div class="navbar">
                <ul class="flex justify-between">
                    <li />
                    <li>
                        <button class="flex flex-col items-center">
                            <img src="./imgs/Home_light.svg" alt="Home" />
                            <p class="nav-btn-mobile">Home</p>
                        </button>
                    </li>

                    <li>
                        <button class="flex flex-col items-center"
                            ><img
                                src="./imgs/Desk_alt_light.svg"
                                alt="Portfolio"
                            />
                            <p class="nav-btn-mobile">Portfolio</p></button
                        >
                    </li>
                    <li>
                        <button class="flex flex-col items-center"
                            ><img src="./imgs/Phone_light.svg" alt="Contact" />
                            <p class="nav-btn-mobile">Contact</p></button
                        >
                    </li>

                    <li />
                </ul>
            </div>
        </nav>
        <div class="pb-60 mb-60" />
    {:else}
        <nav class="navbar-background">
            <ul class="flex justify-between">
                <li class="nav-btn"><span class="font-bold">LAY</span>CODE</li>
                <ul class="flex">
                    <li class="nav-btn">Home</li>
                    <li class="nav-btn">Portfolio</li>
                    <li class="nav-btn">Contact</li>
                </ul>
            </ul>
        </nav>
    {/if}
</main>

<style lang="postcss" global>
    @tailwind base;
    @tailwind components;
    @tailwind utilities;

    @layer utilities {
        .navbar {
            position: fixed;
            top: 0;
            width: 100%;
            z-index: 100;
        }
        .navbar-background {
            background-color: #000;
            position: fixed;
            top: var(--topPxSize);
            width: 100%;
            height: 45px;
            z-index: 100;
        }
        .nav-btn {
            @apply text-white mr-6;
        }
        .nav-btn-mobile {
            @apply text-white text-sm text-center;
        }
    }
</style>

这是它应该看起来或多或少的样子。

更新: 我用这段代码做了我想做的,但问题是如果屏幕变宽然后又变小,动画停止工作这里是更新的代码。

代码:

<script>
    //checks if on phone
    let onPhone;
    function checkIfOnPhone() {
        let width = window.innerWidth > 0 ? window.innerWidth : screen.width;
        if (width < 426) {
            onPhone = true;
        } else {
            onPhone = false;
        }
    }
    checkIfOnPhone();
    addEventListener("resize", checkIfOnPhone);
    //user scroling page
    document.addEventListener("scroll", scrollListener);
    let scrollTop;
    function scrollListener() {
        scrollTop =
            window.pageYOffset ||
            (
                document.documentElement ||
                document.body.parentNode ||
                document.body
            ).scrollTop;
    }
    scrollListener();

    //playground zone
    import { onMount } from "svelte";

    let tracker, paragraphs;

    onMount(() => {
        sectionObserver.observe(tracker);
        paragraphs = [...document.getElementsByTagName("p")];
    });

    const options = {
        rootMargin: "0px 0px 0px 0px",
    };

    const sectionObserver = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
            console.log(entry);
            if (entry.isIntersecting) {
                paragraphs.forEach((p) => p.classList.remove("collapse"));
            } else {
                paragraphs.forEach((p) => p.classList.add("collapse"));
            }
        });
    }, options);
</script>

<main>
    {#if onPhone}
        <nav>
            <div id="ul-wrapper">
                <ul class="navbar">
                    <li />
                    <li class="nav-btn-mobile">
                        <img src="./imgs/Home_light.svg" alt="Home" />
                        <p class="nav-btn-text">Home</p>
                    </li>
                    <li class="nav-btn-mobile">
                        <img src="./imgs/Desk_alt_light.svg" alt="Portfolio" />
                        <p class="nav-btn-text">Portfolio</p>
                    </li>
                    <li class="nav-btn-mobile">
                        <img src="./imgs/Phone_light.svg" alt="Contact" />
                        <p class="nav-btn-text">Contact</p>
                    </li>
                    <li />
                </ul>
            </div>
        </nav>
    {:else}
        <nav class="navbar-background">
            <ul class="flex justify-between">
                <li class="nav-btn"><span class="font-bold">LAY</span>CODE</li>
                <ul class="flex">
                    <li class="nav-btn">Home</li>
                    <li class="nav-btn">Portfolio</li>
                    <li class="nav-btn">Contact</li>
                </ul>
            </ul>
        </nav>
    {/if}
    <div id="content">
        <div id="tracker" bind:this={tracker} />
    </div>
</main>

<style lang="postcss" global>
    @tailwind base;
    @tailwind components;
    @tailwind utilities;

    @layer utilities {
        .navbar {
            position: fixed;
            width: 100%;
            background: #000;
            display: flex;
            justify-content: space-between;
        }
        .navbar-background {
            background-color: #000;
            position: fixed;
            width: 100%;
            height: 45px;
            z-index: 100;
        }
        .nav-btn {
            @apply text-white;
        }
        .nav-btn-mobile {
            @apply text-white flex flex-col items-center;
        }
        .nav-btn-text {
            line-height: 2;
            overflow: hidden;
            transition: all 300ms;
            font-size: 0.8rem;
        }
        :global(.collapse) {
            line-height: 0 !important;
        }
        #content {
            height: 3000px;
            background: lightblue;
            padding: 1rem 3rem;
        }
        #tracker {
            margin-bottom: 8rem;
        }
    }
</style>

我建议您设置
而不是将文本区域切割 20px

document.querySelector('.nav-btn-mobile').style.display = "hidden";
.nav-btn-mobile{
  display:hidden;
}

您可以将它添加到另一个 class 中,或者只在您的 Javascript 中更改它,因为


它只会隐藏您的导航栏文本,而不是覆盖导航栏中的徽标。

您可以使用 IntersectionObserver 来跟踪元素在页面上的位置。当它越过某个点时,在菜单中的段落元素上切换 class 什么会转换 line-height.

一个REPL

(没有 window 调整大小/onPhone 功能的旧版本 >>REPL

<script>
    import Icon from './Icon.svelte'
    import {onMount} from 'svelte'
        
    let tracker, paragraphs

    onMount(() => {
        sectionObserver.observe(tracker)
    })

    // checks if on phone
    let onPhone;
    function checkIfOnPhone() {
        let width = window.innerWidth > 0 ? window.innerWidth : screen.width;
        if (width < 426) {
            onPhone = true;
        } else {
            onPhone = false;
        }
    }
    checkIfOnPhone();
    addEventListener("resize", checkIfOnPhone);

    // setup section Observer
    const options = {
        rootMargin: "0px 0px 0px 0px"
    }   
    const sectionObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
//          console.log(entry)              
            paragraphs = [...document.getElementsByTagName('p')]
            if(entry.isIntersecting){
                paragraphs.forEach(p => p.classList.remove('collapse'))
            } else {
                paragraphs.forEach(p => p.classList.add('collapse'))
            }
        })
    }, options) 
                
</script>

<main>
    {#if onPhone}
    <nav>
        <div id="ul-wrapper">
        <ul class="mobile">
            <li class="nav-btn">
                <Icon icon={1} />
                <p class="nav-btn-mobile">Home</p>
            </li>
            <li class="nav-btn">
                <Icon icon={2} />
                <p class="nav-btn-mobile">Portfolio</p>
            </li>
            <li class="nav-btn">
                <Icon icon={3} />
                <p class="nav-btn-mobile">Contact</p>
            </li>
        </ul>   
        </div>
    </nav>
    {:else}
          <nav class="navbar-background">
            <ul class="flex justify-between">
              <li class="nav-btn logo"><div><b>LAY</b>CODE</div></li>                
                            <li class="nav-btn">Home</li>
                            <li class="nav-btn">Portfolio</li>
                            <li class="nav-btn">Contact</li>                
            </ul>
        </nav>
    {/if}
    
    <div id="content">
        <div id="tracker" bind:this={tracker}></div>
        <h1>
            Page Content
        </h1>
    </div>  
</main>

<style>
    :global(body) {
        margin: 0;
        padding: 0;
    }
    ul {
        position: fixed;
        width: 100%;
        background: #e3e3e3;
        margin: 0;
        padding:0;
        list-style: none;
        display: flex;
        justify-content: space-evenly;
    }
    li {
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: .5rem;
    }
    .logo {
        white-space: nowrap;
    }
    p {
        line-height: 2;
        margin: 0;
        padding: 0;
        overflow: hidden;
        transition: all 300ms;
    }   
    :global(.collapse) {
        line-height: 0 !important;
    }
    #content {
        height: 3000px;
        background: lightblue;
        padding: 1rem 3rem;
    }
    #tracker {
        margin-bottom: 8rem;
    }
</style>

你不能只使用简单的 CSS 来做到这一点吗?

body {
  margin: 0;
  padding: 0;
}
nav {
  position: fixed;
  width: 100%;
  top: 0;
  background: #333;
  color: #fff;
}
ul {
  margin: 0;
  list-style-type: none;
}
li {
  padding: 15px;
}
.content {
  background-color: #00ff00;
  position: absolute;
  top: 48px;
  width: 100%;
  height: 110vh;
}

https://codepen.io/kyager/pen/abLowBJ