JavaScript實現彈性導航效果

本文實例為大傢分享瞭JavaScript實現彈性導航效果的具體代碼,供大傢參考,具體內容如下

主要利用offsetX

1.先搭架子:

* {
      margin: 0;
      padding: 0;
        }
        
        .nav {
            width: 900px;
            height: 63px;
            background: url(images/doubleOne.png) no-repeat right center;
            border: 1px solid #ccc;
            margin: 100px auto;
            position: relative;
        }
        
        ul {
            position: relative;
            z-index: 999;
        }
        
        ul>li {
            list-style: none;
            float: left;
            width: 88px;
            height: 63px;
            line-height: 63px;
            text-align: center;
        }
        
        span {
            display: inline-block;
            width: 88px;
            height: 63px;
            background: url("images/tMall.png") no-repeat;
            position: absolute;
            left: 0;
            top: 0;
}
<div class="nav">
        <ul>
            <li>雙11狂歡</li>
            <li>服裝會場</li>
            <li>數碼傢電</li>
            <li>傢居建材</li>
            <li>母嬰童裝</li>
            <li>手機會場</li>
            <li>美妝會場</li>
            <li>進口會場</li>
            <li>飛豬旅行</li>
        </ul>
        <span></span>
</div>

2.編寫邏輯部分

//1.拿到需要操作的元素
const oItems = document.querySelectorAll("li");
 let oSpan = document.querySelector("span");
 
//2.監聽每個菜單的點擊事件
for (let i = 0; i < oItems.length; i++) {
            let item = oItems[i];
            item.onclick = function() {
                //offsetLeft 得到被點擊的元素距離第一個定位祖先元素的偏移位
                // console.log(this.offsetLeft);
                // oSpan.style.left = this.offsetLeft + 'px';
                //調用函數
                easeAnimation(oSpan, {
                    "left": this.offsetLeft
                });
            };
        }

animation.js

(function() {
    /**
     * 勻速動畫
     * @param {*} ele 執行動畫元素
     * @param {*} obj 該元素的哪些屬性需要執行動畫
     * @param {*} fn  動畫執行完成後可能還需要執行的操作
     * 
     * 調用方式參考
     * linearAnimation(oDiv, {
                "marginTop": 500,
                "marginLeft": 300
        });
     */
    function linearAnimation(ele, obj, fn) {
        clearInterval(ele.timerId);
        ele.timerId = setInterval(function() {
            // flag變量用於標記是否所有的屬性都執行完瞭動畫
            let flag = true;
 
            for (let key in obj) {
                let target = obj[key];
 
                // 1.拿到元素當前的位置
                // let begin = parseInt(ele.style.width) || 0;
                let style = getComputedStyle(ele);
                // let begin = parseInt(style.width) || 0;
                let begin = parseFloat(style[key]) || 0;
 
                // 2.定義變量記錄步長
                let step = (begin - target) > 0 ? -13 : 13;
 
                // 3.計算新的位置
                begin += step;
                // console.log(Math.abs(target - begin), Math.abs(step));
                if (Math.abs(target - begin) > Math.abs(step)) { //未執行完動畫
                    flag = false;
                } else { //執行完動畫
                    begin = target;
                }
 
                // 4.重新設置元素的位置
                // ele.style.width = begin + "px";
                ele.style[key] = begin + "px";
            }
 
            //判斷動畫是否執行完
            if (flag) {
                //動畫執行完後關閉定時器
                clearInterval(ele.timerId);
 
                //判斷是否傳入fn函數,有才執行反之不執行
                // if(fn){
                //     fn();
                // }
                fn && fn();
            }
        }, 100);
    }
 
    //緩動動畫
    function easeAnimation(ele, obj, fn) {
        clearInterval(ele.timerId);
        ele.timerId = setInterval(function() {
            // flag變量用於標記是否所有的屬性都執行完瞭動畫
            let flag = true;
 
            for (let key in obj) {
                let target = obj[key];
 
                // 1.拿到元素當前的位置
                let style = getComputedStyle(ele);
                let begin = parseInt(style[key]) || 0;
 
                // 2.定義變量記錄步長
                // 公式: (結束位置 - 開始位置) * 緩動系數(0 ~1)
                let step = (target - begin) * 0.3;
 
                // 3.計算新的位置
                begin += step;
                if (Math.abs(Math.floor(step)) > 1) {
                    flag = false;
                } else {
                    begin = target;
                }
                // 4.重新設置元素的位置
                ele.style[key] = begin + "px";
            }
 
            //判斷動畫是否執行完
            if (flag) {
                //動畫執行完後關閉定時器
                clearInterval(ele.timerId);
 
                //判斷是否傳入fn函數,有才執行反之不執行
                fn && fn();
            }
        }, 100);
    }
 
    // 將函數綁定到window對象上, 這樣全局就可以使用瞭
    window.linearAnimation = linearAnimation;
    window.easeAnimation = easeAnimation;
})();

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: