基於Jquery的炫酷特效(間隔刷新不同)

實現內容:

類似於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,請大家評論區走一走

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章