【メモ】初級jQuery見落としがちなあれこれ


## セレクター

### $("html", attributes)

第二引数のオブジェクトのプロパティが、属性に反映される

```javascript
$("<a></a>", {
  href: "http://placeimg.com/640/360/people",
  target: "_blank",
  "class": "className",
  on: {
   click: function() {
    alert("第二引数のオブジェクト");
   } 
  }
});
```

`class`は予約語なのでクオーテーションで囲う

### [属性名*=値][属性名~=値]

```html
<ul id="menu1">
  <li name="item">TOP</li>
  <li name="itemlist">ABOUT</li>
  <li name="item list">PROFILE</li>
  <li name="list">CONTACT</li>
</ul>
```

```javascript
// 部分一致
let $item1 = $("li[name*='item']")
console.log($item1); // TOP, ABOUT, PROFILE

// スペースで区切られた単語ベースの一致
let $item2 = $("li[name~='item']")
console.log($item2); // TOP, PROFILE
```

ちなみに
`[属性名^=値]`は前方一致、
`[属性名$=値]`は後方一致

### セレクタの検索対象

第二引数で指定する

```javascript
$('li', '#menu1').css('color', 'red');
```

`#menu2`,`#menu3`の子要素のliは赤くならない。

内部では`find()`が使われている

### 一般兄弟

```html
<h1>タイトル</h1>
<p>testtesttest</p>
<p>testtesttest</p>
<p>testtesttest</p>
```

```javascript:隣接兄弟セレクタ（1つ目のp）
$('h1 + p').css('color', 'red');
```

```javascript:一般兄弟セレクタ（全てのp）
$('h1 ~ p').css('color', 'red');
```


## フィルター

### :not

セレクターにマッチしない要素をフィルタリング

### :contains / :has 

`:contains(text)`
`:has(selector)`

### :empty

検索0件表示のときに何かやる、とかに使えそう

```
<ul class="news">
  <li class="item"><span>news1</span></li>
  <li class="item">news2</li>
  <li class="item"></li>
</ul>
```

```javascript
// 一番下以外のli要素に下線を引く
// フィルターを二重にするテクニック
$('li:not(:last-child)').css('border-bottom', '1px dotted #000')

$("li:contains('news')").css('color', 'red'); // テキスト検索
$("li:has(span)").css('font-weight', 'bold'); // セレクタ検索

$("li:empty").css('background-color', '#ccc');
```

### :checked

フォーム関係のフィルターは大量にある

```html
<input type="radio" value="春" />春
<input type="radio" value="夏" checked />夏
<input type="radio" value="秋"　/>秋
<input type="radio" value="冬" />冬
```

```javascript:ユーザーの選択した値を取得
const val = $("input:checked").val();
console.log(val); // 夏
```

##### 複数の:checkedを取得

```html
<form action="post">
  <input type="checkbox" value="春" />春
  <input type="checkbox" value="夏" checked />夏
  <input type="checkbox" value="秋"　/>秋
  <input type="checkbox" value="冬" />冬
  <button type="submit">送信</button>
</form>
```

```javascript:応用編
$('button[type="submit"]').on('click', (e) => {  
  const chkArr = $('input[type="checkbox"]:checked').map(
    function () { return $(this).val(); }
  ).toArray();
  // ["夏", "冬"] 
});
```


### .is()

```javascript:チェックされているinputがあるか判定
const isChecked = $('input').is(':checked');
console.log(isChecked); // true
```

### .find() / .filter()

.middleを取得する場合

```html
<ul>
  <li></li>
  <li class="middle"></li>
  <li></li>
</ul>
```

```javascript:find()は親要素、filter()は同レベル要素
$('ul').find('.middle')
$('li').filter('.middle')
```


### $.grep()

```javascript:関数を通してtrueの値を回収する
const arr = [1,2,3,4,5];
const result = $.grep(arr, (val) => {
  return val > 2;
});
console.log(result); // [3, 4, 5]
```


## 属性

### .attr()

応用：`.attr( name, function (index, attr) )`

マッチした要素の全てに第二引数で指定する関数を実行し、
その返り値を属性にセットする

```html
<img src="http://placeimg.com/640/360/people" alt="人" title="ランダムな">
<img src="http://placeimg.com/640/360/sepia" alt="セピア" title="ランダムな">
<img src="http://placeimg.com/640/360/any" alt="何か" title="ランダムな">
```

```javascript:title属性を書き換える
$('img').attr("title", function (index, attr) {
  return  attr + this.alt + index;
});
// ランダムな人0
// ランダムなセピア1
// ランダムな何か2
```


## DOM操作

### .each()

```html
<ul>
  <li class="item">テスト1</li>
  <li class="item">テスト2</li>
  <li class="item">テスト3</li>
  <li class="item">テスト4</li>
  <li class="item">テスト5</li>
</ul>
```

elmはDOM要素そのものなので、jQueryメソッドは使えない
`$(elm)`になる点に注意

```javascript
$('li').each( (index, elm) => {
  
  if(index === 1){
    return; // スキップ（= continue）
  } else if(index === 3){
    return false; // each自体をストップ（= break）
  }
  
  const content = $(elm).text();
  console.log(index + ' : ' + content);
  
});
```

### .eq() / .get() / .toArray()

```javascript
$('li').eq(0);　// Object

// 以下の2つは同じもの 生の要素が返ってくる
$('li').get(0);
$('li')[0];

// 以下の2つは同じもの 配列が返ってくる
$('li').get(); // Array
$('li').toArray(); // Array

$('li'); // Object
```


## イベント

### .change()

セレクト型、ラジオボタン、チェックボックスなどで、ユーザーの選択が変更された時点で発火。
**テキスト入力では、フォーカスが離れた瞬間に発火（リアルタイムではない）。**

### 非推奨

error(), load(), unload()は、ver.3.0にて削除予定
bind(), delegate()も将来廃止予定

### 委譲

**・大量のイベントを付与するメモリの無駄使いを防げる**
**・後から追加したDOM要素にもイベントを付与できる**

```javascript
$('ul').on('click', 'li', function() {
  $(this).css('color', 'red');
});
```

子要素（li）で発生したイベントを親要素（ul）が捉えている（バブリング）
なるべく近くの親を選ぶ。最悪$(document)


## アニメーション

### .queue()

```javascript
const $box = $('#box');
$box.animate({width: "+=100px"}, 1000);
$box.queue(function(next){
  $(this).css({opacity: 0.5});
  // 次の処理を呼び出す $(this).dequeue();でもよい
  next();
});
$box.animate({height: "+=100px"}, 1000).delay(1000).fadeOut(1000);
```

### 連続実行防止

デモ：http://codepen.io/mo4_9/pen/jrNWAk

`:not(:animated)`で、アニメーション中の要素にはアニメーションできないようにする

```javascript:not
const $btn_notanim = $('#btn-notAnim');
$btn_notanim.on('click', () => {
  $('#box:not(:animated)').fadeToggle(1000);
});
```

アニメーションを停止させて、新しいアニメーションに移る

```javascript:stop
const $btn_stop = $('#btn-stop');
$btn_stop.on('click', () => {
  $box.stop().fadeToggle(1000);
});
```