一键生成“水波纹按钮”,连 CSS 动画都不用自己写了!一键生成“水波纹按钮”,连 CSS 动画都不用自己写了!

举报
不惑 发表于 2025/07/14 14:21:28 2025/07/14
【摘要】 前两天做页面交互时,突然有个想法:“我想加一个点击时有水波纹的按钮,就像 Android 上那种 Material Ripple 效果,既优雅又带感。”以前搞这种动画,光是 CSS 和 JS 的交互处理就能折腾一阵子:点击位置的计算、波纹的生成、动画时间、淡出曲线、性能优化……一大堆细节。但现在,我只在 CodeBuddy 里轻描淡写地说了一句:“生成一个按钮,点击时有水波纹动画,模仿 Ma...

前两天做页面交互时,突然有个想法:“我想加一个点击时有水波纹的按钮,就像 Android 上那种 Material Ripple 效果,既优雅又带感。”

以前搞这种动画,光是 CSS 和 JS 的交互处理就能折腾一阵子:点击位置的计算、波纹的生成、动画时间、淡出曲线、性能优化……一大堆细节。

但现在,我只在 CodeBuddy 里轻描淡写地说了一句:

“生成一个按钮,点击时有水波纹动画,模仿 Material Design Ripple 效果。”

没想到 CodeBuddy 直接给我整了个现成的,自带动画、自适应点击位置、可复用样式的按钮组件,效果干净、流畅,完全不输手写版本。

我想要的水波纹效果是什么样?

我说的“水波纹”并不是那种浮夸的点击特效,而是 Material Design 里的那种:

  • 鼠标点击按钮时,以点击点为中心出现一个淡淡的圆形扩散波纹;

  • 波纹会逐渐扩散变大,然后渐隐消失;

  • 在不同按钮尺寸下,动画自然适配,不突兀;

  • 背景色不被覆盖,波纹只是视觉反馈;

  • 不阻塞其他交互,响应足够快。

说白了,就是一种“细腻但克制”的美感。

CodeBuddy 如何“自动生成”这个效果?

CodeBuddy 的能力在于,它不只是理解按钮该长什么样,它还能理解“水波纹”这三个字背后的交互意图。

我只输入一句自然语言指令:

“生成一个按钮,点击时显示水波纹动画,模拟 Material Ripple 效果。”

CodeBuddy 给我的组件非常完整:

  • 按钮结构:简洁干净,支持文本、图标或任意子内容;

  • CSS 动画:用 @keyframes 精细模拟波纹扩散和透明度衰减;

  • 事件逻辑:自动绑定点击事件,根据鼠标点击位置动态生成波纹;

  • 性能考虑:波纹元素会在动画结束后自动移除,内存友好;

  • 可复用性:生成的是组件化写法,可以多处引用、不重复代码;

  • 样式隔离:波纹层与按钮内容分离,保证文字/icon 不被覆盖。

而我,不用动手写一行样式。

点击反馈体验:超出预期的细腻

我原本以为 CodeBuddy 只是给一个基础版,结果效果出奇地丝滑。点击按钮的那一刻,波纹从鼠标点中心扩散开,透明度控制得刚刚好,没有明显的卡顿或突兀。

更惊喜的是——

  • 多次快速点击:波纹能正确叠加,不互相遮盖;

  • 适配深色背景:波纹颜色会自动调整为浅色调;

  • 移动端长按:也能触发波纹,反馈一致;

  • hover 状态:还贴心加了阴影过渡,动静结合。

可以说,这就是标准 UI 体验里“锦上添花”的交互小亮点。

想拓展?CodeBuddy 还能继续自动加料

我试着继续和 CodeBuddy 说:

“加一个变体,支持长按触发水波纹,并显示文字提示。”

CodeBuddy 就自动生成了一个新版本,按钮长按超过 500ms 不但有水波纹,还会在上方弹出一句提示信息,比如:“正在执行,请稍候……”

我又说了一句:

“按钮加图标,放在左边,点击水波纹不遮住图标。”

CodeBuddy 就更新了按钮结构,图标和文字左右排布,并自动让水波纹绕开图标中心,重点落在点击位置。真的是非常智能的补全能力。

CodeBuddy 帮我省下的不只是时间

以前,我总觉得一些交互效果就算好看,可能不值得花一两个小时来写。但现在有了 CodeBuddy ,我只需要几秒钟就能把想法变成现实,还能自动生成质量不错的代码。

从“我想要一个水波纹按钮”,到“这个按钮已经可以上线用了”,只隔着一行自然语言。

这个过程,不仅提升了效率,更释放了我的创造力。因为我再也不会因为“实现起来太麻烦”而放弃一个好点子了。

想试试的朋友可以这样做:

打开 CodeBuddy ,输入这句:

“生成一个按钮,点击时带水波纹动画,模拟 Material Ripple 效果。”

然后看看 CodeBuddy 给你的惊喜。如果你有更复杂的交互想法,也尽管说出来,它都能帮你“对号入座”。未来的前端开发,也许真的不再是写组件,而是说组件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Material 水波纹动画效果</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Arial', 'Microsoft YaHei', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 20px;
            color: #333;
        }

        .header {
            text-align: center;
            margin-bottom: 50px;
            color: white;
        }

        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
        }

        .header p {
            font-size: 1.1em;
            opacity: 0.9;
        }

        .demo-container {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 30px;
            max-width: 1200px;
            width: 100%;
        }

        .demo-section {
            background: rgba(255, 255, 255, 0.95);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
            backdrop-filter: blur(10px);
        }

        .section-title {
            font-size: 1.3em;
            font-weight: bold;
            margin-bottom: 20px;
            color: #333;
            text-align: center;
        }

        /* 基础水波纹容器 */
        .ripple-container {
            position: relative;
            overflow: hidden;
            cursor: pointer;
            user-select: none;
            -webkit-tap-highlight-color: transparent;
        }

        /* 水波纹动画 */
        .ripple {
            position: absolute;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.6);
            transform: scale(0);
            animation: ripple-animation 0.6s linear forwards;
            pointer-events: none;
            z-index: 1;
        }

        @keyframes ripple-animation {
            0% {
                transform: scale(0);
                opacity: 1;
            }
            100% {
                transform: scale(4);
                opacity: 0;
            }
        }

        /* 长按水波纹动画 */
        .ripple-long-press {
            position: absolute;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.3);
            transform: scale(0);
            animation: ripple-long-press-animation 2s ease-out forwards;
            pointer-events: none;
            z-index: 1;
        }

        @keyframes ripple-long-press-animation {
            0% {
                transform: scale(0);
                opacity: 0.8;
            }
            50% {
                transform: scale(2);
                opacity: 0.6;
            }
            100% {
                transform: scale(4);
                opacity: 0;
            }
        }

        /* 基础按钮样式 */
        .btn {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding: 12px 24px;
            margin: 10px;
            border: none;
            border-radius: 8px;
            background: #2196f3;
            color: white;
            font-size: 16px;
            font-weight: 500;
            transition: all 0.3s ease;
            position: relative;
            min-width: 120px;
            min-height: 48px;
        }

        .btn:hover {
            background: #1976d2;
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(33, 150, 243, 0.4);
        }

        .btn:active {
            transform: translateY(0);
        }

        /* 图标按钮样式 */
        .btn-with-icon {
            padding-left: 16px;
            padding-right: 24px;
            justify-content: flex-start;
            gap: 12px;
        }

        .btn-icon {
            font-size: 18px;
            z-index: 2;
            position: relative;
            flex-shrink: 0;
            width: 20px;
            text-align: center;
        }

        .btn-text {
            z-index: 2;
            position: relative;
        }

        /* 不同颜色的按钮 */
        .btn-success {
            background: #4caf50;
        }

        .btn-success:hover {
            background: #388e3c;
            box-shadow: 0 4px 12px rgba(76, 175, 80, 0.4);
        }

        .btn-warning {
            background: #ff9800;
        }

        .btn-warning:hover {
            background: #f57c00;
            box-shadow: 0 4px 12px rgba(255, 152, 0, 0.4);
        }

        .btn-danger {
            background: #f44336;
        }

        .btn-danger:hover {
            background: #d32f2f;
            box-shadow: 0 4px 12px rgba(244, 67, 54, 0.4);
        }

        .btn-secondary {
            background: #6c757d;
        }

        .btn-secondary:hover {
            background: #545b62;
            box-shadow: 0 4px 12px rgba(108, 117, 125, 0.4);
        }

        /* 圆形按钮 */
        .btn-circle {
            width: 56px;
            height: 56px;
            border-radius: 50%;
            padding: 0;
            min-width: auto;
            font-size: 24px;
        }

        /* 卡片样式 */
        .card {
            background: #fff;
            border-radius: 12px;
            padding: 20px;
            margin: 10px 0;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            transition: all 0.3s ease;
        }

        .card:hover {
            transform: translateY(-4px);
            box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
        }

        /* 长按提示 */
        .long-press-tooltip {
            position: absolute;
            top: -40px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 8px 12px;
            border-radius: 4px;
            font-size: 12px;
            white-space: nowrap;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.3s ease;
            z-index: 10;
        }

        .long-press-tooltip::after {
            content: '';
            position: absolute;
            top: 100%;
            left: 50%;
            transform: translateX(-50%);
            border: 4px solid transparent;
            border-top-color: rgba(0, 0, 0, 0.8);
        }

        .long-press-tooltip.show {
            opacity: 1;
        }

        /* 进度指示器 */
        .progress-indicator {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 4px;
            background: rgba(255, 255, 255, 0.3);
            border-radius: 2px;
            overflow: hidden;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .progress-bar {
            height: 100%;
            background: rgba(255, 255, 255, 0.8);
            width: 0%;
            transition: width linear;
            border-radius: 2px;
        }

        .progress-indicator.show {
            opacity: 1;
        }

        /* 列表项样式 */
        .list-item {
            display: flex;
            align-items: center;
            padding: 16px 20px;
            margin: 2px 0;
            background: #fff;
            border-radius: 8px;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }

        .list-item:hover {
            background: #f5f5f5;
        }

        .list-icon {
            margin-right: 16px;
            font-size: 20px;
            width: 24px;
            text-align: center;
            color: #666;
            z-index: 2;
            position: relative;
        }

        .list-content {
            flex: 1;
            z-index: 2;
            position: relative;
        }

        .list-title {
            font-weight: 500;
            margin-bottom: 4px;
        }

        .list-subtitle {
            font-size: 14px;
            color: #666;
        }

        /* 输入框水波纹 */
        .input-container {
            position: relative;
            margin: 15px 0;
        }

        .input-field {
            width: 100%;
            padding: 16px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
            background: #fff;
            transition: border-color 0.3s ease;
            outline: none;
        }

        .input-field:focus {
            border-color: #2196f3;
        }

        /* 开关样式 */
        .switch-container {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 16px 0;
            margin: 10px 0;
        }

        .switch {
            position: relative;
            width: 52px;
            height: 32px;
            background: #ccc;
            border-radius: 16px;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }

        .switch.active {
            background: #2196f3;
        }

        .switch-thumb {
            position: absolute;
            top: 2px;
            left: 2px;
            width: 28px;
            height: 28px;
            background: white;
            border-radius: 50%;
            transition: transform 0.3s ease;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        }

        .switch.active .switch-thumb {
            transform: translateX(20px);
        }

        /* 演示说明 */
        .demo-info {
            background: #e3f2fd;
            border-left: 4px solid #2196f3;
            padding: 15px;
            margin: 20px 0;
            border-radius: 4px;
            font-size: 14px;
            color: #1565c0;
        }

        /* 响应式设计 */
        @media (max-width: 768px) {
            .demo-container {
                grid-template-columns: 1fr;
                gap: 20px;
            }
            
            .header h1 {
                font-size: 2em;
            }
            
            .demo-section {
                padding: 20px;
            }
        }

        /* 自定义水波纹颜色 */
        .ripple-blue {
            background: rgba(33, 150, 243, 0.6);
        }

        .ripple-green {
            background: rgba(76, 175, 80, 0.6);
        }

        .ripple-orange {
            background: rgba(255, 152, 0, 0.6);
        }

        .ripple-red {
            background: rgba(244, 67, 54, 0.6);
        }

        .ripple-dark {
            background: rgba(0, 0, 0, 0.2);
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>🌊 Material 水波纹动画效果</h1>
        <p>模拟 Material Design Ripple 效果,支持点击、长按和图标按钮</p>
    </div>

    <div class="demo-container">
        <!-- 基础按钮演示 -->
        <div class="demo-section">
            <div class="section-title">🎯 基础水波纹按钮</div>
            <div class="demo-info">
                点击按钮查看水波纹效果,支持多种颜色主题
            </div>
            
            <button class="btn ripple-container" data-ripple-color="white">
                默认按钮
            </button>
            
            <button class="btn btn-success ripple-container" data-ripple-color="white">
                成功按钮
            </button>
            
            <button class="btn btn-warning ripple-container" data-ripple-color="white">
                警告按钮
            </button>
            
            <button class="btn btn-danger ripple-container" data-ripple-color="white">
                危险按钮
            </button>
        </div>

        <!-- 图标按钮演示 -->
        <div class="demo-section">
            <div class="section-title">🔘 图标按钮水波纹</div>
            <div class="demo-info">
                水波纹不会遮挡左侧图标,保持图标清晰可见
            </div>
            
            <button class="btn btn-with-icon ripple-container" data-ripple-color="white">
                <span class="btn-icon">📁</span>
                <span class="btn-text">打开文件</span>
            </button>
            
            <button class="btn btn-success btn-with-icon ripple-container" data-ripple-color="white">
                <span class="btn-icon">💾</span>
                <span class="btn-text">保存文档</span>
            </button>
            
            <button class="btn btn-warning btn-with-icon ripple-container" data-ripple-color="white">
                <span class="btn-icon">⚙️</span>
                <span class="btn-text">设置选项</span>
            </button>
            
            <button class="btn btn-danger btn-with-icon ripple-container" data-ripple-color="white">
                <span class="btn-icon">🗑️</span>
                <span class="btn-text">删除文件</span>
            </button>
        </div>

        <!-- 长按按钮演示 -->
        <div class="demo-section">
            <div class="section-title">👆 长按水波纹效果</div>
            <div class="demo-info">
                长按按钮1秒以上触发特殊水波纹效果和提示文字
            </div>
            
            <button class="btn ripple-container long-press-btn" 
                    data-ripple-color="white" 
                    data-long-press-text="长按已激活!">
                <span class="progress-indicator">
                    <div class="progress-bar"></div>
                </span>
                <span class="long-press-tooltip">继续长按激活</span>
                长按我试试
            </button>
            
            <button class="btn btn-success btn-with-icon ripple-container long-press-btn" 
                    data-ripple-color="white" 
                    data-long-press-text="下载已开始!">
                <span class="progress-indicator">
                    <div class="progress-bar"></div>
                </span>
                <span class="long-press-tooltip">长按开始下载</span>
                <span class="btn-icon">⬇️</span>
                <span class="btn-text">长按下载</span>
            </button>
            
            <button class="btn btn-danger btn-with-icon ripple-container long-press-btn" 
                    data-ripple-color="white" 
                    data-long-press-text="删除已确认!">
                <span class="progress-indicator">
                    <div class="progress-bar"></div>
                </span>
                <span class="long-press-tooltip">长按确认删除</span>
                <span class="btn-icon">⚠️</span>
                <span class="btn-text">长按删除</span>
            </button>
        </div>

        <!-- 圆形按钮演示 -->
        <div class="demo-section">
            <div class="section-title">⭕ 圆形浮动按钮</div>
            <div class="demo-info">
                经典的Material Design圆形浮动按钮 (FAB)
            </div>
            
            <button class="btn btn-circle ripple-container" data-ripple-color="white">
                ➕
            </button>
            
            <button class="btn btn-success btn-circle ripple-container" data-ripple-color="white">
                ✓
            </button>
            
            <button class="btn btn-warning btn-circle ripple-container" data-ripple-color="white">
                ⚡
            </button>
            
            <button class="btn btn-danger btn-circle ripple-container" data-ripple-color="white">
                ❌
            </button>
        </div>

        <!-- 卡片和列表演示 -->
        <div class="demo-section">
            <div class="section-title">📋 交互式列表</div>
            <div class="demo-info">
                列表项支持水波纹效果,图标不会被遮挡
            </div>
            
            <div class="card">
                <div class="list-item ripple-container" data-ripple-color="dark">
                    <div class="list-icon">📧</div>
                    <div class="list-content">
                        <div class="list-title">新邮件通知</div>
                        <div class="list-subtitle">您有3封未读邮件</div>
                    </div>
                </div>
                
                <div class="list-item ripple-container" data-ripple-color="dark">
                    <div class="list-icon">🔔</div>
                    <div class="list-content">
                        <div class="list-title">系统通知</div>
                        <div class="list-subtitle">软件更新可用</div>
                    </div>
                </div>
                
                <div class="list-item ripple-container" data-ripple-color="dark">
                    <div class="list-icon">👤</div>
                    <div class="list-content">
                        <div class="list-title">用户设置</div>
                        <div class="list-subtitle">管理您的个人资料</div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 输入框和开关演示 -->
        <div class="demo-section">
            <div class="section-title">🎛️ 交互控件</div>
            <div class="demo-info">
                输入框和开关也支持水波纹反馈效果
            </div>
            
            <div class="input-container">
                <input type="text" class="input-field ripple-container" placeholder="点击输入框查看效果" data-ripple-color="blue">
            </div>
            
            <div class="switch-container">
                <span>启用通知</span>
                <div class="switch ripple-container" data-ripple-color="blue">
                    <div class="switch-thumb"></div>
                </div>
            </div>
            
            <div class="switch-container">
                <span>深色模式</span>
                <div class="switch ripple-container" data-ripple-color="blue">
                    <div class="switch-thumb"></div>
                </div>
            </div>
        </div>
    </div>

    <script>
        class MaterialRipple {
            constructor() {
                this.longPressTimer = null;
                this.longPressDelay = 1000; // 长按延迟时间
                this.init();
            }

            init() {
                // 为所有水波纹容器添加事件监听
                document.addEventListener('click', this.handleClick.bind(this));
                document.addEventListener('mousedown', this.handleMouseDown.bind(this));
                document.addEventListener('mouseup', this.handleMouseUp.bind(this));
                document.addEventListener('mouseleave', this.handleMouseLeave.bind(this));
                
                // 触摸事件支持
                document.addEventListener('touchstart', this.handleTouchStart.bind(this));
                document.addEventListener('touchend', this.handleTouchEnd.bind(this));
                document.addEventListener('touchcancel', this.handleTouchCancel.bind(this));

                // 开关特殊处理
                this.initSwitches();
            }

            // 处理点击事件
            handleClick(e) {
                const container = e.target.closest('.ripple-container');
                if (!container) return;

                // 开关特殊处理
                if (container.classList.contains('switch')) {
                    this.toggleSwitch(container);
                }

                this.createRipple(e, container);
            }

            // 处理鼠标按下
            handleMouseDown(e) {
                const container = e.target.closest('.long-press-btn');
                if (!container) return;

                this.startLongPress(e, container);
            }

            // 处理鼠标释放
            handleMouseUp(e) {
                this.endLongPress();
            }

            // 处理鼠标离开
            handleMouseLeave(e) {
                this.endLongPress();
            }

            // 处理触摸开始
            handleTouchStart(e) {
                const container = e.target.closest('.long-press-btn');
                if (!container) return;

                // 创建模拟的鼠标事件对象
                const touch = e.touches[0];
                const mouseEvent = {
                    clientX: touch.clientX,
                    clientY: touch.clientY,
                    target: e.target
                };

                this.startLongPress(mouseEvent, container);
            }

            // 处理触摸结束
            handleTouchEnd(e) {
                this.endLongPress();
            }

            // 处理触摸取消
            handleTouchCancel(e) {
                this.endLongPress();
            }

            // 创建水波纹效果
            createRipple(e, container, isLongPress = false) {
                const rect = container.getBoundingClientRect();
                const size = Math.max(rect.width, rect.height);
                const x = e.clientX - rect.left - size / 2;
                const y = e.clientY - rect.top - size / 2;

                const ripple = document.createElement('div');
                ripple.className = isLongPress ? 'ripple-long-press' : 'ripple';
                
                // 设置水波纹颜色
                const rippleColor = container.dataset.rippleColor;
                if (rippleColor) {
                    ripple.classList.add(`ripple-${rippleColor}`);
                }

                ripple.style.width = ripple.style.height = size + 'px';
                ripple.style.left = x + 'px';
                ripple.style.top = y + 'px';

                // 如果是图标按钮,确保水波纹不遮挡图标
                if (container.classList.contains('btn-with-icon')) {
                    const icon = container.querySelector('.btn-icon');
                    if (icon) {
                        const iconRect = icon.getBoundingClientRect();
                        const containerRect = container.getBoundingClientRect();
                        const iconRelativeX = iconRect.left - containerRect.left;
                        const iconRelativeY = iconRect.top - containerRect.top;
                        
                        // 调整水波纹起始位置,避开图标区域
                        if (e.clientX - rect.left < iconRelativeX + iconRect.width + 10) {
                            ripple.style.left = (iconRelativeX + iconRect.width + 5) + 'px';
                        }
                    }
                }

                container.appendChild(ripple);

                // 动画完成后移除水波纹元素
                setTimeout(() => {
                    if (ripple.parentNode) {
                        ripple.parentNode.removeChild(ripple);
                    }
                }, isLongPress ? 2000 : 600);
            }

            // 开始长按检测
            startLongPress(e, container) {
                const tooltip = container.querySelector('.long-press-tooltip');
                const progressIndicator = container.querySelector('.progress-indicator');
                const progressBar = container.querySelector('.progress-bar');

                // 显示提示和进度条
                if (tooltip) tooltip.classList.add('show');
                if (progressIndicator) progressIndicator.classList.add('show');

                // 重置进度条
                if (progressBar) {
                    progressBar.style.transition = `width ${this.longPressDelay}ms linear`;
                    progressBar.style.width = '100%';
                }

                this.longPressTimer = setTimeout(() => {
                    this.triggerLongPress(e, container);
                }, this.longPressDelay);
            }

            // 结束长按检测
            endLongPress() {
                if (this.longPressTimer) {
                    clearTimeout(this.longPressTimer);
                    this.longPressTimer = null;
                }

                // 隐藏所有长按相关元素
                document.querySelectorAll('.long-press-tooltip.show').forEach(tooltip => {
                    tooltip.classList.remove('show');
                });

                document.querySelectorAll('.progress-indicator.show').forEach(indicator => {
                    indicator.classList.remove('show');
                    const progressBar = indicator.querySelector('.progress-bar');
                    if (progressBar) {
                        progressBar.style.transition = 'width 0.3s ease';
                        progressBar.style.width = '0%';
                    }
                });
            }

            // 触发长按事件
            triggerLongPress(e, container) {
                // 创建长按水波纹
                this.createRipple(e, container, true);

                // 显示长按文字提示
                const longPressText = container.dataset.longPressText;
                if (longPressText) {
                    this.showToast(longPressText);
                }

                // 隐藏提示元素
                this.endLongPress();

                // 触发自定义长按事件
                const longPressEvent = new CustomEvent('longpress', {
                    detail: { element: container, originalEvent: e }
                });
                container.dispatchEvent(longPressEvent);
            }

            // 初始化开关
            initSwitches() {
                document.querySelectorAll('.switch').forEach(switchEl => {
                    switchEl.addEventListener('longpress', (e) => {
                        console.log('开关长按事件触发');
                    });
                });
            }

            // 切换开关状态
            toggleSwitch(switchEl) {
                switchEl.classList.toggle('active');
            }

            // 显示消息提示
            showToast(message) {
                // 移除已存在的提示
                const existingToast = document.querySelector('.toast');
                if (existingToast) {
                    existingToast.remove();
                }

                const toast = document.createElement('div');
                toast.className = 'toast';
                toast.textContent = message;
                toast.style.cssText = `
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    background: rgba(0, 0, 0, 0.8);
                    color: white;
                    padding: 15px 20px;
                    border-radius: 8px;
                    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
                    transform: translateX(400px);
                    transition: transform 0.3s ease;
                    z-index: 10000;
                    font-size: 14px;
                    max-width: 300px;
                `;

                document.body.appendChild(toast);

                // 显示动画
                setTimeout(() => {
                    toast.style.transform = 'translateX(0)';
                }, 100);

                // 自动隐藏
                setTimeout(() => {
                    toast.style.transform = 'translateX(400px)';
                    setTimeout(() => {
                        if (toast.parentNode) {
                            toast.parentNode.removeChild(toast);
                        }
                    }, 300);
                }, 3000);
            }
        }

        // 自定义事件监听示例
        document.addEventListener('longpress', (e) => {
            console.log('长按事件触发:', e.detail.element);
            
            // 可以根据不同按钮执行不同操作
            const element = e.detail.element;
            if (element.textContent.includes('下载')) {
                console.log('开始下载文件...');
            } else if (element.textContent.includes('删除')) {
                console.log('确认删除操作...');
            }
        });

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', () => {
            new MaterialRipple();
            
            // 添加一些演示交互
            document.querySelectorAll('.list-item').forEach(item => {
                item.addEventListener('click', () => {
                    const title = item.querySelector('.list-title').textContent;
                    console.log(`点击了列表项: ${title}`);
                });
            });

            // 输入框聚焦效果
            document.querySelectorAll('.input-field').forEach(input => {
                input.addEventListener('focus', () => {
                    input.parentElement.style.transform = 'scale(1.02)';
                });
                
                input.addEventListener('blur', () => {
                    input.parentElement.style.transform = 'scale(1)';
                });
            });
        });

        // 键盘快捷键支持
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' && e.target.classList.contains('ripple-container')) {
                // 模拟点击事件
                const clickEvent = new MouseEvent('click', {
                    clientX: e.target.offsetLeft + e.target.offsetWidth / 2,
                    clientY: e.target.offsetTop + e.target.offsetHeight / 2,
                    bubbles: true
                });
                e.target.dispatchEvent(clickEvent);
            }
        });
    </script>
</body>
</html> 
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。