环形轮盘数组索引异常:顺时针旋转无法正确获取索引
解决环形轮盘顺时针旋转时的索引异常问题
我仔细看了你的代码和问题描述,发现核心问题出在旋转方向的判断逻辑错误,以及startPoint和endPoint的维护逻辑搞反了,导致索引获取异常。比如你提到的点击第8个元素后再点击第7个的场景,程序错误地执行了顺时针逻辑,而非预期的逆时针逻辑,自然无法正确加载目标元素。
先给你梳理下关键错误点:
- 原代码里判断顺时针/逆时针的逻辑完全颠倒,依赖
degrees > ($('.circle').data('deg') || 0)这个条件根本不符合实际操作场景; - 你定义的是“顺时针从数组尾部取值、逆时针从下一个索引取值”,但原代码里顺时针操作时改了
startPoint,逆时针时改了endPoint,完全搞反了维护对象; getItemsFromBack函数的取数逻辑有漏洞,跨数组循环取数时顺序会出错。
下面是修正后的完整代码,我标注了关键修改的地方:
var numberOfElement = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]; var initialRender = numberOfElement.slice(0, 11); var startPoint = initialRender.length; // 初始下一个逆时针取数的索引:11(对应元素12) var endPoint = numberOfElement.length; // 初始下一个顺时针取数的尾部位置:30(数组长度) function generateHtml() { var html = ''; initialRender.forEach(function(item, index) { var angle = 18 * (index); var className = angle === 90 ? 'active' : ''; html += '<div class="shapes ' + className + '" data-deg="' + angle + '" style="--deg:' + angle + 'deg;"> <span class="set-pos">' + (item) + '</span> <span> ' + angle + ' deg </span></div>'; }) document.querySelector('#dynamic-html').innerHTML = html; } generateHtml(); $('#dynamic-html').on('click', '.shapes', function() { var deg = 90; var activeDeg = $('.active').data('deg'); var selectedElementDeg = $(this).data('deg'); var diff = Math.abs((activeDeg - selectedElementDeg) / 18); $('.shapes').removeClass('active'); $(this).addClass('active'); var degrees = deg - selectedElementDeg; $('.circle').css({ 'transform': 'rotate(' + degrees + 'deg)' }).attr('data-deg', degrees); // 🔧 关键修改1:修正旋转方向判断逻辑 // 点击元素角度 > 激活元素角度 → 顺时针旋转(从数组尾部取数) // 点击元素角度 < 激活元素角度 → 逆时针旋转(从startPoint取数) var isClockWise = selectedElementDeg > activeDeg; if (isClockWise) { // 顺时针逻辑:移除右侧diff个元素,添加左侧新元素 var itemLength = $('.shapes').length; $('.shapes:gt(' + ((itemLength - 1) - diff) + ')').remove(); var newItems = generateItem(getItemsFromBack(diff), true); newItems = $(newItems).get().reverse(); $('#dynamic-html').prepend(newItems); // 🔧 关键修改2:顺时针操作维护endPoint,而非startPoint endPoint -= diff; if (endPoint < 0) { endPoint += numberOfElement.length; } } else { // 逆时针逻辑:移除左侧diff个元素,添加右侧新元素 var newItems = generateItem(getItemFromStart(diff), false); $('#dynamic-html').append(newItems); $('.shapes:lt(' + (diff) + ')').remove(); // 🔧 关键修改3:逆时针操作维护startPoint,而非endPoint startPoint += diff; if (startPoint >= numberOfElement.length) { startPoint -= numberOfElement.length; } } }) // 🔧 关键修改4:修正从数组尾部取数的逻辑,处理循环场景 function getItemsFromBack(length) { var values = []; const total = numberOfElement.length; let start = endPoint - length; if (start < 0) { // 跨数组末尾时,先取从start到数组末尾的部分,再取开头的部分 values = numberOfElement.slice(start).concat(numberOfElement.slice(0, -start)); } else { // 正常情况取start到endPoint的元素 values = numberOfElement.slice(start, endPoint); } // 反转保证元素顺序符合轮盘添加需求 return values.reverse(); } // 🔧 关键修改5:修正从startPoint取数的逻辑,简化循环处理 function getItemFromStart(length) { var values = []; const total = numberOfElement.length; let remaining = length; let currentStart = startPoint; while (remaining > 0) { const take = Math.min(remaining, total - currentStart); values = values.concat(numberOfElement.slice(currentStart, currentStart + take)); remaining -= take; currentStart = 0; // 取完当前段后回到数组开头 } // 更新startPoint,自动循环到数组开头 startPoint = (startPoint + length) % total; return values; } function generateItem(items, isClockWise) { var html = "", lastItemAngle; if (isClockWise) { lastItemAngle = $('#dynamic-html .shapes:first').data('deg'); } else { lastItemAngle = $('#dynamic-html .shapes:last').data('deg'); } items.forEach(function(item, index) { if (isClockWise) { var angles = lastItemAngle - (18 * (index + 1)) } else { var angles = lastItemAngle + (18 * (index + 1)) } html += '<div class="shapes" data-deg="' + (angles) + '" style="--deg:' + angles + 'deg;"> <span class="set-pos">' + (item) + '</span> <span> ' + angles + ' deg </span></div>'; }); return html; }
现在测试你说的场景:点击第8个元素(角度126deg,对应元素8)后,再点击第7个元素(角度108deg,对应元素7),此时程序会判断为逆时针旋转,从startPoint取对应数量的元素(初始是元素12),添加到轮盘右侧,同时移除左侧的元素。当startPoint走到数组末尾后,会自动回到0开始取元素1、2,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Jitender
相关产品推荐
相关产品推荐

