首页 > 解决方案 > 如果有人点击太快,如何防止不必要的点击?

问题描述

Menu item我有一个带有可移动面板的侧边栏 - 当您单击或时,您可以在片段中看到它们向左或向右移动Go back

问题是,如果您快速单击按钮(您可以通过快速多次单击按钮来重新创建问题),它有时会在同一面板上计算currentIndex++(或--)两次使其卡住,然后它会只需继续向translate同一个面板添加金额。

在我的示例中,只有 3 个宽度为 的面板40,因此它只能移动到 之间translate-x-0的某个位置-translate-x-120,但如果它被卡住,它只会继续向卡住的面板添加 40 的跳跃,所以你可以看到类似-translate-x-800如果你只是继续点击

const App = {
    data() {
        return {
                sidebarWidth: 40,
                currentIndex: 0,      
       }
    },
    computed: {
            position() {
                if (this.currentIndex === 0) {
            return 'translate-x-0'
        } else {
                  return `-translate-x-${this.sidebarWidth * this.currentIndex}`
        }
            }
        }
}

Vue.createApp(App).mount('#app')
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
    <div class="h-screen flex">
        <div class="flex container w-40 h-80 bg-black mx-auto my-auto text-black overflow-hidden">
            <div class="sidebar container flex transform duration-1000" :class="position">

                <div class="sidebar-menu flex-shrink-0 w-40 transform duration-1000 bg-gray-300">
                    <button @click="currentIndex++">Menu item</button>
                </div>

                <div class="sidebar-menu flex-shrink-0 w-40 bg-blue-300 transform duration-1000">
                    <div class="flex flex-col">
                        <button class="flex justify-start" @click="currentIndex--">
                        Go back
                        </button>

                        <button class="flex justify-start" @click="currentIndex++">
                        Menu item
                        </button>
                    </div>
                </div>

                <div class="sidebar-menu flex-shrink-0 w-40 transform duration-1000 bg-red-300">
                    <div class="flex flex-col">
                        <button class="flex justify-start" @click="currentIndex--">
                        Go back
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

标签: vue.jsvuejs3

解决方案


问题是索引增量/减量不受限制/截断,因此即使使用去抖动器也可能超过实际菜单数量。

通过查询组件中的元素来确定菜单计数.sidebar-menu,并防止索引超过这个最大值:

export default {
    mounted() {
        this.menuCount = this.$el.querySelectorAll('.sidebar-menu').length
    },
    methods: {
        nextIndex(delta) {
           this.currentIndex = (this.currentIndex + delta) % this.menuCount
        }
    }
}

然后将该方法绑定到click-handlers:

<button class="flex justify-start" @click="nextIndex(-1)">
  Go back
</button>
<button class="flex justify-start" @click="nextIndex(1)">
  Menu item
</button>

const App = {
    data() {
        return {
                sidebarWidth: 40,
                currentIndex: 0,
                menuCount: 0,
       }
    },
    computed: {
       position() {
           if (this.currentIndex === 0) {
               return 'translate-x-0'
           } else {
              return `-translate-x-${this.sidebarWidth * this.currentIndex}`
           }
       }
    },
    mounted() {
        this.menuCount = this.$el.querySelectorAll('.sidebar-menu').length
    },
    methods: {
        nextIndex(delta) {
           this.currentIndex = (this.currentIndex + delta) % this.menuCount
        }
    }
}

Vue.createApp(App).mount('#app')
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
    <div class="h-screen flex">
        <div class="flex container w-40 h-80 bg-black mx-auto my-auto text-black overflow-hidden">
            <div class="sidebar container flex transform duration-1000" :class="position">

                <div class="sidebar-menu flex-shrink-0 w-40 transform duration-1000 bg-gray-300">
                    <button @click="nextIndex(1)">Menu item</button>
                </div>

                <div class="sidebar-menu flex-shrink-0 w-40 bg-blue-300 transform duration-1000">
                    <div class="flex flex-col">
                        <button class="flex justify-start" @click="nextIndex(-1)">
                        Go back
                        </button>

                        <button class="flex justify-start" @click="nextIndex(1)">
                        Menu item
                        </button>
                    </div>
                </div>

                <div class="sidebar-menu flex-shrink-0 w-40 transform duration-1000 bg-red-300">
                    <div class="flex flex-col">
                        <button class="flex justify-start" @click="nextIndex(-1)">
                        Go back
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>


推荐阅读