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