0
点赞
收藏
分享

微信扫一扫

javaScript小案例------js实现手风琴效果篇

云岭逸人 2022-04-05 阅读 73
javascript

原生js书写手风琴效果

js手风琴效果

手风琴效果展示

第一种方法

手风琴需求

html和css:

html:
<!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>手风琴效果</title>
    <link rel="stylesheet" href="./index.css">
</head>

<body>
    <ul class="container">
        <li class="menu-container">
            <p>菜单一</p>
            <ul class="menu-ul">
                <li>菜单一.1</li>
                <li>菜单二.2</li>
                <li>菜单三.3</li>
                <li>菜单四.4</li>
            </ul>
        </li>
        <li class="menu-container">
            <p>菜单二</p>
            <ul class="menu-ul">
                <li>菜单二.1</li>
                <li>菜单二.2</li>
                <li>菜单二.3</li>
                <li>菜单二.4</li>
            </ul>
        </li>
        <li class="menu-container">
            <p>菜单三</p>
            <ul class="menu-ul">
                <li>菜单三.1</li>
                <li>菜单三.2</li>
                <li>菜单三.3</li>
                <li>菜单三.4</li>
            </ul>
        </li>
        <li class="menu-container">
            <p>菜单四</p>
            <ul class="menu-ul">
                <li>菜单四.1</li>
                <li>菜单四.2</li>
                <li>菜单四.3</li>
                <li>菜单四.4</li>
            </ul>
        </li>
    </ul>
    <script src="./index.js"></script>
    <script src="./animate.js"></script>
</body>

</html>
css:
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.container {
    width: 200px;
    margin: 0 auto;
    margin-top: 40px;
}

.menu-container {
    background-color: cadetblue;
    margin-top: 30px;
}

li {
    list-style: none;
}

p {
    /* padding-left: 40px; */
    margin-left: 40px;
    font-size: 15px;
    font-weight: bold;
    cursor: pointer;
    height: 40px;
    line-height: 40px;
}

.menu-ul {
    padding-left: 20px;
    line-height: 40px;
    height: 0px;
    overflow: hidden;
    background-color: violet;
}

js

animate.js
// 动画
function createAnimation(options) {
    var form = options.form;
    var to = options.to;
    var totalTime = options.totalTime || 1000;
    var duration = options.duration || 15;
    var times = Math.floor(totalTime / duration);
    var durationHeight = (to - form) / times;
    var curTime = 0;
    var timeId = setInterval(function() {
        form += durationHeight;
        curTime++;
        if (curTime >= times) {
            form = to;
            clearInterval(timeId);
            options.onend && options.onend();
        }
        options.onmove && options.onmove(form);
    }, duration);
}

index.js
// 封装document.querySelector()
function $(selector) {
    return document.querySelector(selector);
}
// 交互
// 获取到所有的菜单项
var title = document.querySelectorAll('.menu-container p');
// console.log(title);
// 遍历所有的菜单项,分别注册鼠标点击事件
for (var i = 0; i < title.length; i++) {
    title[i].onclick = function() {
        var click = document.querySelector('.menu-ul[status=opened]');
        if (click) {
            close(click);
        }
        switchMenu(this.nextElementSibling);
    };
}
// 点击菜单,菜单显示出来
var menu = $('.menu-ul');
var menuHeight = 40;
var totalTime = 20;

function open(menu) {
    var status = menu.getAttribute('status');
    if (status !== 'closed' && status) {
        return;
    }
    menu.setAttribute('status', 'playing');
    createAnimation({
        form: 0,
        to: menuHeight * menu.children.length,
        totalTime: 500,
        onmove: function(n) {
            menu.style.height = n + 'px';
        },
        onend: function() {
            menu.setAttribute('status', 'opened');
        },
    });
}

function close(menu) {
    var status = menu.getAttribute('status');
    if (status !== 'opened') {
        return;
    }
    menu.setAttribute('status', 'playing');
    createAnimation({
        form: menuHeight * menu.children.length,
        to: 0,
        totalTime: 500,
        onmove: function(n) {
            menu.style.height = n + 'px';
        },
        onend: function() {
            menu.setAttribute('status', 'closed');
        },
    });
}

function switchMenu(menu) {
    var status = menu.getAttribute('status');
    if (status === 'palying') {
        return;
    } else if (status === 'opened') {
        close(menu);
    } else {
        open(menu);
    }
}

第二种方法

<!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;
            font-size: 100%;
            list-style: none;
        }
        .menu {
            width: 200px;
            height: 50px;
            background: #409eff;
            color: #fff;
            line-height: 50px;
            margin: 0 auto;
            margin-top: 50px;
            text-align: center;
            cursor: pointer;
            position: relative;
        }
        .sub-menu {
            background: #ddebfd;
            font-size: 14px;
            line-height: 35px;
            color: #333;
            padding: 10px 0;
            position: absolute;
            width: 100%;
        }
    </style>
    <style>
        .sub-menu {
            transform-origin: center top;
            transform: scaleY(0);
            transition: 0.5s;
        }
        .menu:hover .sub-menu {
            transform: scaleY(1);
        }
    </style>
</head>

<body>
    <div class="menu">
        <h2>下拉菜单</h2>
        <ul class="sub-menu">
            <li>子菜单1</li>
            <li>子菜单2</li>
            <li>子菜单3</li>
            <li>子菜单4</li>
        </ul>
    </div>
</body>

</html>
举报

相关推荐

0 条评论