> For the complete documentation index, see [llms.txt](https://ayugioh2003.gitbook.io/full-stack-first-meet/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ayugioh2003.gitbook.io/full-stack-first-meet/liu-30015b-qian-7aef5d-jquery.md).

# 六、\[前端] 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
