原生js實現一些功能

原生js實現功能

1.短信驗證(幾秒以後能夠再次發送)

function sendCode(){
        //設置秒數
    var timeNum = 5;
    this.disabled = true;
    var that = this;
    timer = setInterval(function(){
        timeNum--;
        that.value = timeNum + "秒後可再次發送";
        if (timeNum <= 0) {
            clearInterval(timer);
            that.disabled = false;
            btn.value = "點擊發送驗證碼";
        }
    }, 1000);
}
var btn = document.getElementById(("btn"));
btn.onclick = sendCode;

2.封裝緩動函數

var btn = document.getElementById("btn");
var demo = document.getElementById("demo");
btn.onclick = function () {
    animate(demo, {"zIndex": 5});
};

function animate(obj, json, fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        var flag = true;
        for (var k in json) {
            if (k === "opacity") {//單獨處理透明度
                //var leader = parseInt(getStyle(obj, k)) || 0;
                var leader = getStyle(obj, k) * 100;//透明度沒有單位的 也不用parseInt
                //不必給默認值 也不該該給
                var target = json[k] * 100;
                var step = (target - leader) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                leader = leader + step;
                obj.style[k] = leader / 100;
                //以前擴大100倍 如今縮小100倍數 透明度沒有單位
            } else if (k === "zIndex") {//層級也要特殊處理
                obj.style.zIndex = json[k];//層級不須要漸變 直接設置成目標值
            } else {
                var leader = parseInt(getStyle(obj, k)) || 0;
                var target = json[k];
                var step = (target - leader) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                leader = leader + step;
                obj.style[k] = leader + "px";
            }
            if (leader !== target) {
                flag = false;
            }
        }
        if (flag) {//最後任然是true 說明都到了
            clearInterval(obj.timer);//清理定時器
            if (fn) {//若是有才調用
                fn();//動畫執行完成後 會執行傳入的回調函數
            }
        }
    }, 15);
}

//封裝 獲取計算後樣式屬性的兼容函數 可以獲取任意對象的任意屬性
function getStyle(obj, attr) {
    if (window.getComputedStyle) {
        return window.getComputedStyle(obj, null)[attr];
    } else {
        return obj.currentStyle[attr];
    }
}

3.點擊回到網頁頂部

var backTop = document.getElementById("backTop");
    //需求:一開始小火箭不顯示 滾動一點以後再顯示 點擊小火箭 回調頂部
    //窗體滾動的時候 判斷scrollTop若是大於0就顯示小火箭 不然就隱藏
window.onscroll = function () {
    backTop.style.display = scroll().top > 0 ? "block" : "none";
};
//點擊火箭要回去
backTop.onclick = function () {
    //window.scrollTo(0, 0);
    //漸漸的滾回去
    var timer = setInterval(function () {
        var target = 0;
        var leader = scroll().top;
        var step = (target - leader) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        leader = leader + step;
        window.scrollTo(0, leader);
        if (leader === target) {
            clearInterval(timer);
        }
    }, 15);
};
//封裝計算頁面當前滾動的距離的函數
function scroll() {
    return {
        top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0,
        left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0
    };
}

4.響應式佈局原理

var timer = null;
responsive();
//onscroll onresize onmousemove事件 執行頻率很快
//若是要執行的是很是消耗資源的代碼 而且不必頻率那麼大 能夠進行節流
window.onresize = function () {
    //console.log(client().width);
    //responsive();
    clearTimeout(timer);
    timer = setTimeout(responsive, 500);
};

function responsive() {
    if (client().width > 960) {//電腦
        document.body.style.backgroundColor = "red";
        document.body.innerHTML = "computer";
    } else if (client().width > 640) {//平板
        document.body.style.backgroundColor = "green";
        document.body.innerHTML = "tablet";
    } else {
        document.body.style.backgroundColor = "yellow";
        document.body.innerHTML = "moblie";
    }
}

//封裝一個 可以獲取網頁可視區寬高的兼容函數
function client() {
    return {
        width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || 0,
        height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || 0
    };
}

5.整屏滑動(電梯導航)

var ul = document.getElementsByTagName("ul")[0];
var ulLis = ul.children;
var ol = document.getElementsByTagName("ol")[0];
var olLis = ol.children;
//調用函數
elevator(olLis,ulLis);
//封裝綁定導航事件函數
//navLis爲點擊元素的dom數組,viewLis爲顯示元素的dom數組
function elevator(navLis,viewLis){
    var timer = null; 
    //2.點擊ol中的li 讓窗口跑到 對應的ul中的li的位置
    for (var j = 0; j < navLis.length; j++) {
        navLis[j].index = j;
        navLis[j].onclick = function () {
            clearInterval(timer);
            //讓窗口跑到 對應的ul中的li的位置
            //目標 和點擊的ol中的li對應的ul中的li的offsetTop
            var target = viewLis[this.index].offsetTop;
            //window.scrollTo(0, target);
            timer = setInterval(function () {
                //step = (target-leader)/10
                //leader = leader + step
                var leader = scroll().top;//當前頁面被捲去的頭部
                var step = (target - leader) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                leader = leader + step;
                window.scrollTo(0, leader);
                if (leader === target) {
                    clearInterval(timer);
                }
            }, 15);
        };
    }
}

//封裝 能夠獲取任意瀏覽器中頁面滾動座標的兼容函數
function scroll() {
    return {
        top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0,
        left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0
    };
}

6.點擊鼠標跟隨(點擊鼠標,元素移到鼠標點擊位置)

var pic = document.getElementById("pic");
//鼠標點擊頁面 獲取點擊時的位置 讓精靈圖 漸漸地過來
document.onclick = function (event) {
    var event = event || window.event;
    //獲取點擊時在頁面上的位置
    var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
    var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
    //計算目標
    var targetX = pageX - pic.offsetWidth / 2;
    var targetY = pageY - pic.offsetHeight / 2;
    //讓精靈圖漸漸地過來
    animate(pic, {"left": targetX, "top": targetY});
};

7.放大鏡特效

//需求 鼠標通過盒子 顯示遮罩和大圖 鼠標移動的時候 讓遮罩跟着移動讓大圖按照比例移動
//找人
var box = document.getElementById("box");
var smallBox = document.getElementById("smallBox");
var bigBox = document.getElementById("bigBox");
var bigImg = document.getElementById("bigImg");
var mask = document.getElementById("mask");
//1.鼠標通過盒子 顯示遮罩和大圖 鼠標離開 隱藏
smallBox.onmouseover = function () {
    //顯示遮罩和大圖
    mask.style.display = "block";
    bigBox.style.display = "block";
};
smallBox.onmouseout = function () {
    //隱藏遮罩和大圖
    mask.style.display = "none";
    bigBox.style.display = "none";
};
//2.鼠標在盒子上移動的時候 讓遮罩跟着鼠標的座標走
smallBox.onmousemove = function (event) {
    var event = event || window.event;
    //鼠標在頁面中的座標
    var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
    var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
    //計算鼠標在盒子中的座標
    var boxX = pageX - box.offsetLeft;//這裏不能用smallBox由於由於他的父級box是有定位的
    var boxY = pageY - box.offsetTop;
    //計算遮罩的座標
    var maskX = boxX - mask.offsetWidth / 2;//減去自身寬度的一半
    var maskY = boxY - mask.offsetHeight / 2;//減去自身高度的一半
    //3.限定遮罩位置
    if (maskX < 0) {
        maskX = 0;
    }
    if (maskX > smallBox.offsetWidth - mask.offsetWidth) {
        maskX = smallBox.offsetWidth - mask.offsetWidth;
    }
    if (maskY < 0) {
        maskY = 0;
    }
    if (maskY > smallBox.offsetHeight - mask.offsetHeight) {
        maskY = smallBox.offsetHeight - mask.offsetHeight;
    }
    //讓遮罩跟着遮罩的座標走
    mask.style.left = maskX + "px";//記得加單位
    mask.style.top = maskY + "px";//記得加單位
    //4.按照比例移動大圖
    //大圖片當前的位置 = 大圖片可以移動的總距離/遮罩可以移動的總距離*遮罩當前的位置
    //大圖片可以移動的總距離 = 大圖的寬度-大盒子的寬度
    var bigImgToMove = bigImg.offsetWidth - bigBox.offsetWidth;
    //遮罩可以移動的總距離 = 小盒子的寬度-遮罩的寬度
    var maskToMove = smallBox.offsetWidth - mask.offsetWidth;
    //rate = 大圖片可以移動的總距離/遮罩可以移動的總距離
    var rate = bigImgToMove / maskToMove;
    //大圖片當前的位置 = rate*遮罩當前的位置
    bigImg.style.left = -rate * maskX + "px";//方向相反因此是負數
    bigImg.style.top = -rate * maskY + "px";//方向相反因此是負數
};

8.可拖拽特效

//需求:在drop上按下鼠標 窗口變爲可拖動的狀態 移動鼠標後d_box跟着鼠標走
//找人
var d_box = document.getElementById("d_box");//外層盒子
var drop = document.getElementById("drop");//拖動條
//給拖動條註冊鼠標按下事件 onmousedown 鼠標按下事件
drop.onmousedown = function (event) {
    var event = event || window.event;
    //鼠標在頁面中的位置
    var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
    var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
    //鼠標按下的一瞬間 鼠標在盒子中的位置
    var boxX = pageX - d_box.offsetLeft;
    var boxY = pageY - d_box.offsetTop;
    //讓d_box能夠跟着鼠標移動 也就是註冊鼠標移動事件
    document.onmousemove = function (event) {
        var event = event || window.event;
        //獲取鼠標在頁面上的座標
        var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
        var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
        //讓盒子跟着鼠標在頁面上的座標
        d_box.style.left = pageX - boxX + "px";
        d_box.style.top = pageY - boxY + "px";
        //清除選中文字
        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
    };
};
//鼠標彈起後 盒子就不能跟着了
document.onmouseup = function () {
    document.onmousemove = null;
};

9.滾動條特效

var box = document.getElementById("box");
var content = document.getElementById("content");
var bar = document.getElementById("bar");

//1.計算並設置滾動條的高度
//滾動條高度/窗口的高度 = 窗口的高度/內容的高度
//滾動條高度= 窗口的高度/內容的高度*窗口的高度
//若是content的高度大於box的高度 滾動條才須要設置高度
//若是content的高度小於box的高度 滾動條就不該該有高度
if (content.offsetHeight > box.offsetHeight) {
    bar.style.height = box.offsetHeight / content.offsetHeight * box.offsetHeight + "px";
} else {
    bar.style.height = 0;
}
//2.鼠標在bar上按下 讓bar能夠跟着鼠標的座標 鼠標移動的時候讓bar 跟着鼠標的座標
bar.onmousedown = function (event) {
    var event = event || window.event;
    //獲取鼠標在頁面中的座標
    var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
    //鼠標按下的一瞬間 獲取鼠標在bar中的位置
    var barBoxY = pageY - box.offsetTop - bar.offsetTop;
    document.onmousemove = function (event) {
        var event = event || window.event;
        //鼠標在頁面中的座標
        var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
        //鼠標在盒子中的座標
        var boxY = pageY - box.offsetTop;
        //bar應該到的座標
        var barY = boxY - barBoxY;
        //3.限制barY的運動範圍
        if (barY < 0) {//頂部不能出去
            barY = 0;
        }
        if (barY > box.offsetHeight - bar.offsetHeight) {//底部不能出去
            barY = box.offsetHeight - bar.offsetHeight;
        }
        //讓bar跟着鼠標在盒子中的的座標
        bar.style.top = barY + "px";
        //清空選中文字
        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
        //計算content要移動的距離
        //content要移動的距離/bar當前移動的距離 = content可以移動的總距離/bar可以移動的總距離
        //content要移動的距離 = content可以移動的總距離/bar可以移動的總距離*bar當前移動的距離
        //rate=content可以移動的總距離/bar可以移動的總距離
        var rate = (content.offsetHeight - box.offsetHeight) / (box.offsetHeight - bar.offsetHeight);
        //content要移動的距離 = rate*bar當前移動的距離 並且方向相反
        content.style.top = -rate * barY + "px";

    };
};

//在頁面彈起鼠標 bar就不能跟着了
document.onmouseup = function () {
    document.onmousemove = null;
};

10.登陸模態框

//點擊登陸按鈕 讓mask和show 顯示
//找人
var login = document.getElementById("login");
var mask = document.getElementById("mask");
var show = document.getElementById("show");
login.onclick = function (event) {
    mask.style.display = "block";
    show.style.display = "block";
    //阻止的是登陸按鈕的冒泡
    var event = event || window.event;
    if (event.stopPropagation) {
        event.stopPropagation();
    } else {
        event.cancelBubble = true;
    }
};
//點擊文檔中的任意位置(除了中間的show) 讓模態框小時
document.onclick = function (event) {
    var event = event || window.event;
    var target = event.target || event.srcElement;
    //若是點擊的不是show才應該消失
    if (target.id !== "show") {
        mask.style.display = "none";
        show.style.display = "none";
    }
};

11.選中顯示分享(本案例只顯示一個元素,分享須要導入第三方插件)

var test = document.getElementById("test");
var demo = document.getElementById("demo");
//需求:鼠標在test區域彈起 顯示demo 並且demo的位置是在鼠標的位置
test.onmouseup = function (event) {
    var event = event || window.event;
    //鼠標在頁面上的位置
    var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
    var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;

    //若是選中了文字 才讓demo出現
    var txt = window.getSelection ? window.getSelection().toString() : document.selection.createRange().text;
    if (txt) {//若是有選中的值才顯示
        //顯示demo
        demo.style.display = "block";
        //demo的位置是在鼠標的位置上的
        demo.style.left = pageX - 40 + "px";
        demo.style.top = pageY + 10 + "px";
    }
};
//在頁面上任何地方按下鼠標 就讓demo消失
document.onmousedown = function (event) {
    var event = event || window.event;
    var target = event.target || event.srcElement;
    if (target.id !== "demo") {
        //若是不是demo才消失
        demo.style.display = "none";
    }
};

12.瀑布流佈局

//由於未來要涉及到圖片的高度 因此即便寫在下面也要寫在onload裏面
window.onload = function () {
    var container = document.getElementById("container");
    var boxes = container.children;
    var pageWidth = document.documentElement.clientWidth;
    var boxWidth = boxes[0].offsetWidth;
    var column = Math.floor(pageWidth / boxWidth);
    console.log(column);
    var arrHeight = [];

    function waterfall() {
        for (var i = 0; i < boxes.length; i++) {
            if (i < column) {
                arrHeight[i] = boxes[i].offsetHeight;
            } else {
                var minHeight = getMin(arrHeight).value;
                var minHeightIndex = getMin(arrHeight).index;
                boxes[i].style.position = "absolute";
                boxes[i].style.left = boxes[minHeightIndex].offsetLeft + "px";
                boxes[i].style.top = minHeight + "px";
                arrHeight[minHeightIndex] = minHeight + boxes[i].offsetHeight;
            }
        }
    }

    waterfall();

    //6.判斷觸底
    //窗體滾動的時候 判斷是否觸底 若是觸底了 就要動態加載圖片了
    window.onscroll = function () {
        if (bottomed()) {
            //alert("該加載了");
            //7.動態加載
            var json = [
                {"src": "images/P_000.jpg"},
                {"src": "images/P_001.jpg"},
                {"src": "images/P_002.jpg"},
                {"src": "images/P_003.jpg"},
                {"src": "images/P_004.jpg"},
                {"src": "images/P_005.jpg"},
                {"src": "images/P_006.jpg"},
                {"src": "images/P_007.jpg"},
                {"src": "images/P_008.jpg"},
                {"src": "images/P_009.jpg"},
            ];
            //根據數據動態建立頁面結構 有一條數據就建立一個box
            for (var i = 0; i < json.length; i++) {
                //json[i]
                //div.box>img[src]
                var div = document.createElement("div");
                div.className = "box";
                container.appendChild(div);
                var img = document.createElement("img");
                img.src = json[i].src;
                div.appendChild(img);
            }
            waterfall();
        }
    };
    function bottomed() {//判斷是否觸底的函數 若是觸底了就返回true 不然返回false
        //瀏覽器底部接觸到了 最後一個盒子的頂部的時候就算觸底了
        //最後一個盒子的頂部是 最後一個盒子的offsetTop
        //頁面被捲去的頭部的高度+瀏覽器窗口的高度 > 最後一個盒子的offsetTop (說明觸底)
        var scrollTop = window.pageYOffset;//頁面被捲去的頭部的高度
        var clientHeight = window.innerHeight;//瀏覽器窗口的高度
        //最後一個盒子 boxes[boxes.length-1]
        //最後一個盒子的offsetTop
        var lastBoxTop = boxes[boxes.length - 1].offsetTop;
        if (scrollTop + clientHeight > lastBoxTop) {
            return true;//觸底了
        } else {
            return false;//還沒觸底
        }
    }

};

function getMin(arr) {
    var min = {};
    min.value = arr[0];
    min.index = 0;
    for (var i = 0; i < arr.length; i++) {
        if (min.value > arr[i]) {
            min.value = arr[i];
            min.index = i;
        }
    }
    return min;
}

13.封裝的兼容函數

/**
 * 兼容全部瀏覽器的獲取內部文本的函數
 * @param element
 * @returns {*}
 */
function getInnerText(element) {
    if (typeof element.innerText === "string") {
        return element.innerText;
    } else {
        return element.textContent;
    }
}
/**
 * 兼容全部瀏覽器的設置內部文本的函數
 * @param element
 * @param content
 */
function setInnerText(element, content) {
    if (typeof element.innerText === "string") {
        element.innerText = content;
    } else {
        element.textContent = content;
    }
}


/**
 * 獲取下一個兄弟元素的兼容方法
 * @param element
 * @returns {*}
 */
function getNextElement(element) {
    if (element.nextElementSibling) {
        return element.nextElementSibling;
    } else {
        var next = element.nextSibling;
        while (next && 1 !== next.nodeType) {
            next = next.nextSibling;
        }
        return next;
    }
}

/**
 * 獲取上一個兄弟元素的兼容方法
 * @param element
 * @returns {*}
 */
function getPreviousElement(element) {
    if (element.previousElementSibling) {
        return element.previousElementSibling;
    } else {
        var prev = element.previousSibling;
        while (prev && 1 !== prev.nodeType) {
            prev = prev.previousSibling;
        }
        return prev;
    }
}

/**
 * 獲取第一個子元素的兼容方法
 * @param element
 * @returns {*}
 */
function getFirstElement(element) {
    if (element.firstElementChild) {
        return element.firstElementChild;
    } else {
        var node = element.firstChild;
        while (node && 1 !== node.nodeType) {
            node = node.nextSibling;
        }
        return node;
    }
}
/**
 * 獲取最後一個子元素的兼容方法
 * @param element
 * @returns {*}
 */
function getLastElement(element) {
    if (element.lastElementChild) {
        return element.lastElementChild;
    } else {
        var node = element.lastChild;
        while (node && 1 !== node.nodeType) {
            node = node.previousSibling;
        }
        return node;
    }
}

/**
 * 獲取頁面滾動座標的兼容寫法
 * @returns {{top: (Number|number), left: (Number|number)}}
 */
function scroll() {
    return {
        top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0,
        left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0
    }
}
/**
 * 獲取網頁可視區寬高的兼容寫法
 * @returns {{width: (Number|number), height: (Number|number)}}
 */
function client() {
    return {
        width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || 0,
        height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || 0
    };
}

/**
 * 處理事件對象兼容問題的工具類
 */
var eventUtils = {
    getEvent: function (event) {
        return event || window.event;
    },
    getPageX: function (event) {
        return event.pageX || event.clientX + document.documentElement.scrollLeft;
    },
    getPageY: function (event) {
        return event.pageY || event.clientY + document.documentElement.scrollTop;
    },
    stopPropagation: function (event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        }
    },
    getTarget: function (event) {
        return event.target || event.srcElement;
    },
    addEvent: function (element, eventName, listener) {
        if (element.addEventListener) {//高級瀏覽器綁定事件的方式
            element.addEventListener(eventName, listener, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + eventName, listener);
        } else {
            //若是以上兩種都不支持 確定是支持btn.onclick btn["onclick"]
            element["on" + eventName] = listener;
        }
    },
    removeEvent: function (element, eventName, listener) {
        if (element.removeEventListener) {
            element.removeEventListener(eventName, listener, false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + eventName, listener);
        } else {
            //若是以上兩種都不支持 確定支持 btn.onclick = null
            element["on" + eventName] = null;
        }
    }
};
相關文章
相關標籤/搜索