原生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;
        }
    }
};

转载于:https://my.oschina.net/u/3317396/blog/1812194

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值