跳到主要內容

範例 - JavaScript 實作 Excel 頁籤移動元件

最近想調整之前做的在有限空間內的選單內容切換元件
參考的項目來源則是Excel的下方頁籤選擇器
Excel這類廣泛使用的軟體,設計都還滿值得參考的
一方面是Microsoft將它做得滿直覺的
另一方面則是一般大眾也被訓練到能接受它的操作流程

實作的成果如下:


點擊下一項時,選單容器會自動往右邊捲動一個不定長度的子元件的距離
長按著下一項按鈕不放,則會持續往右捲動到底

程式碼如下
var longPressAct;
function moveElements(container, direction) {
var childElements = container.children,
maxScrollLeft = container.scrollWidth - container.clientWidth,
currentScrollLeft = container.scrollLeft,
moveRight = direction === 'R';
//boarder line check
if (moveRight && currentScrollLeft === maxScrollLeft) return;
else if (!moveRight && currentScrollLeft === 0) return;
var accumulatedWidth = 0,
widthArray = [],
currentFrontTabIndex = 0;
for (var i = 0, max = childElements.length; i < max; i++) {
if(childElements[i].style.display==='none') continue;
accumulatedWidth += childElements[i].offsetWidth;
widthArray.push(accumulatedWidth);
if (currentScrollLeft >= accumulatedWidth) {
currentFrontTabIndex++;
}
}
var moveScale = 6;
var scrollRange, moveFunc, remainder;
if (moveRight) {
scrollRange = widthArray[currentFrontTabIndex] - (currentFrontTabIndex > 0 ? widthArray[currentFrontTabIndex-1] : 0);
remainder = scrollRange % moveScale;
moveFunc = function () {
if (scrollRange >= moveScale) {
scrollRange -= moveScale;
container.scrollLeft += moveScale;
requestAnimationFrame(moveFunc);
} else {
scrollRange -= remainder;
container.scrollLeft += remainder;
}
};
} else {
scrollRange = currentScrollLeft - (currentFrontTabIndex >= 2 ? widthArray[currentFrontTabIndex-2] : 0);
remainder = scrollRange % moveScale;
moveFunc = function () {
if(remainder!==0){
scrollRange -= remainder;
container.scrollLeft -= remainder;
remainder=0; //set remainder to zero to make the calculation easier.
requestAnimationFrame(moveFunc);
}
else if (scrollRange >= 0) {
scrollRange -= moveScale;
container.scrollLeft -= moveScale;
if (0 !== scrollRange){
requestAnimationFrame(moveFunc);
}
}
};
}
requestAnimationFrame(moveFunc);
longPressAct = setTimeout(function () {
moveElements(container, direction);
}, 150);
var mouseUpCtrl = function () {
clearTimeout(longPressAct);
window.removeEventListener('mouseup', mouseUpCtrl);
};
window.addEventListener('mouseup', mouseUpCtrl);
}
view raw TabMoving.js hosted with ❤ by GitHub


透過requestAnimationFrame避免動畫進行時碰到掉幀
這樣就是一段很流暢的移動效果了

留言