2020年8月24日 星期一

[JavaScript]試做簡單的無滾動條橫軸選單

     常常會在購物或新聞相關網站看到的橫軸選單,滑鼠按住左右滑動就可以往其他項目移動。最近心血來潮想說用原生的JavaScript來做做看類似的功能,實際上做起來還挺有趣的。

目前試著做出簡單類似效果如下:

說明:

 1.首先在HTML定義紅藍黃三個區塊當作選單項目,並且加上要拿來當作快速鍵的小圓紐

<div class="MenuBar">
    <ul>
        <div id="Menu" style="transform: translate(0px);">
            <li><span style="background-color: red;"></span></li>
            <li><span style="background-color: blue;"></span></li>
            <li><span style="background-color: yellow;"></span></li>
        </div>
    </ul>
    <ul id="PointBar" class="PointBar">
        <li><button style="background-color: red;" value="1"></button></li>
        <li><button value="2"></button></li>
        <li><button value="3"></button></li>
    </ul>
</div>

2.以下為CSS,主要來調整小圓紐外觀和將三個區塊改成一橫排並塞在沒有橫滾動條的小方框裡

<style type="text/CSS">
    .PointBar{
        text-align: center;
    }
    .PointBar>li{
        display: inline-block;
    }
    .PointBar>li>button{
        margin: 0px;
        padding: 0px;
        border-radius: 100%;
        width: 10px;
        height: 10px;
        
        border-style: none;
        background-color: gray;
    }
    
    .MenuBar{
        width:220px;
        overflow:hidden;
    }
    
    .MenuBar>ul{
        padding:0px;
    }
    .MenuBar>ul>div{
        position: relative;
        top:0px;
        left:0px;
        width: 670px;
        height: 120px;
        
        user-select: none;
    }
    .MenuBar>ul>div>li{
        padding:10px;
        display: inline-block;
    }
    .MenuBar>ul>div>li>span{
        display: inline-block;
        width:200px;
        height: 100px;
    }
</style>

3.利用JavaScrript去做監聽選單的點擊和移動事件來做出相對應的處理,並加上小圓鈕的點擊事件

<script type="text/JavaScript">
    var MObj = document.getElementById("Menu");
    //是否按下滑鼠
    let BUpDown = false;
    //按下位置
    let DownX = 0;
    //目前Bar偏移位置
    let NowMoveX = 0;
    
    //按下
    MObj.addEventListener("mousedown", e =>{
        BUpDown = true;
        DownX = e.screenX;
        //紀錄偏移位置
        NowMoveX = parseInt(MObj.style.transform.replace("translate(", "").replace("px)",""),10);
    })
    
    //放開
    window.addEventListener("mouseup", e =>{
        if(BUpDown){
            //紀錄偏移位置
            NowMoveX = parseInt(MObj.style.transform.replace("translate(", "").replace("px)",""),10);
        }
        BUpDown = false;
    })
    
    //移動
    MObj.addEventListener("mousemove", e =>{
        if (BUpDown === true) {
            let ToltalX = NowMoveX + e.screenX -DownX;
            //左邊界
            if (ToltalX > 0){ToltalX = 0;}
            //右邊界
            else if (ToltalX < MObj.offsetWidth *(-1) + MObj.children[0].offsetWidth + 10) ToltalX = MObj.offsetWidth *(-1) + MObj.children[0].offsetWidth +10;
            
            MObj.style.transform = "translate(" + ToltalX.toString() + "px)";
        }
    })
    
    //小圓鈕加入click監聽
    var liArray = document.getElementById("PointBar").children;
    for (let i=0; i<liArray.length; i++)
    {
        liArray[i].children[0].addEventListener("click", e=>{
            //按鈕變色事件
            for (let j=0; j<liArray.length; j++)
            {
                if (i == j)
                {
                    liArray[j].children[0].style.backgroundColor = "red";
                }
                else {
                    liArray[j].children[0].style.backgroundColor = "";
                }
            }
            
            //移動選單項目事件
            let X= MObj.children[0].offsetWidth*(parseInt(liArray[i].children[0].value, 10)-1)*(-1);
           
            //目標X值
            iTargetX = X;
            
            if (iTargetX > NowMoveX){bRight= false;}
            else{bRight=true;}
            
            //先停止
            clearInterval(iMoveSelect);
            //選單位移動畫
            iMoveSelect = setInterval(MoveSelect, 1);
        })
    }
    
    //移動函式
    //true: 向右; false: 向左

    var bRight = true;
    var iTargetX = 0;
    var iMoveSelect = 0;
    
    function MoveSelect()
    {
        //向右到定位後
        if (bRight &&  NowMoveX<= iTargetX)
        {
            MObj.style.transform = "translate(" + iTargetX.toString() + "px)";
            clearInterval(iMoveSelect);
        }
        //向左到定位後
        else if (!bRight &&  NowMoveX>= iTargetX)
        {
            MObj.style.transform = "translate(" + iTargetX.toString() + "px)";
            clearInterval(iMoveSelect);
        }
        else {
            if (bRight){
                NowMoveX -= 3;
            }
            else {
                NowMoveX += 3
            }
            //更新現在位置
            MObj.style.transform = "translate(" + NowMoveX.toString() + "px)";
        }
    }
</script>

成品如下:

沒有留言:

張貼留言