1. 程式人生 > >JavaScript製作元件特效及注意問題(個人整理筆記)

JavaScript製作元件特效及注意問題(個人整理筆記)

個人理解:所謂的動畫,就是利用定時器,把元素的屬性按某一規律變化的過程。 在函式內利用引數當css屬性時,style[attr] <==> style.arr,比如arr等於border。

注意問題

  • IE和其他瀏覽器的相容,IE的事件物件和其他瀏覽器的事件物件不同,IE為window.event,而其他瀏覽器的函式中預設有e的事件物件。
  • 把a標籤的href設定為javascript:void(0)實現不跳轉,也表示這個a標籤是為某種功能而採用的,不是為跳轉而設定的。
  • 凡是與滾動有關的或者某一東西跟著動的,大多數與滾動scoll系列有關,還用到offset系列、滑鼠的clientX、clientY等。
  • 凡是與動畫有關的,大多數與屬性的改變有關,比如width,height,top,left,透明度等等,而且是按某一規律(公式)。

參考

Bootstrap 參考https://v4.bootcss.com/

fullPage.js 參考http://www.dowebok.com/77.html

normalize.css 初始化CSS

html5shiv.min.js ie8及以下相容h5

專案特效及相容程式碼

相容程式碼

設定元素文字內容

/**
 * 設定元素的文字內容
 * @param element 任意元素
 * @param text 任意文字內容
 */
function setInnerText
(element, text) { if (typeof(element.textContent) == "undefined") { element.innerText = text; } else { element.textContent = text; } }

獲取元素文字內容

/**
 * 獲取元素的文字內容
 * @param element 任意元素
 * @returns {*} 任意元素中的文字內容
 */
function getInnerText(element) {
    if (typeof(element.textContent)
== "undefined") { return element.innerText; } else { return element.textContent; } }

為任意一個元素繫結事件

//為任意一個元素繫結事件:元素,事件型別,事件處理函式
function addEventListener(element,type,fn) {
    if(element.addEventListener){
        element.addEventListener(type,fn,false);
    }else if(element.attachEvent){ //IE支援
        element.attachEvent("on"+type,fn);
    }else{
        element["on"+type]=fn;
    }
}

為任意的一個元素解綁某個事件

//為任意的一個元素解綁某個事件:元素,事件型別,事件處理函式
function removeEventListener(element,type,fn) {
    if(element.removeEventListener){
        element.removeEventListener(type,fn,false);
    }else if(element.detachEvent){
        element.detachEvent("on"+type,fn);
    }else{
        element["on"+type]=null;
    }
}

獲取的是頁面向上或者向左捲曲出去的距離的值

/**
 * 獲取的是頁面向上或者向左捲曲出去的距離的值,返回的是物件
 * @returns {{top: (Number|number), left: (Number|number)}}
 */
function getScroll() {
    return {
        top: window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0,
        left: window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft||0
    };
}

獲取內部樣式表或外部樣式表屬性

/*
* element---任意的元素
* attr---屬性
* */
function getAttrValue(element,attr) {
    return element.currentStyle?element.currentStyle[attr] : window.getComputedStyle(element,null)[attr]||0;
}

動畫函式

/*
* 終極版本的動畫函式---有bug
* */
function animate(element,json,fn) {
    clearInterval(element.timeId);
    element.timeId=setInterval(function () {
        var flag=true;//假設都達到了目標
        for(var attr in json){
            if(attr=="opacity"){//判斷屬性是不是opacity
                var current= getAttrValue(element,attr)*100;
                //每次移動多少步
                var target=json[attr]*100;//直接賦值給一個變數,後面的程式碼都不用改
                var step=(target-current)/10;//(目標-當前)/10
                step=step>0?Math.ceil(step):Math.floor(step);
                current=current+step;
                element.style[attr]=current/100;
            }else if(attr=="zIndex"){//判斷屬性是不是zIndex
                element.style[attr]=json[attr];
            }else{//普通的屬性

                //獲取當前的位置----getAttrValue(element,attr)獲取的是字串型別
                var current= parseInt(getAttrValue(element,attr))||0;
                //每次移動多少步
                var target=json[attr];//直接賦值給一個變數,後面的程式碼都不用改
                var step=(target-current)/10;//(目標-當前)/10
                step=step>0?Math.ceil(step):Math.floor(step);
                current=current+step;
                element.style[attr]=current+"px";
            }
            if(current!=target){
                flag=false;//如果沒到目標結果就為false
            }
        }
        if(flag){//結果為true
            clearInterval(element.timeId);
            if(fn){//如果使用者傳入了回撥的函式
                fn(); //就直接的呼叫,
            }
        }
        console.log("target:"+target+"current:"+current+"step:"+step);
    },10);
}

clientX、clientY和pageX、pageY及事件物件

    //window.event和事件引數物件e的相容
    //clientX和clientY單獨的使用的相容程式碼
    //scrollLeft和scrollTop的相容程式碼
    //pageX,pageY和clientX+scrollLeft 和clientY+scrollTop
    //把程式碼封裝在一個函式
    //把程式碼放在一個物件中
    var evt = {
        //window.event和事件引數物件e的相容
        getEvent: function (evt) {
            return window.event || evt;
        },
        //可視區域的橫座標的相容程式碼
        getClientX: function (evt) {
            return this.getEvent(evt).clientX;
        },
        //可視區域的縱座標的相容程式碼
        getClientY: function (evt) {
            return this.getEvent(evt).clientY;
        },
        //頁面向左捲曲出去的橫座標
        getScrollLeft: function () {
            return window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft || 0;
        },
        //頁面向上捲曲出去的縱座標
        getScrollTop: function () {
            return window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0;
        },
        //相對於頁面的橫座標(pageX或者是clientX+scrollLeft)
        getPageX: function (evt) {
            return this.getEvent(evt).pageX ? this.getEvent(evt).pageX : this.getClientX(evt) + this.getScrollLeft();
        },
        //相對於頁面的縱座標(pageY或者是clientY+scrollTop)
        getPageY: function (evt) {
            return this.getEvent(evt).pageY ? this.getEvent(evt).pageY : this.getClientY(evt) + this.getScrollTop();
        }
    };

無縫輪播圖

  1. 利用li橫排佈局圖片,overflow設定為hidden。
  2. 首尾圖片一樣。
  3. 當移到最後一張圖片時立即跳回第一張。if判斷距離(即寬度)
  4. 輪播ul設為絕對定位,利用ul的left進行移動,看像是圖片移動的效果。
  5. 輪播圖一排的圓點用ul-li做,用排他功能做特效,先全部取消特效,再特定一個給特效。
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            list-style: none;

        }
        img {
            vertical-align: top;
        }
        /*取消圖片底部3畫素距離*/
        .box {
            width: 300px;
            height: 200px;
            margin: 100px auto;
            background-color: pink;
            border: 1px solid red;
            position: relative;
            overflow: hidden;
        }
        .box ul li {
            float: left;
        }
        .box ul {
            width: 1500px;
            position: absolute;
            left: 0;
            top: 0;
        }
    </style>
</head>
<body>
<div class="box" id="screen">
    <ul>
        <li><img src="../images/01.jpg" alt=""/></li>
        <li><img src="../images/02.jpg" alt=""/></li>
        <li><img src="../images/03.jpg" alt=""/></li>
        <li><img src="../images/04.jpg" alt=""/></li>
        <li><img src="../images/01.jpg" alt=""/></li>
    </ul>
</div>
<script>
    var current = 0;//只聲明瞭一次
    function f1() {
        var ulObj = document.getElementById("screen").children[0];
        current -= 10;
        //重點程式碼
        if (current < -1200) {
            ulObj.style.left = 0 + "px";
            current = 0;
        } else {
            ulObj.style.left = current + "px";
        }
    }
    var timeId = setInterval(f1, 20);
    document.getElementById("screen").onmouseover = function () {
        //停止
        clearInterval(timeId);
    };
    document.getElementById("screen").onmouseout = function () {
        //繼續
        timeId = setInterval(f1, 20);
    };
</script>
</body>
</html>

百度搜索輔助

  1. 利用onkeyup事件
  2. 用string物件的.indexof判斷符合內容放入另一個數組。
  3. 根據陣列來判斷是否需建立div,以及新增子節點。
  4. 建立div前判斷是否之前就有div,有就先移出再建。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 450px;
            margin: 200px auto;
        }
        #txt {
            width: 350px;
        }
        #dv {
            overflow: hidden;
        }
        p {
            margin: 3px 5px;
            padding: 0;
            cursor: pointer;
        }
        p:hover {
            background-color: yellow;
        }
    </style>
</head>
<body>
<div id="box">
    <input type="text" id="txt"/>
    <input type="button" value="搜尋" id="btn"/>
</div>
<script>
    var keyWords = ["我很帥", "我真的很帥", "我真的非常帥", "我帥", "我帥帥帥"];
    var txt = document.getElementById("txt");
    txt.onkeyup = function (ev) {
        if (document.getElementById("dv")) {
            document.getElementById("box").removeChild(document.getElementById("dv"));
        }
        var text = this.value;//儲存輸入內容
        var tempArr = [];
        for (var i = 0; i < keyWords.length; i++) {
            if (keyWords[i].indexOf(text) == 0) {//判斷內容是否符合
                tempArr.push(keyWords[i]);
            }
        }
        //如果輸入內容為空或者符合的內容陣列長度為0,移除div
        if (this.value.length == 0 || tempArr.length == 0) {
            if (document.getElementById("dv")) {
                document.getElementById("box").removeChild(document.getElementById("dv"));
            }
        } else {
            if (!document.getElementById("dv")) {
                var divObj = document.createElement("div");
                document.getElementById("box").appendChild(divObj);
                divObj.id = "dv";
                divObj.style.width = "350px";
                divObj.style.border = "1px solid green";
            }

            for (var i = 0; i < tempArr.length; i++) {
                var pObj = document.createElement("p");
                document.getElementById("dv").appendChild(pObj);
                setInnerText(pObj, tempArr[i]);
            }
        }
    };
    //新增文字的相容程式碼
    function setInnerText(element, text) {
        if (typeof element.textContent == "undefined") {
            element.innerText = text;
        } else {
            element.textContent = text;
        }
    }
    //獲取文字的相容程式碼
    function getInnerText(element) {
        if (typeof element.textContent == "undefined") {
            return element.innerText;
        } else {
            return element.textContent;
        }
    }
</script>
</body>
</html>

固定導航欄案例

  1. 利用widow.onscroll事件。
  2. 利用scroll系列且相容程式碼獲取當導航欄剛到頂時,上面滾出去的距離x。
  3. 當滾動到一定距離後(實際>=x時),設定導航欄的定位position為absolute,且top為0,並把導航欄下面部分設定margin-Top防止跳上去。
  4. 當實際<