從零開始學 Web 之 BOM(三)offset,scroll,變速動畫函式
一、直接使用 document 獲取的元素
// 獲取 body
document.body;
// 獲取 title
document.title; // 獲取的是 title 中的值
// 獲取 html
document.documentElement;
1、案例:圖片跟著滑鼠移動
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> img { position: absolute; } </style> </head> <body> <img src="images/Daotin.png" id="im"> <script src="common.js"></script> <script> document.onmousemove = function (ev) { // 獲取滑鼠的橫縱座標 my$("im").style.left = ev.clientX + "px"; my$("im").style.top = ev.clientY + "px"; } </script> </body> </html>
1、獲取滑鼠的橫縱座標在滑鼠移動的事件中;
2、注意:圖片能夠移動,一定要脫標。
二、offset系列
offsetWidth:獲取元素的寬(加邊框)
offsetHeight:獲取元素的高(加邊框)
offsetLeft:獲取元素距離左邊位置的值
offsetTop:獲取元素距離上邊位置的值
三、scroll 系列
scroll:捲曲
scrollWidth:如果元素中內容寬度小於元素的寬度,則為元素的寬度(不含邊框),否則為元素中內容的實際寬度。 scrollHeight:如果元素中內容高度小於元素的高度,則為元素的高度(不含邊框),否則為元素中內容的實際高度。 scrollLeft:元素中的內容往左捲曲出去的距離。(有滾動條的時候) scrollTop:元素中的內容往上捲曲出去的距離。(有滾動條的時候)
1、封裝獲取 scrollLeft 和 scrollTop 的函式
function getScroll() {
return {
left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
};
}
1、返回的是一個物件,這個物件有兩個自定義屬性 left 和 top ,使用的時候直接使用 getScroll().left 或者 getScroll().top 即可獲得瀏覽器滾動條向左向上移動的距離。
2、之所以用 “||” 操作是因為瀏覽器相容問題。
四、變速動畫函式
// 變速動畫移動函式
function animation(element, target) {
clearInterval(element.timeId); // 每次呼叫函式就清理之前的timeId
// 判斷當前的位置
element.timeId = setInterval(function () {
var current = element.offsetLeft; // 不能使用 element.style.left
var onestep = (target - current) / 10;
onestep = onestep > 0 ? Math.ceil(onestep) : Math.floor(onestep);
current += onestep;
element.style.left = current + "px";
// if (Math.abs(current - target) >= onestep) {
// element.style.left = current + "px";
// } else {
// clearInterval(timeId);
// element.style.left = target + "px";
// }
if(target === current) {
clearInterval(element.timeId);
return;
}
// 測試程式碼
console.log("target="+target+", current="+current+", step="+onestep);
}, 20);
}
1、Math.ceil() 和 Math.round() 和 Math.floor() 的區別:
zconsole.log(Math.ceil(11.1)); // 12
console.log(Math.ceil(11.8)); // 12
console.log(Math.ceil(-11.1)); // -11
console.log(Math.ceil(-11.8)); // -11
console.log(Math.round(11.1)); // 11
console.log(Math.round(11.8)); // 12
console.log(Math.round(-11.1)); // -11
console.log(Math.round(-11.8));// -12
console.log(Math.floor(11.1)); // 11
console.log(Math.floor(11.8)); // 11
console.log(Math.floor(-11.1)); // -12
console.log(Math.floor(-11.8)); // -12
2、這裡 onestep 使用向上取整,才能走到終點。
3、這裡就不需要判斷 if (Math.abs(current - target) >= onestep) 了,因為每次走的 onestep 總是越來越小,到最後都會變成1,所以不存在走不夠或者超出的情況。
4、定時器中加個 return,可以防止走到終點,函式還在不停迴圈的情況。
1、案例:筋斗雲
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 800px;
height: 50px;
margin: 0 auto;
margin-top: 200px;
background-color: pink;
position: relative;
}
li {
float: left;
list-style-type: none;
width: 100px;
height: 30px;
background-color: #fff;
margin: 10px;
cursor: pointer;
text-align: center;
font: 700 20px/30px "Microsoft YaHei";
}
span {
position: absolute;
width: 100px;
height: 30px;
background-color: rgba(181, 14, 205, 0.8);
left: 10px;
top: 10px;
}
</style>
</head>
<body>
<input type="button" value="按鈕" id="btn">
<div id="box">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<span></span>
</div>
<script src="common.js"></script>
<script>
// 獲取box元素
var boxObj = my$("box");
// 獲取span元素
var spanObj = boxObj.children[1];
// 獲取所有li元素
var liObjs = boxObj.children[0].children;
// 為所有的li註冊事件
for (var i = 0; i < liObjs.length; i++) {
// 註冊滑鼠進入
liObjs[i].onmouseover = mouseoverHandle;
// 註冊滑鼠點選
liObjs[i].onclick = clickHandle;
// 註冊鼠標出來
liObjs[i].onmouseout = mouseoutHandle;
}
function mouseoverHandle() {
animationChangeSpeed(spanObj, this.offsetLeft);
}
var currentPos = 10;
function clickHandle() {
currentPos = this.offsetLeft;
}
function mouseoutHandle() {
animationChangeSpeed(spanObj, currentPos);
}
</script>
</body>
</html>
1、var currentPos = 10; 是因為我的 span 有個 maigin-left:10px,如果是從最左邊開始的話就為 0。
五、獲取任意元素的任意屬性值
在 window 下有一個方法:window.getComputedStyle(element, string)
可以獲取一個元素所有的屬性值。
其中第一個引數為需要獲取的元素;第二個引數為是否有偽類或者偽樣式。返回值是這個元素所有屬性的物件集合。
當我們需要什麼屬性的時候,點出來就可以了。
但是這個方法 IE8 不支援,在 IE8 下有一個屬性 currentStyle, 通過 元素.currentStyle
的方式可以得到返回值為這個元素所有屬性的集合。
相容程式碼:
function getStyle(element, attr) {
return window.getComputedStyle ?
window.getComputedStyle(element, null)[attr] :
element.currentStyle[attr];
}
六、為變速動畫函式增強
1、增加任意一個屬性值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
input {
margin-top: 10px;
}
div {
position: absolute;
width: 200px;
height: 100px;
background-color: yellowgreen;
margin-top: 10px;
/*left: 20px;*/
}
</style>
</head>
<body>
<input type="button" value="移動400px" id="btn1">
<input type="button" value="移動800px" id="btn2">
<div id="dv"></div>
<script src="common.js"></script>
<script>
// 移動400px
my$("btn1").onclick = function () {
animation(my$("dv"), "top", 400);
};
// 移動800px
my$("btn2").onclick = function () {
animation(my$("dv"), "width", 800);
};
var timeId = 0;
// 變速動畫移動函式
// element --- 任意元素
// attr ---- 任意屬性名字
// target ---目標位置
function animation(element, attr, target) {
clearInterval(element.timeId); // 每次呼叫函式就清理之前的timeId
// 判斷當前的位置
element.timeId = setInterval(function () {
var current = parseInt(getStyle(element, attr)); // 獲取任意元素的任意一個屬性值
var onestep = (target - current) / 10;
onestep = onestep > 0 ? Math.ceil(onestep) : Math.floor(onestep);
current += onestep;
element.style[attr] = current + "px";
if(target === current) {
clearInterval(element.timeId);
}
// 測試程式碼
console.log("target="+target+", current="+current+", step="+onestep);
}, 20);
}
</script>
</body>
</html>
getStyle 函式返回的屬性值是加“px”的所以要加
parseInt
進行處理。
2、增加任意多個屬性值
<body>
<input type="button" value="移動" id="btn">
<div id="dv"></div>
<script src="common.js"></script>
<script>
my$("btn").onclick = function () {
animation(my$("dv"), {"left":100,"top":400,"width":400,"height":200});
};
var timeId = 0;
// 變速動畫移動函式
// element --- 任意元素
// attr ---- 任意屬性名字
// target ---目標位置
function animation(element, json) {
clearInterval(element.timeId); // 每次呼叫函式就清理之前的timeId
// 判斷當前的位置
element.timeId = setInterval(function () {
var flag = true;
for(var attr in json) {
var current = parseInt(getStyle(element, attr)); // 獲取任意元素的任意一個屬性值
var target = json[attr];
var onestep = (target - current) / 10;
onestep = onestep > 0 ? Math.ceil(onestep) : Math.floor(onestep);
current += onestep;
element.style[attr] = current + "px";
// 保證所有屬性都達到目標才清理定時器
if(target !== current) {
flag = false;
}
}
if (flag) {
clearInterval(element.timeId);
}
// 測試程式碼
console.log("target="+target+", current="+current+", step="+onestep);
}, 20);
}
</script>
</body>
1、既然需要多對屬性,很自然的想到 json
2、在移動的時候使用 for in 迴圈遍歷 json
3、因為每個屬性達到目標值的次數不同,所以需要在所有屬性都到達目標值時才清理定時器。
3、增加回調函式
回撥函式:當一個函式作為引數的時候,這個函式就是回撥函式。
作用:增加動畫的次數。
<body>
<input type="button" value="移動" id="btn">
<div id="dv"></div>
<script src="common.js"></script>
<script>
my$("btn").onclick = function () {
animation(my$("dv"), {"left":100,"top":400,"width":400,"height":200}, function (){
animation(my$("dv"), {"left":300,"top":40,"width":140,"height":20}, function (){
animation(my$("dv"), {"left":50,"top":200,"width":200,"height":100});
});
});
};
var timeId = 0;
// 變速動畫移動函式
// element --- 任意元素
// attr ---- 任意屬性名字
// target ---目標位置
function animation(element, json, fn) {
clearInterval(element.timeId); // 每次呼叫函式就清理之前的timeId
// 判斷當前的位置
element.timeId = setInterval(function () {
var flag = true;
for(var attr in json) {
var current = parseInt(getStyle(element, attr)); // 獲取任意元素的任意一個屬性值
var target = json[attr];
var onestep = (target - current) / 10;
onestep = onestep > 0 ? Math.ceil(onestep) : Math.floor(onestep);
current += onestep;
element.style[attr] = current + "px";
// 保證所有屬性都達到目標才清理定時器
if(target !== current) {
flag = false;
}
}
if (flag) {
clearInterval(element.timeId);
if(fn) {
fn();
}
}
// 測試程式碼
//console.log("target="+target+", current="+current+", step="+onestep);
}, 20);
}
// 獲取任意元素的任意一個屬性值
function getStyle(element, attr) {
return window.getComputedStyle ?
window.getComputedStyle(element, null)[attr] :
element.currentStyle[attr];
}
</script>
</body>
1、回撥函式的呼叫應該在迴圈之後,清理定時器之後呼叫。
2、測試 chrome、firefox 都可以, IE8 出錯,顯示 element.style[attr] = current + "px"; 有問題,暫時不知道什麼原因。
4、增加透明度和層級
透明度:opacity
層級:z-Index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
position: absolute;
width: 200px;
height: 100px;
background-color: yellowgreen;
}
input {
z-index: 1;
position: absolute;
}
</style>
</head>
<body>
<input type="button" value="移動" id="btn">
<div id="dv"></div>
<script src="common.js"></script>
<script>
my$("btn").onclick = function () {
animation(my$("dv"),
{"height": 200, "width":15,"opacity":1,"zIndex":10});
};
// 獲取任意元素的任意一個屬性值
function getStyle(element, attr) {
return window.getComputedStyle ?
window.getComputedStyle(element, null)[attr] :
element.currentStyle[attr];
}
// 變速動畫移動函式
// element --- 任意元素
// attr ---- 任意屬性名字
// target ---目標位置
function animation(element, json, fn) {
clearInterval(element.timeId); // 每次呼叫函式就清理之前的timeId
// 判斷當前的位置
element.timeId = setInterval(function () {
var flag = true;
for (var attr in json) {
// 判斷attr是不是層級zIndex
if (attr === "zIndex") {
element.style[attr] = json[attr];
} else if (attr === "opacity") { // 判斷attr是不是透明度opacity
// 獲取當前透明度*100,方便計算
var current = getStyle(element, attr) * 100;
// 目標透明度也*100
var target = json[attr] * 100;
var onestep = (target - current) / 10;
onestep = onestep > 0 ? Math.ceil(onestep) : Math.floor(onestep);
current += onestep;
element.style[attr] = current / 100;
} else { // 其他屬性
var current = parseInt(getStyle(element, attr)); // 獲取任意元素的任意一個屬性值
var target = json[attr];
var onestep = (target - current) / 10;
onestep = onestep > 0 ? Math.ceil(onestep) : Math.floor(onestep);
current += onestep;
element.style[attr] = current + "px";
}
// 保證所有屬性都達到目標才清理定時器
if (target !== current) {
flag = false;
}
}
if (flag) {
clearInterval(element.timeId);
if (fn) {
fn();
}
}
// 測試程式碼
//console.log("target="+target+", current="+current+", step="+onestep);
}, 20);
}
</script>
</body>
</html>
1、此為最終版變速動畫函式。
2、透明度的設定因為是小數計算,所以需要都乘以100,最後再除以100.
3、層級 zIndex 不需要漸變,直接設定即可。
5、案例:手風琴效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 1200px;
height: 500px;
margin: 100px 0 0 100px;
border: 1px solid red;
overflow: hidden;
}
li {
float: left;
list-style: none;
width: 240px;
height: 500px;
}
</style>
</head>
<body>
<div id="dv">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<script src="common.js"></script>
<script>
var liObjs = my$("dv").getElementsByTagName("li");
for (var i = 0; i < liObjs.length; i++) {
liObjs[i].style.backgroundImage = "url(images/dos.jpg)";
// 滑鼠進入
liObjs[i].onmouseover = mouseoverHandle;
// 滑鼠退出
liObjs[i].onmouseout = mouseoutHandle;
}
function mouseoverHandle() {
// 先設定所有寬度為100
for (var j = 0; j < liObjs.length; j++) {
animation(liObjs[j], {"width": 100});
}
// 再設定當前元素寬度為800
animation(this, {"width": 800});
}
function mouseoutHandle() {
for (var j = 0; j < liObjs.length; j++) {
animation(liObjs[j], {"width": 240});
}
}
// 獲取任意元素的任意一個屬性值
function getStyle(element, attr) {
return window.getComputedStyle ?
window.getComputedStyle(element, null)[attr] :
element.currentStyle[attr];
}
// 變速動畫移動函式
// element --- 任意元素
// attr ---- 任意屬性名字
// target ---目標位置
function animation(element, json, fn) {
clearInterval(element.timeId); // 每次呼叫函式就清理之前的timeId
// 判斷當前的位置
element.timeId = setInterval(function () {
var flag = true;
for (var attr in json) {
// 判斷attr是不是層級zIndex
if (attr === "zIndex") {
element.style[attr] = json[attr];
} else if (attr === "opacity") { // 判斷attr是不是透明度opacity
// 獲取當前透明度*100,方便計算
var current = getStyle(element, attr) * 100;
// 目標透明度也*100
var target = json[attr] * 100;
var onestep = (target - current) / 10;
onestep = onestep > 0 ? Math.ceil(onestep) : Math.floor(onestep);
current += onestep;
element.style[attr] = current / 100;
} else { // 其他屬性
var current = parseInt(getStyle(element, attr)); // 獲取任意元素的任意一個屬性值
var target = json[attr];
var onestep = (target - current) / 10;
onestep = onestep > 0 ? Math.ceil(onestep) : Math.floor(onestep);
current += onestep;
element.style[attr] = current + "px";
}
// 保證所有屬性都達到目標才清理定時器
if (target !== current) {
flag = false;
}
}
if (flag) {
clearInterval(element.timeId);
if (fn) {
fn();
}
}
// 測試程式碼
//console.log("target="+target+", current="+current+", step="+onestep);
}, 20);
}
</script>
</body>
</html>
相關推薦
從零開始學 Web 之 BOM(三)offset,scroll,變速動畫函數
樣式 清理 java mar dde sof mov har width 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔 博客園:
從零開始學 Web 之 BOM(三)offset,scroll,變速動畫函式
一、直接使用 document 獲取的元素 // 獲取 body document.body; // 獲取 title document.title; // 獲取的是 title 中的值 // 獲取 html document.documentElement; 1、案例:圖片跟著滑鼠移動 <!DOC
從零開始學 Web 之 HTML5(三)網路監聽,全屏,檔案讀取,地理定位介面,應用程式快取
一、網路監聽介面 ononline:網路連通時觸發 onoffline:網路斷開時觸發 window.addEventListener("online", function(){}); window.addEventListener("offline", function(){}); 二、全屏介面 全
從零開始學 Web 之 BOM(四)client系列
一、client 系列 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style
從零開始學 Web 之 BOM(二)定時器
一、定時器 BOM 中有兩中方式設定定時器。 1、方式一 特點:定時器可以重複使用。 // 引數有兩個: // 第一個引數:定時器定時結束處理函式 // 第二個引數:定時事件,單位毫秒。 // 返回值:定時器id值 var timeId = window.setInterval(function()
從零開始學 Web 之 BOM(一)BOM的概念,一些BOM物件
大家好,這裡是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... +------------------------------------------------------------ github:https://github.com/Daotin/Web 微信公眾號:Web前端之
從零開始學 Web 之 DOM(一)DOM的概念,對標簽操作
關註 1.5 pan 什麽 tin p標簽 nod text == 大家好,這裏是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關註。在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,
從零開始學 Web 之 Ajax(三)Ajax 概述,快速上手
lan 技術分享 php 概述 由於 val asc logs 更新 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔 博客園:ht
從零開始學 Web 之 ES6(三)ES6基礎語法一
arr 方法 foreach reac 公眾 存在 lock 數組名 回調函數 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔 博
從零開始學 Web 之 jQuery(三)元素操作,鏈式程式設計,動畫方法
一、使用css操作元素樣式 1、常規寫法 $("#dv").css("width", "200px"); $("#dv").css("height", "100px"); $("#dv").css("background", "red"); 2、鏈式寫法 $("#dv").css("width", "20
從零開始學 Web 之 Ajax(五)同步非同步請求,資料格式
一、同步請求與非同步請求 同步請求:在使用者進行請求傳送之後,瀏覽器會一直等待伺服器的資料返回,如果網路延遲比較高,瀏覽器就一直卡在當前介面,直到伺服器返回資料才可進行其他操作。 非同步請求:在使用者進行請求傳送之後,瀏覽器可以自由操作頁面中其他的元素,當伺服器放回資料的時候,才觸發相應事件,對返回的資料
從零開始學 Web 之 CSS(三)連結偽類、背景、行高、盒子模型、浮動
大家好,這裡是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關注。在這裡我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的專案。現在就讓我們一起進入 Web 前端學習的冒險之旅吧! 一、連結偽類 a:
從零開始學 Web 之 DOM(三)innerText與innerHTML、自定義屬性
大家好,這裡是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關注。在這裡我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的專案。現在就讓我們一起進入 Web 前端學習的冒險之旅吧! 一、相容程式碼 1
從零開始學 Web 之 CSS3(三)漸變,background屬性
一、漸變 漸變是CSS3當中比較豐富多彩的一個特性,通過漸變我們可以實現許多炫麗的效果,有效的減少圖片的使用數量,並且具有很強的適應性和可擴充套件性。可分為線性漸變、徑向漸變。 1、線性漸變 線性漸變:指沿著某條直線朝一個方向產生漸變效果。 語法: background: linear-gradient(
從零開始學 Web 之 DOM(一)DOM的概念,對標籤操作
大家好,這裡是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關注。在這裡我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的專案。現在就讓我們一起進入 Web 前端學習的冒險之旅吧! 一、DOM概念 D
從零開始學 Web 之 Ajax(四)介面文件,驗證使用者名稱唯一性案例
>大家好,這裡是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... > > - github:https://github.com/Daotin/Web > - 微信公眾號:[Web前端之巔](https://github.com/Daotin/pi
從零開始學 Web 之 HTML5(四)拖拽介面,Web儲存,自定義播放器
>大家好,這裡是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... > > - github:https://github.com/Daotin/Web > - 微信公眾號:[Web前端之巔](https://github.com/Daotin/pi
從零開始學 Web 之 HTML(三)表單
大家好,這裡是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關注。在這裡我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的專案。現在就讓我們一起進入 Web 前端學習的冒險之旅吧! 一、表格 1
從零開始學 Web 之 jQuery(一)jQuery的概念,頁面載入事件
一、jQuery的概念 1、什麼是 JavaScript 庫? JavaScript 開發的過程中,處理瀏覽器的相容很複雜而且很耗時,於是一些封裝了這些操作的庫應運而生。這些庫還會把一些常用的程式碼進行封裝。 把一些常用到的方法寫到一個單獨的 js 檔案,使用的時候直接去引用這js檔案就可以了,這個 js
從零開始學 Web 之 JavaScript(三)函式
大家好,這裡是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關注。在這裡我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的專案。現在就讓我們一起進入 Web 前端學習的冒險之旅吧! 一、函式 1、函式