JavaScript製作元件特效及注意問題(個人整理筆記)
阿新 • • 發佈:2018-12-11
個人理解:所謂的動畫,就是利用定時器,把元素的屬性按某一規律變化的過程。 在函式內利用引數當css屬性時,style[attr] <==> style.arr,比如arr等於border。
注意問題
- IE和其他瀏覽器的相容,IE的事件物件和其他瀏覽器的事件物件不同,IE為window.event,而其他瀏覽器的函式中預設有e的事件物件。
- 把a標籤的href設定為javascript:void(0)實現不跳轉,也表示這個a標籤是為某種功能而採用的,不是為跳轉而設定的。
- 凡是與滾動有關的或者某一東西跟著動的,大多數與滾動scoll系列有關,還用到offset系列、滑鼠的clientX、clientY等。
- 凡是與動畫有關的,大多數與屬性的改變有關,比如width,height,top,left,透明度等等,而且是按某一規律(公式)。
參考
Bootstrap 參考https://v4.bootcss.com/
fullPage.js 參考http://www.dowebok.com/77.html
normalize.css 初始化CSS
html5shiv.min.js ie8及以下相容h5
專案特效及相容程式碼
相容程式碼
設定元素文字內容
/**
* 設定元素的文字內容
* @param element 任意元素
* @param text 任意文字內容
*/
function setInnerText (element, text) {
if (typeof(element.textContent) == "undefined") {
element.innerText = text;
} else {
element.textContent = text;
}
}
獲取元素文字內容
/**
* 獲取元素的文字內容
* @param element 任意元素
* @returns {*} 任意元素中的文字內容
*/
function getInnerText(element) {
if (typeof(element.textContent) == "undefined") {
return element.innerText;
} else {
return element.textContent;
}
}
為任意一個元素繫結事件
//為任意一個元素繫結事件:元素,事件型別,事件處理函式
function addEventListener(element,type,fn) {
if(element.addEventListener){
element.addEventListener(type,fn,false);
}else if(element.attachEvent){ //IE支援
element.attachEvent("on"+type,fn);
}else{
element["on"+type]=fn;
}
}
為任意的一個元素解綁某個事件
//為任意的一個元素解綁某個事件:元素,事件型別,事件處理函式
function removeEventListener(element,type,fn) {
if(element.removeEventListener){
element.removeEventListener(type,fn,false);
}else if(element.detachEvent){
element.detachEvent("on"+type,fn);
}else{
element["on"+type]=null;
}
}
獲取的是頁面向上或者向左捲曲出去的距離的值
/**
* 獲取的是頁面向上或者向左捲曲出去的距離的值,返回的是物件
* @returns {{top: (Number|number), left: (Number|number)}}
*/
function getScroll() {
return {
top: window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0,
left: window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft||0
};
}
獲取內部樣式表或外部樣式表屬性
/*
* element---任意的元素
* attr---屬性
* */
function getAttrValue(element,attr) {
return element.currentStyle?element.currentStyle[attr] : window.getComputedStyle(element,null)[attr]||0;
}
動畫函式
/*
* 終極版本的動畫函式---有bug
* */
function animate(element,json,fn) {
clearInterval(element.timeId);
element.timeId=setInterval(function () {
var flag=true;//假設都達到了目標
for(var attr in json){
if(attr=="opacity"){//判斷屬性是不是opacity
var current= getAttrValue(element,attr)*100;
//每次移動多少步
var target=json[attr]*100;//直接賦值給一個變數,後面的程式碼都不用改
var step=(target-current)/10;//(目標-當前)/10
step=step>0?Math.ceil(step):Math.floor(step);
current=current+step;
element.style[attr]=current/100;
}else if(attr=="zIndex"){//判斷屬性是不是zIndex
element.style[attr]=json[attr];
}else{//普通的屬性
//獲取當前的位置----getAttrValue(element,attr)獲取的是字串型別
var current= parseInt(getAttrValue(element,attr))||0;
//每次移動多少步
var target=json[attr];//直接賦值給一個變數,後面的程式碼都不用改
var step=(target-current)/10;//(目標-當前)/10
step=step>0?Math.ceil(step):Math.floor(step);
current=current+step;
element.style[attr]=current+"px";
}
if(current!=target){
flag=false;//如果沒到目標結果就為false
}
}
if(flag){//結果為true
clearInterval(element.timeId);
if(fn){//如果使用者傳入了回撥的函式
fn(); //就直接的呼叫,
}
}
console.log("target:"+target+"current:"+current+"step:"+step);
},10);
}
clientX、clientY和pageX、pageY及事件物件
//window.event和事件引數物件e的相容
//clientX和clientY單獨的使用的相容程式碼
//scrollLeft和scrollTop的相容程式碼
//pageX,pageY和clientX+scrollLeft 和clientY+scrollTop
//把程式碼封裝在一個函式
//把程式碼放在一個物件中
var evt = {
//window.event和事件引數物件e的相容
getEvent: function (evt) {
return window.event || evt;
},
//可視區域的橫座標的相容程式碼
getClientX: function (evt) {
return this.getEvent(evt).clientX;
},
//可視區域的縱座標的相容程式碼
getClientY: function (evt) {
return this.getEvent(evt).clientY;
},
//頁面向左捲曲出去的橫座標
getScrollLeft: function () {
return window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft || 0;
},
//頁面向上捲曲出去的縱座標
getScrollTop: function () {
return window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0;
},
//相對於頁面的橫座標(pageX或者是clientX+scrollLeft)
getPageX: function (evt) {
return this.getEvent(evt).pageX ? this.getEvent(evt).pageX : this.getClientX(evt) + this.getScrollLeft();
},
//相對於頁面的縱座標(pageY或者是clientY+scrollTop)
getPageY: function (evt) {
return this.getEvent(evt).pageY ? this.getEvent(evt).pageY : this.getClientY(evt) + this.getScrollTop();
}
};
無縫輪播圖
- 利用li橫排佈局圖片,overflow設定為hidden。
- 首尾圖片一樣。
- 當移到最後一張圖片時立即跳回第一張。if判斷距離(即寬度)
- 輪播ul設為絕對定位,利用ul的left進行移動,看像是圖片移動的效果。
- 輪播圖一排的圓點用ul-li做,用排他功能做特效,先全部取消特效,再特定一個給特效。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
img {
vertical-align: top;
}
/*取消圖片底部3畫素距離*/
.box {
width: 300px;
height: 200px;
margin: 100px auto;
background-color: pink;
border: 1px solid red;
position: relative;
overflow: hidden;
}
.box ul li {
float: left;
}
.box ul {
width: 1500px;
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="box" id="screen">
<ul>
<li><img src="../images/01.jpg" alt=""/></li>
<li><img src="../images/02.jpg" alt=""/></li>
<li><img src="../images/03.jpg" alt=""/></li>
<li><img src="../images/04.jpg" alt=""/></li>
<li><img src="../images/01.jpg" alt=""/></li>
</ul>
</div>
<script>
var current = 0;//只聲明瞭一次
function f1() {
var ulObj = document.getElementById("screen").children[0];
current -= 10;
//重點程式碼
if (current < -1200) {
ulObj.style.left = 0 + "px";
current = 0;
} else {
ulObj.style.left = current + "px";
}
}
var timeId = setInterval(f1, 20);
document.getElementById("screen").onmouseover = function () {
//停止
clearInterval(timeId);
};
document.getElementById("screen").onmouseout = function () {
//繼續
timeId = setInterval(f1, 20);
};
</script>
</body>
</html>
百度搜索輔助
- 利用onkeyup事件
- 用string物件的.indexof判斷符合內容放入另一個數組。
- 根據陣列來判斷是否需建立div,以及新增子節點。
- 建立div前判斷是否之前就有div,有就先移出再建。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#box {
width: 450px;
margin: 200px auto;
}
#txt {
width: 350px;
}
#dv {
overflow: hidden;
}
p {
margin: 3px 5px;
padding: 0;
cursor: pointer;
}
p:hover {
background-color: yellow;
}
</style>
</head>
<body>
<div id="box">
<input type="text" id="txt"/>
<input type="button" value="搜尋" id="btn"/>
</div>
<script>
var keyWords = ["我很帥", "我真的很帥", "我真的非常帥", "我帥", "我帥帥帥"];
var txt = document.getElementById("txt");
txt.onkeyup = function (ev) {
if (document.getElementById("dv")) {
document.getElementById("box").removeChild(document.getElementById("dv"));
}
var text = this.value;//儲存輸入內容
var tempArr = [];
for (var i = 0; i < keyWords.length; i++) {
if (keyWords[i].indexOf(text) == 0) {//判斷內容是否符合
tempArr.push(keyWords[i]);
}
}
//如果輸入內容為空或者符合的內容陣列長度為0,移除div
if (this.value.length == 0 || tempArr.length == 0) {
if (document.getElementById("dv")) {
document.getElementById("box").removeChild(document.getElementById("dv"));
}
} else {
if (!document.getElementById("dv")) {
var divObj = document.createElement("div");
document.getElementById("box").appendChild(divObj);
divObj.id = "dv";
divObj.style.width = "350px";
divObj.style.border = "1px solid green";
}
for (var i = 0; i < tempArr.length; i++) {
var pObj = document.createElement("p");
document.getElementById("dv").appendChild(pObj);
setInnerText(pObj, tempArr[i]);
}
}
};
//新增文字的相容程式碼
function setInnerText(element, text) {
if (typeof element.textContent == "undefined") {
element.innerText = text;
} else {
element.textContent = text;
}
}
//獲取文字的相容程式碼
function getInnerText(element) {
if (typeof element.textContent == "undefined") {
return element.innerText;
} else {
return element.textContent;
}
}
</script>
</body>
</html>
固定導航欄案例
- 利用widow.onscroll事件。
- 利用scroll系列且相容程式碼獲取當導航欄剛到頂時,上面滾出去的距離x。
- 當滾動到一定距離後(實際>=x時),設定導航欄的定位position為absolute,且top為0,並把導航欄下面部分設定margin-Top防止跳上去。
- 當實際<