實現內容:
類似於csdn個人博客,每篇文章都分成一個一個板塊,我實現的功能是:隨着瀏覽器滾動條往下滾動,每個文章div都以一個特效出現,並且每次刷新網頁的特效都不同(僅限近兩次,也就是連續兩次不同,但是第一次和第三次可能相同)
環境:
<link rel="stylesheet" href="//cdn.bootcss.com/animate.css/3.5.1/animate.min.css">
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
思路來源:
詩酒趁年華 【有想開發自己博客的可以模仿一下他的博客,個人認爲很好看】
第一次看他的博客覺得很好看,特別是特效特別震撼,以前接觸過這種特效,但是不知道怎麼實現的,於是也沒太在意,最近在開發自己的博客,覺得自己的首頁太過於單調,想加點特效,於是就好好研究了一下他是怎麼實現的,終於功夫不負有心人,我在他網頁源碼上發現了這一行代碼
<link href="//cdn.bootcss.com/animate.css/3.5.1/animate.min.css" rel="stylesheet">
bootcss上的CDN加速項目,於是百度了一下這個animate,原來是css3特效插件,來到官網逛了一圈,發現很多有趣的特效,解決了一大特效難題(對CSS沒研究過,不太會自己寫特效.....)
只需要導入相關css文件,並給div加入類名,即可實現動畫播放動能
突破一、
在仔細研究一下他的效果,隨着滾動條向下移動,每個div以一定的特效出現,應該是給滾動條增加監聽
在jquery的API查了一下滾動監聽(以前一直原生js...鬼知道我怎麼想的...)
$(window).scroll(function(){
.....
})
思路就是,在滾動事件中監聽每一個div到當前可視窗口最下邊的距離,如果到一定的返回內,則設置div可見,並播放動畫(通俗點說,等div馬上要從底下出現的時候,就播放動畫)
於是開始查找相關屬性
- offset【獲取匹配在當前視口的相對偏移。返回的對象包含兩個整型屬性:top 和 left,以像素計。此方法只對可見元素有效】
- scrollTop【獲取匹配元素相對滾動條頂部的偏移。此方法對可見和隱藏元素均有效】
- height:【計算當前元素的高度值】
具體判斷條件就是,首先判斷當前滾動條向下滾動的值,如果這個值 > (當前元素相對於當前窗口的值 - 當前窗口高度)
但是有個問題就是(如果只是滿足這個條件,會出現的問題就是元素的最頂部一出現或者還沒出現,已經開始播放動畫,可能你還沒看到,動畫已經播放完了,經過我的嘗試,在條件的最後邊加上15,就是div露出一塊,在播放動畫,效果比較好,大家可以自己測試一下)
則滿足div播放動畫的條件,播放動畫
突破二、
還有一個需求就是每次刷新頁面都出現不同的特效,思路比較簡單,通過定義一個效果的數組,每次產生一個效果數組範圍內的隨機數,添加類名的時候,選擇數組中的元素即可,因此現在的問題就是兩次刷新網頁產生不同的隨機數,我目前能想到的思路是使用cookie,第一次在$(document).ready()函數中產生隨機數,並通過cookie保存到瀏覽器,第二次在產生隨機數時便與第一次進行比較,如果相同,則再次產生隨機數,直到產生一個不同的隨機數,在退出循環
核心代碼:
/* 存放效果的數組 */
var effectArr = ["lightSpeedIn", "fadeInRight", "fadeInUp", "flipInX", "zoomIn", "rotateInDownRight", "rubberBand", "bounceIn", "bounceInUp", "fadeInDown", "rotateInDownLeft", "rotateInUpLeft", "rollIn"];
/* 隨機數 */
var randomNum = generateRandomNum(effectArr.length);
/* 從cookie讀取的隨機數 */
var cookieNum = parseInt($.cookie("randomCookie"));
/**
* DOM加載完畢後,產生一個隨機數,並將其存入cookie
* 通過while循環產生隨機數,如果不同於cookie中讀取出的,則退出循環,並將新數字存入cookie
*/
$(window).ready(function () {
while (true) {
/* 若兩個數相同,則再次產生隨機數,如果不同,則將新的數放入cookie,同時推出循環 */
if (randomNum === cookieNum) {
console.log("重新產生隨機數中......");
randomNum = generateRandomNum(effectArr.length);
} else {
//將新產生的隨機數存入cookie
$.cookie("randomCookie", randomNum);
break;
}
}
});
$(window).scroll(function () {
// 在scroll函數中,不斷檢測進度條滾動值與每一個div的位置關係,如果滿足條件,則調用相關函數
$(".article").each(function () {
// 獲取每一個div距離網頁最頂端的距離,因此div需要設置relative定位
var above_top = $(this).offset().top;
// 獲取當前窗口距離
var window_height = $(window).height();
// 獲取滾動條滾動了多少
var scrollTop = $(window).scrollTop();
// var elemHeight = $(this).height();
// 如果滾動條滾動的高度大 > (元素距離頂部距離 - 當前窗口高度 + 15)
// 加15是爲了讓div露出一點在播放動畫,所以最開始讓div隱藏
if (scrollTop > (above_top - window_height + 15)) {
$(this).css({"visibility": "visible","opacity":"0.8"});
//添加animated屬性
$(this).addClass("animated");
$(this).addClass(effectArr[randomNum]);
}
});
});
/**
* 根據傳入數組的長度產生一個隨機數,用於控制網頁效果
* @param arrayLength
* @returns {number}
*/
function generateRandomNum(arrayLength) {
return parseInt(Math.random() * arrayLength);
}
html代碼隨便寫了寫,我的是jsp頁面,,有點亂
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>animate</title>
<style>
.article {
visibility: hidden;
position: relative;
padding: 20px;
width: 100%;
background: #000;
border-bottom: 1px solid #ccc;
margin-bottom: 25px;
border-radius: 10px;
opacity: 0.8;
box-shadow: 3px 2px 8px rgba(0, 0, 0, 0.15);
line-height: 200%;
}
</style>
</head>
<body>
<div class="container">
<div class="article">
<p style="line-height:200px;color:#fff;text-align:center">隨便寫點啥撐起div</p>
</div>
<div class="article">
<p style="line-height:200px;color:#fff;text-align:center">隨便寫點啥撐起div</p>
</div>
<div class="article">
<p style="line-height:200px;color:#fff;text-align:center">隨便寫點啥撐起div</p>
</div>
<div class="article">
<p style="line-height:200px;color:#fff;text-align:center">隨便寫點啥撐起div</p>
</div>
</div>
</body>
</html>
做到這,興高采烈的去測試我的代碼,????各種bug
補充一、
由於我的動畫是監聽的滾動條,滾動條不滾動時,無法觸發動畫,也就是屏幕最初幾個div無法播放動畫,因此在加載完DOM節點後,判斷哪些div在最初識的屏幕上,單獨播放動畫,實現銜接
也就是在$(window).ready()中兼容這一部分,於是對頁面最上面幾個元素進行了處理,處理完後,將滾動條滾動到最上面,刷新網頁,果然最上面幾個div成功播放動畫,於是興高采烈的將代碼提交到git,出去玩耍
晚上又拿出來看我的網頁,將滾動條移動到窗口某一地方,再次刷新頁面.....問題又出現了,怎麼在當前可視區域內不播放動畫...有一個問題,真的是太脆弱了...經不住測試
補充二、
本來只考慮了,整個網頁如果不滾動鼠標,無法觸發動畫,也就是網頁最上邊部分,無法播放動畫於是單獨考慮了上面部分單獨播放動畫,然後又出現了新的問題,如果網頁已經移動到最後此時F5,發現,當前可視窗口仍然無法播放動畫,於是調整思路如果當前元素距離頂部高度-滾動條滾動的距離 < 當前窗口的實際高度則證明當前元素在可視範圍內,則播放動畫,問題解決,實現所有區域銜接,盡情刷新吧...
附js全部代碼
/**
* @description:
* 每次打開網頁,文章切換效果均不同
* 通過將每次產生的隨機數放入cookie中,再次打開後從cookie中讀出該數字
* 並與新產生的數字進行比較,如果相同,則再次產生隨機數,直到產生不同的隨機數
* @author rambler
* @time 2019年3月10日16:32:14
*/
/* 存放效果的數組 */
var effectArr = ["lightSpeedIn", "fadeInRight", "fadeInUp", "flipInX", "zoomIn", "rotateInDownRight", "rubberBand", "bounceIn", "bounceInUp", "fadeInDown", "rotateInDownLeft", "rotateInUpLeft", "rollIn"];
/* 隨機數 */
var randomNum = generateRandomNum(effectArr.length);
/* 從cookie讀取的隨機數 */
var cookieNum = parseInt($.cookie("randomCookie"));
/**
* DOM加載完畢後,產生一個隨機數,並將其存入cookie
* 通過while循環產生隨機數,如果不同於cookie中讀取出的,則退出循環,並將新數字存入cookie
*/
$(window).ready(function () {
while (true) {
/* 若兩個數相同,則再次產生隨機數,如果不同,則將新的數放入cookie,同時推出循環 */
if (randomNum === cookieNum) {
console.log("重新產生隨機數中......");
randomNum = generateRandomNum(effectArr.length);
} else {
//將新產生的隨機數存入cookie
$.cookie("randomCookie", randomNum);
break;
}
}
/*
兼容處理
*/
$(".article").each(function(){
console.log($(this).offset().top);
console.log("高度"+$(window).height());
if(($(this).offset().top-$(window).scrollTop())<($(window).height())){
$(this).css("visibility", "visible");
$(this).addClass("animated");
$(this).addClass(effectArr[randomNum]);
}
else{
$(this).removeClass("animated");
$(this).removeClass(effectArr[randomNum]);
}
});
});
/**
* 監控滾動條事件,當超過一定距離,則觸發相應函數
*/
$(window).scroll(function () {
// 在scroll函數中,不斷檢測進度條滾動值與每一個div的位置關係,如果滿足條件,則調用相關函數
$(".article").each(function () {
// 獲取每一個div距離網頁最頂端的距離,因此div需要設置relative定位
var above_top = $(this).offset().top;
// 獲取當前窗口距離
var window_height = $(window).height();
// 獲取滾動條滾動了多少
var scrollTop = $(window).scrollTop();
// var elemHeight = $(this).height();
// 如果滾動條滾動的高度大 > (元素距離頂部距離 - 當前窗口高度 + 15)
// 加15是爲了讓div露出一點在播放動畫,所以最開始讓div隱藏
if (scrollTop > (above_top - window_height + 15)) {
$(this).css({"visibility": "visible","opacity":"0.8"});
//添加animated屬性
$(this).addClass("animated");
$(this).addClass(effectArr[randomNum]);
}
});
});
/**
* 根據傳入數組的長度產生一個隨機數,用於控制網頁效果
* @param arrayLength
* @returns {number}
*/
function generateRandomNum(arrayLength) {
return parseInt(Math.random() * arrayLength);
}
如果出現新的bug,請大家評論區走一走