---
# System prepended metadata

title: JS練習_無限轉軸頁面
tags: [javascript]

---

# JS練習_無限轉軸頁面
製作一個無限捲軸的搜尋頁面

- 成品頁面
![](https://i.imgur.com/W3qKfBz.png)

- 功能
- 按照搜尋關鍵字搜尋符合之假文

### HTML
先利用html寫上假設的項目列表，以利方便設定css的樣式。
1. 最上面用一容器包覆`<input>`製作可搜尋的欄位，
2. 中間則是容器，包覆搜尋的項目。
3. 最下面為 loading point。

### CSS

- 單位
  - `px`：像素，無法像公分或是公尺具體化一像素寬多少/高多少，像素的寬跟高是依顯示器的解析度做判斷。
  - `em`：相對單位。繼承父層元素的寬高設定，要是沒有父層元素就是瀏覽器的根元素預設設定（瀏覽器預設字體大小為16px)。

  - `vh/vw`：相對單位。根據可視視窗寬高決定百分比伸縮的單位。語法上省略%這個符號，數值後面直接接vw跟vh。

  
- `<tag>:nth-of-type(n)`選取器
  - 選取第n個同類型標籤的子物件，n可以是`odd`、`even`或是數字。

```.css
.circle:nth-of-type(2){  /* 迭代選擇器，選到第二個點點 */
    animation-delay: .1s ; 
}
```

## JS
- 實現步驟
- 進入頁面時，假文自API取出，出現在頁面。
- 輸入搜尋字，出現loading point。
- 符合搜尋字之內容，排序出來。

### showPost()

- 目的：從 [jsonplaceholder API](https://jsonplaceholder.typicode.com/) 取得假文。
利用jQuery版本的ajax，
- 什麼是ajax:

     非同步的JavaScript 與XML 技術，一種不需要重新整理頁面，透過JavaScript 跟伺服器交換資料、更新網頁內容的技術。
#### 同步/非同步
    - 同步是看按照任務順序做，前一個任務完成才會做下一個任務。 
    - 非同步是，大家一起做，沒有誰先誰後
    
![](https://i.imgur.com/E5nMK4u.png)  
- 語法：
```.js
$.ajax({
  url:,
  method:,
  dataType:,
  data:
  
  success:function(res){console.log(res)},
  error:function(err){console.log(err)},
});

//url: 要請求資料的網址
//method: 請求資料的方式(Ex:POST / //GET / PUT...等)
//dataType: 請求資料的類型(Ex:xml, json, script, or html...等)
//data: 如果需要傳送資料時，則將資料設定在這裡。
```
本次例子程式碼，先利用console.log看看data是否取出成功。
```.js=
let limit = 5
let page = 1

 $.ajax({
     url: `https://jsonplaceholder.typicode.com/posts?
     _limit=${limit}&_page=${page}`,
     method: 'get',
     dataType: 'json',
     success: function (data) {
       console.log(data);
     }  
 })
 ```
 取出成功
 ![](https://i.imgur.com/RUm3HBF.png)
 
將取出來的資料，使用forEach，遍及每筆資料，利用jQuery創造元素的方式`$('<div></div>')`，加上屬性將取出之假文資料放入設定內容。
 
 ```.js=
 data.forEach(function(post){
                const postEl = $('<div></div>').addClass('post');
                postEl.html(`
                <div class="number">${post.id}</div>
                <div class="post-info">
                    <h2 class ="post-title">${post.title}</h2>
                    <p class = "post-body">${post.body}></p>
                </div>
                `)
```

### scroll event
- 設定條件:
當整個頁面(widtj的滾動距離 + 目前顯示視窗的高度 > (整個頁面的高度 - 5)
在接近底部時，出現loading point並觸發函式`showPost()`繼續產生假文
```.js=
$(window).scroll(function(){
    if ($(document).scrollTop() + $(window).height() > $(document).height() - 5) {
        showLoading();
    }
})
```

### 元素的寬度/高度
  ![](https://i.imgur.com/F90A8Iy.png)
圖片來自：https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements

#### 絕對位置
- offsetWidth/ offsetHeight：元素本身+邊界+padding+捲軸
- client：元素裡的==子元素==的寬高 +padding (!沒有邊界跟捲軸)
- scroll：元素內的子元素的寬高，要是子元素超出捲軸外，也包含超出部分，在沒有捲軸時，scroll就等於client
#### 相對位置
- offset:元素本身相對於母元素的水平/垂直距離
- client: 元素本身內外水平/垂直距離，就是邊界的寬高
- scrollTop/ scrollLeft:常用！內容被捲動的距離，內容頂端跟捲軸頂端的相對距離。

  - scrollTop:表示滾動的高度
  - scrollTop()->設定滾動的高度/ 取得滾動的高度
```.js
取得滾動的高度：
      var scrollTop = document.documentElement.scrollTop
```
      



### setTimeout()
  設置定時器，等時間倒數完畢，就執行一段函式或程式碼。
  
- 語法


```
var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...]);
var timeoutID = scope.setTimeout(function[, delay]);
var timeoutID = scope.setTimeout(code[, delay]);
```
  
[setTimeout 小科普](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setTimeout)


### filterSearch()
使用者在input輸入搜尋值，會顯示符合搜尋值的post出來。


```.js=
function filterSearch(){
    const text = $('input').val().toLowerCase();
    $('.post').css('display','none')
    $(`.post:contains('${text}')`).css('display','flex');}
```
- [contain小科普](https://www.w3schools.com/jquery/sel_contains.asp)

###### tags: `javascript`
