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