JS数组指针prev、current、next的实现方式,涉及是否删除当前元素的情况分析
背景
由于业务,需要做一个循环切换的轮播图效果,循环展示列表中的每个item,但是由于切换(从左往右移动,遇到末尾则跳到开头)的过程中可能会删掉当前元素,所以需要更新下标后再切换。由于涉及到几个临界条件,这里列出来处理方式,以便后续参考。
情况分析
一共有两大类:保留
(不删除当前元素,直接更新指针),不保留
(删除这个元素,更新list,然后根据规则进行更新指针)
1. 不保留当前项
splice后,数组长度更新了,有以下的情况:
- 新列表长度为1:那么让
current
为0,prev
和next
为null即可。 - 新列表长度为2:
prev
指向1,current
设置为0,next
为null
。 - 新列表长度为3:
prev
为2,current
为0,next
为1。(这个不写也可以,按照第四种的情况进行处理也是这个结果) - 新列表长度大于3:
41. current位于list头部:current
不变仍为0
,prev
为list.length - 1
,如果next
的值与新的prev
一样,则next
为null
。
42. current位于list中间:current
和next
移动到下一位,prev
不变,如果新的next
和prev
一样,则next
为null
。
43. current位于list尾部:current
为list.length - 1
,prev
为原prev值 - 1
,如果next
的值和新的prev
一样,则next
为null
。
2. 保留当前项
数组长度没变化,那么有下面的情况:
- 列表长度为1:那么让
current
为0,prev
和next
为null即可。 - 列表长度为2:切换顺序,
prev
和current
对调,next
为null
。 - 列表长度大于2:
prev
: 变为原current
的值;current
: 变为原next
的值;next
:原next值 + 1
后是否触达数组末尾,若是则设为0
,不是则设为原next值 + 1
。
代码
这里给出的简化过后的代码:
<template> <el-switch v-model="isHold" label="保留"></el-switch> <el-button @click="handleIndexSwitch()">切换</el-button> </template> <script setup> import { ref, onMounted } from "vue"; import { getListApi } from "@/api/list"; const isHold = ref(false); // 页面里面有个开关,是否在切换后删除当前item const list = ref([]); const currentItem = ref(); const INDEX = ref({ prev: null, current: null, next: null, }); onMounted(() => { getList(); }); function getList() { getListApi().then((res) => { let result = res.data.data; // 初始化下标 switch (result.length) { case 1: INDEX.value = { prev: null, current: 0, next: null, }; break; case 2: INDEX.value = { prev: 1, current: 0, next: null, }; break; default: INDEX.value = { prev: result.length - 1, current: 0, next: 1, }; break; } list.value = result; currentItem.value = result[INDEX.value.current]; }); } /** * 处理请求列表的切换 (保留|不保留) */ function handleIndexSwitch() { if (!list.value.length) return; /** 不保留,则把当前的item删掉,然后重新计算prev、current和next的指针指向 */ if (!isHold.value) { // 删除当前项 list.value.splice(INDEX.value.current, 1); if (list.value.length === 0) { currentItem.value = null; getList(); return; } switch (list.value.length) { case 1: INDEX.value = { prev: null, current: 0, next: null, }; break; case 2: INDEX.value = { prev: 1, current: 0, next: null, }; break; case 3: INDEX.value = { prev: 2, current: 0, next: 1, }; break; default: if (INDEX.value.current === 0) { INDEX.value = { prev: list.value.length - 1, current: 0, next: 1, }; } else if (INDEX.value.current === list.value.length - 1) { INDEX.value = { prev: INDEX.value.prev - 1, current: list.value.length - 1, next: INDEX.value.prev, }; } else { INDEX.value = { prev: INDEX.value.prev, current: INDEX.value.next, next: INDEX.value.next + 1 === list.value.length ? 0 : INDEX.value.next + 1, }; } break; } } else { /** 保留,则切换下一个 */ switch (list.value.length) { case 1: INDEX.value = { prev: null, current: 0, next: null, }; break; case 2: /** 调换一下顺序? */ INDEX.value = { prev: INDEX.value.current, current: INDEX.value.prev, next: null, }; break; default: INDEX.value = { prev: INDEX.value.current, current: INDEX.value.next, next: INDEX.value.next + 1 === list.value.length ? 0 : INDEX.value.next + 1, }; break; } } currentItem.value = list.value[INDEX.value.current]; isHold.value = true; } </script>
« 上一篇: 修复控制台出现 Deprecation Warning: The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0 的问题
» 下一篇: 修复HTTPS升级后出现 Mixed Content: The page at 'https://xxx' was loaded over HTTPS, but requested an insecure frame 'http://xxx'. This request has been blocked; the content must be served over HTTPS. 的问题
» 下一篇: 修复HTTPS升级后出现 Mixed Content: The page at 'https://xxx' was loaded over HTTPS, but requested an insecure frame 'http://xxx'. This request has been blocked; the content must be served over HTTPS. 的问题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理