0%

JS實作- scrollBlog

成品

觀察功能需求

1.隨著頁面的往下捲動,會載入新的資料

  • 一開始頁面載入,會呈現5筆資料,捲動往下,會再載入5筆
  • 使用{JSON} Placeholder的資料來串接(運用ajax)
  • 設定捲動位置,並於該位置時,會呈現載入的圖示
  • setTimeout來呈現載入的時間與畫面

2.網頁的各資料是有順序,資料左上會有編碼

  • 利用資料本身的id作為序號
  • 於js時,帶入該變數取值

css部分

1.製作左上方,數字

  • 利用position: absolute;定位位置,並利用並利用topleft調整位置
  • 使用display: flex;調整數字的位置,align-items: center; justify-content: center;使水平、垂直置中
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    .post .number {
    position: absolute;
    top: -15px;
    left: -15px;
    font-size: 15px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #fff;
    color: #296ca8;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 7px 10px;
    }

2.載入畫面的原點圖示

  • 先製作load的基本設定,如flex的排列、位置固定於下方,以及透明度的顯示
  • 針對原點訂定背景、原點大小。新增動畫效果,animation: bounce 0.5s ease-in infinite;
  • 動畫名稱@keyframes bounce,設定在某時間點,translateY,的位置。
  • 為了讓圓點的跳動時間不同,針對2、3的原點,設定延遲時間animation-delay: 0.2s;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    .loader {
    /* opacity: 0; */
    display: flex;
    position: fixed; /*位置固定於最下面*/
    bottom: 50px;
    transition: opacity 0.3s ease-in;
    }

    .loader.show {
    opacity: 1;
    }

    /*製作圓點*/


    .circle {
    background-color: #fff;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin: 5px;
    animation: bounce 0.5s ease-in infinite;
    }


    .circle:nth-of-type(2) {
    animation-delay: 0.1s;
    }

    .circle:nth-of-type(3) {
    animation-delay: 0.2s;
    }

    @keyframes bounce {
    0%,
    100% {
    transform: translateY(0);
    }

    50% {
    transform: translateY(-10px);
    }
    }


js部分

1.jsonplaceholder:

2.使用ajax串接API

  • Async/Await 非同步流程控制-筆記
  • 參考Using async await with jQuery’s $.ajaxHow to await the ajax request?,使用jQuery’s$.ajax執行async
  • 在try裡面,放入一般$.ajax抓取API資料的方式,如url、type、dataType
  • 首先,在連結的部分,我們希望每次抓取5筆資料,呈現1頁,所以在外面設置let limit = 5;let page = 1於url中加入該變數
  • 在抓取資料成功時,放入function,並用$.each來執行
    • $.each先傳入該資料(data)陣列,其function (index, value)放入索引以及值的內容。
    • 宣告postEl變數,創造名為postdiv=> $('\<div />')
    • 加入postclass
    • 加入html
    • 最後將此變數,放置呈現文章的容器postEl.appendTo('#posts-container');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
let limit = 5
let page = 1

async function doAjax() {
let result;

try {
result = await $.ajax({
url: `https://jsonplaceholder.typicode.com/posts?_limit=${limit}&_page=${page}`,
type: 'get',
dataType: 'json',
success: function (data) {

$.each(data, function (index, value) {
const postEl = $('<div />').addClass('post').html(`<div class="number">${value.id}</div> <div class="post-info"><h2 class="post-title">${value.title}</h2><p class="post-body">${value.body}</p>
</div>`)
//console.log(postEl)
postEl.appendTo('#posts-container');
//$('#posts-container').append(postEl)

});


}
});

return result;
} catch (error) {
console.error(error);
}

}

doAjax();

查看是否有成功取得資料:console.log(data);

使用jQuery創造div

https://stackoverflow.com/questions/10402567/jquery-div-vs-div

each()

jQuery.each()

3.Infinite Scroll無限捲動(瀑布流)

  • scrollTop網頁右邊的卷軸到最上端網頁的距離有多少
  • scrollHeight 取得整個沒被擋住的高、clientHeight 取得元素的高度(含padding 不含 border)
  • 完整內容高度 (scrollHeight) = 內容頂端與捲軸頂端的距離 (scrollTop) + 捲軸本身高度 (clientHeight) + 內容底端與捲軸底端的距離。

例子:

1
2
3
4
5
6
7
8
9
10
11
$(function () {
$(window).scroll(function () {
var scrollVal = $(this).scrollTop();
$("span.qScrollTop").text(scrollVal);
});
});

if(scrollVal > 500){
/* 如果滾動的物件捲動 > 500 則觸發指定的動作。*/
}

注意:window本身沒有scrollTop/Left這個屬性,所以window.scrollTop是undefined的

所以可能要從body、document來取得

本段落語法:

  • 上述說明各視窗高度得解釋,在此if判斷式中scrollTop + clientHeight >= scrollHeight - 5來計算,當捲軸捲到該位置時,要呈現載入畫面
  • 接著根據載入畫面函式,來放入載入以及呈現接續畫面得設定
    • 使用setTimeout(),在1秒後消除載入圖示,接著在300毫秒後,馬上換頁執行載入新資料
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$(window).scroll(function () {
var scrollTop = $(this).scrollTop();
var scrollHeight = $('body').prop("scrollHeight");
//一樣 var scrollHeight2 = document.documentElement.scrollHeight;
var clientHeight = document.documentElement.clientHeight;
//https://stackoverflow.com/questions/10423759/plain-javascript-to-jquery-clientheight

// console.log('scrollTop:', scrollTop);
// console.log('scrollHeight:', scrollHeight);
// console.log('clientHeight:', clientHeight);


if (scrollTop + clientHeight >= scrollHeight - 5) {
//console.log('show up 123')
showLoading();
}
})


//顯示載入圖示,並取得更多串接資料
function showLoading() {
$('.loader').addClass('show');


setTimeout(function () {

$('.loader').removeClass('show');
setTimeout(function () {
page++;
doAjax();
}, 300);

}, 1000); //1秒之後消失

}

參考資料:
[筆記] 計算網頁底部位置,當網頁達到底部時才產生效果─jQuery
一次搞懂 clientHeight/scrollHeight/scrollTop的區別
談談 JavaScript 的 setTimeout 與 setInterval

4.篩選輸入框資料

  • 綁定事件為.keyup指放開鍵盤的那個剎那,觸發該事件
  • 執行的函式內容為:
    • var text取得輸入值並轉為小寫
    • 利用迴圈,去搜尋關鍵字,判斷,值轉為小寫文字的內容是否符合條件
    • -1 :意指條件不符合
    • indexOf() 方法用來判斷字串字串變數中是否包含某字串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//輸入框搜尋//https://makitweb.com/jquery-search-text-in-the-element-with-contains-selector/  (=>Loop all .content )
$('#filter').keyup(function () {

// Search text
var text = $('#filter').val().toLowerCase();

// Hide all content class element
$('.post').hide();

// Search
$('.post').each(function () {

if ($(this).text().toLowerCase().indexOf("" + text + "") != -1) {
$(this).closest('.post').show();
}
});

參考資料:
比較 keydown, keypress, keyup 的差異
jQuery – Search text in the Element with :contains() Selector
JavaScript String indexOf()


補充參考:
JS20min Day — 20 AJAX 非同步處理 (Asynchronous JavaScript and XML)
回呼函式 Callbacks、Promises 物件、Async/Await 非同步流程控制 - 彭彭直播 at 2019/04/07