elementTarget.addEventListener の復習

__addEventLister__ を上手く使いこなせていない事を痛感したのでメモしておく。　気付きがあった段階で、追記していきたい。

## 基本

```txt
elementTarget.addEventListener( type, listener [, useCapture ])
```

- __type__ : "click" とか "keydown" とかのイベントの種類
- __listener__ : "type" で指定したイベントを受け取るオブジェクトか関数
- __useCapture__ : イベントの伝播の方向。 false がデフォルト

-- false : イベントの伝播は、イベントを発火させたDOM -> elementTarget
-- true  : イベントの伝播は、 elementTarget -> イベントを発火させたDOM


## ハンドラ(listener)内での this と event.target

```js

function listener (event) {
    var $target = event.target
    // 処理
}
```

- __this__ : elementTarget
- __event.target__ : イベントを発火させたDOM


```html:test1.html
<!doctype html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="./qunit/qunit-1.10.0.css" />
<script src="./qunit/qunit-1.10.0.js"></script>
<script src="./qunit/qunit-tap.js"></script>
<script>
;(function (global) {
    var q = global.QUnit
    qunitTap(q, function () { console.log.apply(console, arguments) })
    //qt.config.autostart = false
    q.assert.is = q.assert.strictEqual
    q.assert.like = function (str, reg, mes) { this.ok(reg.test(str), mes) }
})(this.self)
</script>
<title>dom.addEventListener useCapture</title>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">

    <ul>
        <li id="aaa"><a href="javascript:void(0);">test 1</a></li>
        <li id="bbb"><a href="javascript:void(0);">test 2</a></li>
        <li id="ccc"><a href="javascript:void(0);">test 3</a></li>
    </ul>

</div>
</body>

<script>
var q = QUnit
var d = document

function setup () {
    this.$ul  = d.querySelector('#qunit-fixture>ul')
    this.$lis = $ul.querySelectorAll('li')
    this.$as  = $ul.querySelectorAll('li>a')
}

q.module('prepare', {setup: setup})
q.test('$as, $lis, $ulが指定できているか', function (t) {
    t.ok(this.$ul, 'exists ul')
    t.is(this.$lis.length, 3, 'exists ul>li')
    t.is(this.$as.length,  3, 'exists ul>li>a')
    t.is(this.$as[0].textContent, 'test 1', 'ul>li>a[0].textContent === "test 1"')
})

q.module('$ul.addEventListener(target, listener, useCapture)でlistenerの扱うevent.target', {setup: setup})
q.asyncTest('$ul.click()', function (t) {
    var that = this
    this.$ul.addEventListener('click', listener, false)
    this.$ul.click()

    function listener (ev) {
        var $target = ev.target
        t.is(that.$ul,  $target, 'ev.target === ul')
        t.is(this, $target, 'this === ul')

        that.$ul.removeEventListener('click', listener, false)

        q.start()
    }
})
q.asyncTest('$as[0].click()', function (t) {
    var that = this
    this.$ul.addEventListener('click', listener, false)
    this.$as[0].click()

    function listener (ev) {
        var $target = ev.target
        t.is(that.$as[0],  $target, 'ev.target === as[0]')
        t.is(this, that.$ul, 'this === ul')

        that.$ul.removeEventListener('click', listener, false)

        q.start()
    }
})

q.module('$ul.addEventListener(target, listener, useCapture), useCapture の指定でイベントの伝播の順序がどうなるか', {setup: setup})
q.asyncTest('useCapture - "false": a -> li ->ul', function (t) {
    var that = this
    var spy = []
    var useCapture = false

    this.$ul.addEventListener('click', listener, useCapture)
    Array.prototype.forEach.apply(this.$lis, [function ($li) {
        $li.addEventListener('click', listener, useCapture)
    }])
    Array.prototype.forEach.apply(this.$as, [function ($a) {
        $a.addEventListener('click', listener, useCapture)
    }])

    this.$as[0].click()

    function listener (ev) {
        spy.push(this)

        if (spy.length === 3) {
            t.is(spy[0], that.$as[0],  '1st fired $as[0]')
            t.is(spy[1], that.$lis[0], '2nd fired $lis[0]')
            t.is(spy[2], that.$ul,     'last fired $ul')

            q.start()
        }
    }
})
q.asyncTest('useCapture - "true": ul -> li ->a', function (t) {
    var that = this
    var spy = []
    var useCapture = true

    this.$ul.addEventListener('click', listener, useCapture)
    Array.prototype.forEach.apply(this.$lis, [function ($li) {
        $li.addEventListener('click', listener, useCapture)
    }])
    Array.prototype.forEach.apply(this.$as, [function ($a) {
        $a.addEventListener('click', listener, useCapture)
    }])

    this.$as[0].click()

    function listener (ev) {
        spy.push(this)

        if (spy.length === 3) {
            t.is(spy[0], that.$ul,     '1st fired $ul')
            t.is(spy[1], that.$lis[0], '2nd fired $lis[0]')
            t.is(spy[2], that.$as[0],  'last fired $as[0]')

            q.start()
        }
    }
})
</script>
```