# 六、\[前端] jQuery

## jQuery 簡介

Javascript 的程式庫 library。程式庫就是程式碼的倉庫，裡面有很多工具

每個程式庫都有自己擅長的事情。jQuery 擅長

* Event
  * click event
* Traversing
  * 抓到節點後，可以爬到其他節點
* DOM Manipulate (洞)
  * 把標籤變成物件，document object model
  * 變成物件，就多了很多函式可以用
  * 像是刪除、修改

這三件事情怎麼綜合發生的呢？已待辦清單為例

* 點擊叉叉
* 找到叉叉的 li 項目
* 移除該項目

## events 事件的發生

mouse 相關

* `.click()` 打開、關閉
* `.hover()` 滑到導覽列文字變色
* `.scroll()` 滾動到某個地方就縮小 logo

keyboard 相關

* kepress 完整操作
* keydown，gmail 按 shift 多選視窗
* keyup

form 相關

* blur / focus / change
  * `.focues()` 選中 input 時，就是 focus 專注
  * `.blur()` 跳出 focus 狀態時，就是 blur 不專注、模糊
  * `.change()` focus 後，打了 hi，要 blur 前，就會觸發 change
  * `.select()` word focus，文字選取反白時
* submit
  * 註冊、送出表單前，先擋下來驗證資料，正確再送出

$(document).ready()

* 找 header 底下的 li，但還不存在；只要 ready 準備好再找就好

binding

* 再解釋 event。
* 點擊 #header, #header li 都是事件
* 只要做了之後，有設定要做什麼事情，有 handle，就能做操作
* 只要在目標上 binding 就好

```javascript
$('#target').bind('click', function(){
    // ... 找目標，綁事件，做功能
});

$('target').click(function() {
    // ... 要監聽什麼事件，可以直接寫
});
```

.on()

* bind 的 target 如果不存在，就像是跟空氣進來；後來 target 進來後，還是不知道做什麼事情
* .on() 如何解決不在場的問題?
* 可以先找在場的人，後來目標進來的話，再跟他說
* 綁匪先跟父母預告，我要綁你小孩喔，等你小孩回家後，記得要讓我綁
* 什麼時候會有這種狀況? 例如，AJAX，資料可能後來才進來

```javascript
$('#header').on('click', 'li', function() {
    // ...
})
```

### events 整理

* click / hover / scroll
* keypress / keydown / keyup
* blur / focus / change
* submit
* $(document).ready()
* bind / on

### 自己另外想了解拖放 event

* 因為我的 todo list 想要能夠排序
* [\[筆記\] 製作可拖曳的元素（HTML5 Drag and Drop API） \~ PJCHENder\
  &#x20;那些沒告訴你的小細節](https://pjchender.blogspot.tw/2017/08/html5-drag-and-drop-api.html)
* [HTML5 Drag and Drop 拖曳效果 - Wibibi](http://www.wibibi.com/info.php?tid=HTML5_Drag_and_Drop_%E6%8B%96%E6%9B%B3%E6%95%88%E6%9E%9C)
* [JS 原生拖拽拖放事件 (drag and drop) · Issue #5 · webplus/blog](https://github.com/webplus/blog/issues/5)
  * 還有提到拖曳本機端照片
* [拖曳事件 - jQuery UI Draggable Events example - Pure Example](http://www.pureexample.com/tw/jquery-ui/draggable-events.html)
  * 持續無間斷拖曳
* [\[HTML5 試試看 - 15\] 互動機制 - drag and drop - iT 邦幫忙:: 一起幫忙解決難題，拯救 IT 人的一天](https://ithelp.ithome.com.tw/articles/10057106)
* [灰色後門: 範例 - JavaScript 實作可拖曳物件](http://pvencs.blogspot.tw/2013/03/javascript.html)
  * 持續無間斷拖曳

## traversing 爬樹

html 的架構，就像是一顆樹，是一種樹狀結構，一顆倒過來的樹。traversing 就是在樹上亂跑

* body
* `#header`
  * `#posts`
    * h1
    * p
    * p
    * `#target`
      * p
      * p
    * p
  * `#sidebar`
* `content`
* `#footer`

### find / children

find 找全部下層的東西；children 只找孩子

```javascript
$('#content').find('p') // 有點像 filter 
$('#posts').children()
$('#posts').children('p')
```

### parent / closest

上一層/最近的祖先

```javascript
$('#target').parent()    // #posts
$('target').closest('#content')    // #content
```

### siblings

找同輩

```javascript
$('#target').siblings()
```

### first / last / eq

可是剛剛找的方式，會回傳很多個元素，該怎麼辦？就用數字指定

```javascript
$('#posts').children().first()
$('#posts').children().last()
$('#posts').children().eq(1)    // 第二個
```

整理

* find / children
* parent / closest
* siblings
* first / last / eq

提問

* 為什麼沒提到讀取一個目標的用法
* 像是 `document.getElementByID('target')` 之類的，jQuery 應該有類似的用法吧？
* 啊，還是上一小節就講了 orz

## DOM manipulate 處理網頁元素

插入系列

* 在 todo 清單底下插入新 item，就是插入的動作
* `.append()`
  * 目標元素的最後一個孩子的後面
* `.prepend()`
  * 目標元素的第一個孩子的前面
* `.before()`
  * 在目標元素之前，sibling
* `.after()`
  * 在目標元素之後

另外一個東西

* `.html()` 整個取代
* 如果沒有塞值進去的話，就是當讀取用
* ```javascript
  $('#target').html('<li>hello</li>');    // 覆蓋
  var foo = $('#target').html();        // 讀取與賦值
  ```

其他

* `.remove()` 把選到的目標移除
* `.empty()` 把目標的內容物全部清空
* `.clone()` 複製目標

其他

* 例如，gmail 打勾信件，會變黃
* `.addClass()` 加上 class
* `.removeClass()` 移除 class
* `.toggleClass()` 開關

其他

* `.css()` 修改 css 內容
* ```javascript
  $('.bar').css({
      width: '20px',
      left: '500px',
  });
  ```

其他

* `.prop()` / `.val()`；property, value，用來讀取屬性的值
* ```markup
  <div id="header">
      <ul>
          <li>
              <a href="about.html">about</a>
          </li>
      </ul>
  </div>
  ```
* ```javascript
  <form action="action.php">
      <input type="text" name="email" value="john@gmail.com">
      <button>submit</button>
  </form>
  ```
* ```javascript
  $('input').prop('value'); // 好像只有 form 裡面的 input 比較常用到 value
  $('input').val();    // 簡寫

  $('input').prop('value'， 20); // 寫入
  $('input').val(20);
  ```

其他

* `.data()`
* 像是 gmail 在跟伺服器拿信的內容，要怎麼知道是那一封
* 每封信有自己的編號 data-id
* ```markup
  <ul>
      <li data-id="2028">Lorem</li>
      <li data-id="1720">Lorem</li>
      <li data-id="9728">Lorem</li>
  </ul>
  ```
* ```javascript
  var result = $('ul li').eq(2).data('id');    // 抓到 9725 
  $('ul li').eq(2).data('id', 25);            // 改成 25
  ```

DOM manipulate 整理

* append / prepend / before / after
* html
* remove / empty / clone
* addClass / removeClass / clone
* css
* prop / val&#x20;
* data

jQuery 整理

* event
* traversing
* DOM manipulating

## \[練習] 極簡版 todo list

用 Codepen 練習，記得要把 JS 區塊引用 jQuery，quick add

需求

* 有 Lorem list 介面
* 有能新增 list 的 button
* 有能刪除 list 的 button

自己試作的

* [\[練習\] 自己試作 todo list。list + create + delete](https://codepen.io/ayugioh2003/pen/bvYJwj?editors=1111)
* [jquery 怎麽獲取當前點擊 class 是第幾個\_百度知道](https://zhidao.baidu.com/question/571163702.html)
* [jQuery判断当前元素是第几个元素&获取第N个元素 - isWTF's blog](https://blog.iswtf.com/article.php?id=1116)
* [\[jQuery\] this 和 $(this) 的區别 @ 碎碎念 :: 隨意窩 Xuite 日誌](http://blog.xuite.net/dizzy03/murmur/40717199-%5BjQuery%5D+this+%E5%92%8C+%24%28this%29+%E7%9A%84%E5%8C%BA%E5%88%AB)

html

```markup
<div class="container">

  <div class="lists">
    <div class="list" id="temp">
      <div class="content">Lorem</div>
      <div class="delete">x</div>
    </div>
  </div>
  <div class="clearfix"></div>

  <button class="add">+ todo</button>
</div>
```

css

```css
.list {
  background-color: pink;
  padding: 5px;
  margin: 5px 0 ;
}

.content {
  float: left;
  background-color: pink;
  width: 95%
}

.delete {
  text-align: center;
  background-color: gray;
}
.delete:hover {
  background-color: orange;
}

.clearfix {
  clear: both;
}
```

js

```javascript
// 清單範本
var tempListHtml = $('.lists').html();

// add button，能在 lists 底下新增清單範本
$('.add').click(function(){
  $('.lists').append(tempListHtml);
});

// delete button，偵測到第幾個 list 的 button 被 click，就 remove 第幾個 list
$('.lists').on('click', '.delete', function(){
  var order = $('.delete').index(this);
  $('.list').eq(order).remove();
})
```

參考後修改的 Codepen

* [修改 taker 的 list + create button + delete button](https://codepen.io/ayugioh2003/pen/wmPVNN?editors=1111)

html

```markup
<ul id="todo">
  <li>
    <div class="content">Lorem, ipsum.</div>
    <div class="delete">x</div>
  </li>
  <li>
    <div class="content">Lorem, ipsum.</div>
    <div class="delete">x</div>
  </li>
  <li>
    <div class="content">Lorem, ipsum.</div>
    <div class="delete">x</div>
  </li>
</ul>

<button id="create">+ todo</button>
```

css

```css
ul {
  padding: 0;
  mragin: 0;
  list-style-type: none;

}

li {
  position: relative;
  background-color: pink;
  padding: 10px;
  margin: 5px 0;
}



.delete {
  /*  del btn 用絕對定位  */
  position: absolute;
  top: 5px;
  right: 20px;
  padding: 4px 10px;
  cursor: pointer;
  background-color: #ccc;
}
.delete:hover {
  background-color: yellow;
}

#create {
  background-color: pink;
  width: 200px;
  height: 50px;
}
```

js

```javascript
$(document).ready(function(){

  $('#create').click(function(){
    // clone
    var todo = $('#todo').find('li').first().clone();
    // insert @bottom
    $('#todo').append(todo);
  });

  $('#todo').on('click', '.delete', function(e){ // 會傳 event 進來
     $(e.currentTarget).closest('li').remove();
  });

  // $('.delete').click(function(e){
  //   // target's li, remove
  //   $(e.currentTarget).closest('li').remove();
  // });

});
```

## \[練習] event binding 做不到的事

```javascript
// 原先是這個，新出現的 .delete 會不知道要監聽
$('.delete').click(function(e){
  // target's li, remove
  $(e.currentTarget).closest('li').remove();
});

// 改成這個才能持續監聽，讓別人交待新來的
$('#todo').on('click', '.delete', function(e){
    $(e.currentTarget).closest('li').remove();
});
```

## AJAX 的概念

舉例

* 填表單時，在網頁上填好，傳訊息給 server
* server 回傳結果。如果有錯誤，就提醒
* 壞處是，只是想知道想東西，卻需要重整頁面

改良

* server 在背景傳資料給網頁，不用重整頁面
* 沒有 AJAX 的話，在 Google Docs 修改文字時，就會一直跳頁跳頁跳針跳針

jQuery + AJAX

* 例如，想刪掉 li，會觸發 delete 的 click event。
* 前端刪，後端也要刪，透過 jQuery code 和 AJAX call 互動
* 例如，想獲得 data-id="20" 的資料，透過 traversing 拿，並與 AJAX call 互動
* 想移除 li，就使用 DOM manipulate 移除

前端小結

* HTML
* CSS
* Javascript
* jQuery


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ayugioh2003.gitbook.io/full-stack-first-meet/liu-30015b-qian-7aef5d-jquery.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
