Material Design 中如何实现滑动删除

在 Material Design 标准中,滑动删除是一种非常常见的交互方式。当用户需要删除某个条目时,只需通过在屏幕上向左或向右滑动来触发删除的操作,从而实现快速、方便、直观的交互体验。那么,在前端中如何实现这个功能呢?接下来,我们就来详细地讲解一下。

实现原理

在 Material Design 中,实现滑动删除通常需要借助一些 JavaScript 库来实现,比如 hammer.jsiscroll.js 等。这些库可以帮助我们实现手势识别和列表滚动等功能,从而完成滑动删除的实现。

具体来说,实现滑动删除的原理如下:

  • 通过 hammer.js 库来识别用户的上下左右滑动手势;
  • 通过 iscroll.js 库来实现列表的横向滚动;
  • 在列表项上注册滑动事件,并在滑动过程中动态地修改列表项的位置和样式;
  • 监听列表项的删除事件,并在删除时执行相应的操作。

实现步骤

实现滑动删除功能的具体步骤如下:

第一步:准备所需库和资源

在开始之前,需要先准备好所需的库和资源,包括:

  • hammer.js 库,用于手势识别;
  • iscroll.js 库,用于列表滚动;
  • 引入适当的样式表和图片资源。

第二步:定义 HTML 结构

在 HTML 中,需要定义一个列表,并为每个列表项添加一个删除按钮。同时,需要为列表项设置相应的样式,以便在滑动时进行样式修改。

<ul id="list">
    <li>
        <div class="content">列表项内容</div>
        <div class="delete">删除</div>
    </li>
    <!-- 其他列表项 -->
</ul>

第三步:设置样式

在 CSS 中,为列表和列表项设置相应的样式,以便实现滑动和删除效果。具体来说,需要设置列表项的位置、宽度和背景色等样式,以及为删除按钮添加合适的样式。

#list {
    position: relative;
    width: 100%;
    overflow: hidden;
}
#list li {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 50px;
    background-color: #fff;
    border-bottom: 1px solid #eee;
    transition: transform .2s ease-out;
    transform: translateX(0);
}
#list li .content {
    float: left;
    width: 80%;
    line-height: 50px;
    padding-left: 20px;
}
#list li .delete {
    float: right;
    width: 20%;
    height: 50px;
    line-height: 50px;
    text-align: center;
    background-color: #f00;
    color: #fff;
    transition: transform .2s ease-out;
    transform: translateX(100%);
}
#list li.swipe {
    background-color: #f4f4f4;
}
#list li.swipe .delete {
    transform: translateX(0);
}

第四步:使用 hammer.js 实现手势识别

在 JavaScript 中,使用 hammer.js 库来实现手势识别。具体来说,需要在列表项上注册 pan 事件,并在事件处理函数中识别用户的滑动方向,并根据滑动方向动态修改列表项的位置。

// 获取需要设置滑动删除的列表
var list = document.querySelector('#list');

// 为每个列表项注册滑动事件
[].slice.call(list.querySelectorAll('li')).forEach(function (li) {
    // 创建 Hammer 实例
    var mc = new Hammer(li);

    // 监听 panleft 和 panright 事件
    mc.on('panleft panright', function (ev) {
        // 获取列表项的位置
        var pos = ev.deltaX;

        // 判断是否滑出距离阈值
        if (Math.abs(pos) > 50) {
            li.classList.add('swipe');
        } else {
            li.classList.remove('swipe');
        }

        // 根据滑动方向设置列表项的位置
        if (ev.type === 'panright') {
            pos = (pos > 0) ? 0 : pos;
            li.style.transform = 'translateX(' + pos + 'px)';
        } else if (ev.type === 'panleft') {
            pos = (pos < 0) ? 0 : pos;
            li.style.transform = 'translateX(' + pos + 'px)';
        }
    });
});

第五步:使用 iscroll.js 实现列表滚动

为了实现横向的列表滚动,需要使用 iscroll.js 库。具体来说,需要在列表外部创建一个容器,并使用 iscroll.js 实例来实现滚动效果。

<div id="wrapper">
    <ul id="list">
        <li>
            <div class="content">列表项内容</div>
            <div class="delete">删除</div>
        </li>
        <!-- 其他列表项 -->
    </ul>
</div>
#wrapper {
    width: 100%;
    overflow: hidden;
}
// 创建 iScroll 实例
var myScroll = new IScroll('#wrapper', {
    scrollX: true,
    scrollY: false,
    click: true
});

第六步:监听删除事件并处理

最后一步是监听删除事件,并在删除时执行相应的操作。具体来说,需要在列表项上注册 click 事件,并在事件处理函数中判断是点击了删除按钮还是列表项本身。

// 为每个列表项注册删除事件
[].slice.call(list.querySelectorAll('.delete')).forEach(function (btn) {
    btn.addEventListener('click', function (ev) {
        // 取消事件冒泡
        ev.stopPropagation();

        // 获取列表项并删除
        var li = btn.parentElement;
        li.parentElement.removeChild(li);
    });
});

实例代码

下面是一个完整的示例代码,可以在浏览器中运行并查看效果。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Material Design 中如何实现滑动删除</title>

    <style>
        #wrapper {
            width: 100%;
            overflow: hidden;
        }
        #list {
            position: relative;
            width: 100%;
            overflow: hidden;
        }
        #list li {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 50px;
            background-color: #fff;
            border-bottom: 1px solid #eee;
            transition: transform .2s ease-out;
            transform: translateX(0);
        }
        #list li .content {
            float: left;
            width: 80%;
            line-height: 50px;
            padding-left: 20px;
        }
        #list li .delete {
            float: right;
            width: 20%;
            height: 50px;
            line-height: 50px;
            text-align: center;
            background-color: #f00;
            color: #fff;
            transition: transform .2s ease-out;
            transform: translateX(100%);
        }
        #list li.swipe {
            background-color: #f4f4f4;
        }
        #list li.swipe .delete {
            transform: translateX(0);
        }
    </style>
</head>
<body>
    <div id="wrapper">
        <ul id="list">
            <li>
                <div class="content">列表项 1</div>
                <div class="delete">删除</div>
            </li>
            <li>
                <div class="content">列表项 2</div>
                <div class="delete">删除</div>
            </li>
            <li>
                <div class="content">列表项 3</div>
                <div class="delete">删除</div>
            </li>
            <!-- 更多列表项 -->
        </ul>
    </div>

    <script src="https://cdn.bootcdn.net/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/iscroll/5.2.0/iscroll.min.js"></script>
    <script>
        // 获取需要设置滑动删除的列表
        var list = document.querySelector('#list');

        // 为每个列表项注册滑动事件
        [].slice.call(list.querySelectorAll('li')).forEach(function (li) {
            // 创建 Hammer 实例
            var mc = new Hammer(li);

            // 监听 panleft 和 panright 事件
            mc.on('panleft panright', function (ev) {
                // 获取列表项的位置
                var pos = ev.deltaX;

                // 判断是否滑出距离阈值
                if (Math.abs(pos) > 50) {
                    li.classList.add('swipe');
                } else {
                    li.classList.remove('swipe');
                }

                // 根据滑动方向设置列表项的位置
                if (ev.type === 'panright') {
                    pos = (pos > 0) ? 0 : pos;
                    li.style.transform = 'translateX(' + pos + 'px)';
                } else if (ev.type === 'panleft') {
                    pos = (pos < 0) ? 0 : pos;
                    li.style.transform = 'translateX(' + pos + 'px)';
                }
            });
        });

        // 为每个列表项注册删除事件
        [].slice.call(list.querySelectorAll('.delete')).forEach(function (btn) {
            btn.addEventListener('click', function (ev) {
                // 取消事件冒泡
                ev.stopPropagation();

                // 获取列表项并删除
                var li = btn.parentElement;
                li.parentElement.removeChild(li);
            });
        });

        // 创建 iScroll 实例
        var myScroll = new IScroll('#wrapper', {
            scrollX: true,
            scrollY: false,
            click: true
        });
    </script>
</body>
</html>

总结

通过以上的步骤,我们成功地实现了 Material Design 中的滑动删除功能。本文中所使用的 hammer.jsiscroll.js 库是非常常见的前端库,不仅可以用来实现滑动删除,还可以用在各种其他的交互效果中。希望本文对于正在学习前端开发的读者有所帮助。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a2be59add4f0e0ffad7b14


纠错反馈