JS无限TAB栏切换,点击按钮自动居中


JS无限TAB栏切换,点击按钮自动居中


截图


遇到一个案例,需要TAB有点击滚动的效果,并且切换显示对应的文字,

在网上搜了一圈,没发现很合适的,要不就是需要给tab和content加唯一ID(麻烦)

所以有了这个代码。


<!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">
    <base target="_blank">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

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

        li {
            list-style-type: none;
        }

        .for9xOnly {
            margin: 8px 0;
        }

        #top7412 {
            width: 100%;
            background: #f2f2f2;
            white-space: nowrap;
            overflow: auto;
            position: relative;
            scroll-behavior: smooth;
        }

        #top7412 li {
            width: 18%;
            height: 40px;
            background-color: #bf9663;
            display: inline-block;
            text-align: center;
            line-height: 40px;
            margin: 3px;
            transition: color 0.2s, text-shadow 0.2s;
            transition-timing-function: ease-out;
            color: transparent;
            text-shadow:
                0 0 1px rgba(254, 252, 124, 1),
                0 0 3px rgba(255, 217, 54, 0.7),
                0 0 5px rgba(255, 0, 0, 1),
                0 0 14px rgba(255, 0, 0, 1),
                0 0 17px rgba(255, 0, 0, 1),
                0 0 20px rgba(255, 0, 0, 1),
                0 5px 25px rgba(0, 0, 255, 0.9);
            font-weight: 300;
            border-radius: 5px;
        }

        .wobble {
            animation: bounceIn .75s;
        }

        #top7412 li.current9888 {
            background: #c0392b;
        }

        #bottom4651 {
            width: 100%;
            background: #fff;
            position: relative;
        }

        #bottom4651 li {
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            padding: 5px 15px;
            display: none;
            font-weight: 800;
        }

        #bottom4651 li p {
            height: 40px;
            line-height: 40px;
            border-bottom: 1px solid #dcc833;
        }

        #bottom4651 li.current9888 {
            display: block;
        }

        .container::-webkit-scrollbar {
            display: none;
        }
        
        .container{
            scrollbar-width: none;
            -ms-overflow-style: none;
            overflow-y: auto;
        }        
            
            .result123 {
            text-align: center;
            height: 40px;
            line-height: 40px;
            margin: 5px 0;
            color: red;
            font-size: 20px;
            background-image: linear-gradient(0deg, rgba(222, 199, 7, 0.33) 0%, rgb(255, 255, 255) 100%);
            box-shadow: inset 0px 0px 0px 1px #ffffff, 0 2px 3px rgba(0, 0, 0, 0.1);
        }

        #bottom4651 li span {
            color: #c0392b;
        }    
    </style>
</head>

<body>
    <div class="for9xOnly">
        <ul id="top7412" class="container">
            <li class="current9888">1</li>
	
            <li>2</li>
	
            <li>3</li>
	
            <li>4</li>
	
            <li>5</li>
	
            <li>6</li>
        </ul>
        <ul id="bottom4651">
            <li class="current9888">
                <p class="result123">我是1</p>

            </li>
	
            <li>
                <p class="result123">我是2</p>
            </li>
	
            <li>
                <p class="result123">我是3</p>
            </li>
	
            <li>
                <p class="result123">我是4</p>
            </li>
	
            <li>
                <p class="result123">我是5</p>
            </li>
	
            <li>
                <p class="result123">我是6</p>
            </li>
	
        </ul>
    </div>

    <script>
        // 获取id=top7412
        var container = document.querySelector("#top7412");
        // 获取id=top7412的宽
        var containerW = container.offsetWidth;
        // 获取id=top7412的所有li,该变量为数组
        var navList = document.getElementById('top7412').getElementsByTagName('li');
        // 获取id=bottom4651的所有li,该变量为数组
        var contents = document.getElementById('bottom4651').getElementsByTagName('li');
        // 函数名handleClick,参数event
        function handleClick(event) {
            // 删除 所有li的属性--class
            for (var j = 0; j < navList.length; j++) {
                navList[j].removeAttribute('class');
            }
            // 设定触发事件的元素的 class 属性的值
            event.target.className = "current9888 wobble";

            // 获取触发事件的元素的 index 属性的值 (即bottom4651下的li的index值)
            var num = event.target.getAttribute("index");
            // 遍历删除所有contents的类名(即bottom4651下的li的类名)
            for (var k = 0; k < contents.length; k++) {
                contents[k].removeAttribute('class');
            }
            // 设定触发事件的元素的 class 属性的值。总结:排他算法
            contents[num].className = "current9888";

            // 获取到当前点击元素的 offsetLeft  - 包裹盒子 offsetWidth 的一半 + 当前点击元素 offsetWidth 的一半
            // event.target.offsetLeft获取到当前点击元素的 offsetLeft(即该元素左上角到父元素左边的距离)
            // containerW / 2 包裹盒子 offsetWidth 的一半
            // event.target.offsetWidth / 2 当前点击元素 offsetWidth 的一半
            // 这三个值相互加减,会产生什么效果?假设父盒子宽为800px,
            // 此时的当前点击元素位于最右边,假设其offsetLeft为750px(显示了该盒子的一半,其他部分被隐藏),
            // 其宽为100px,其一半的宽则为50px,750-400+50=300,则向左滚动300px,
            
            var scrollLeftNum = event.target.offsetLeft - containerW / 2 + event.target.offsetWidth / 2;
            
            // 执行container的滚动条向左滚动,如按上例,则为300px,
            // 本例中使用 CSS将滚动条隐藏,形成点击元素元素自动向容器中间移动的效果

            /***
            CSS如下 使用overflow-y: auto;是为了可以滚动
            .container::-webkit-scrollbar display: none;
            .container{
                scrollbar-width: none;
                -ms-overflow-style: none;
                overflow-y: auto; 
            }
            */

            // container执行滚动
            container.scrollLeft = scrollLeftNum;
        }
        // 给每个li加index,再给每个li绑定事件监听
        for (var i = 0; i < navList.length; i++) {
            navList[i].setAttribute("index", i);
            navList[i].addEventListener('click', handleClick);
        }
        // 可想而知,每个top的li和对应的每个bottom的li的index值都是相同的,
        // 所以不必给li们增加额外的id也可以让它们对应显示,
        // 只需要在点击触发的li对应的bottom的li加一个display:block即可
        
        /*
        20241029版本更新,主要改变是:
        1. 代码更合理,不再直接删除class属性,而是移除指定类名
        2. 直接给class属性添加类名,不再使用覆盖式的className='类名'方法
        3. 使用 scrollIntoView 代替 scrollLeft 的平滑滚动,该方法有3个可选参数:
        start(元素与容器的开头对齐)
        end(元素与容器的末尾对齐)
        center(元素与容器的中间对齐)
        用法:scrollIntoView({ behavior: 'smooth', inline: 'center' })
        */
        
         /*
        var container = document.querySelector("#top7412");
        var navList = container.getElementsByTagName('li');
        var contents = document.getElementById('bottom4651').getElementsByTagName('li');

        function handleClick(event) {
            for (var j = 0; j < navList.length; j++) {
                navList[j].classList.remove('current9888', 'wobble'); // 移除指定类名
            }
            event.target.classList.add("current9888", "wobble"); // 添加类名

            var num = event.target.getAttribute("index");
            for (var k = 0; k < contents.length; k++) {
                contents[k].classList.remove('current9888');
            }
            contents[num].classList.add("current9888");

            // 使用 scrollIntoView 代替 scrollLeft 的平滑滚动
            event.target.scrollIntoView({ behavior: 'smooth', inline: 'start' });
        }

        for (var i = 0; i < navList.length; i++) {
            navList[i].setAttribute("index", i);
            navList[i].addEventListener('click', handleClick);
        }
        */
    </script>
    
</body>
</html>    

文章作者: Alan Work
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alan Work !
  目录