イベントリスナーの簡易マネージャー

``addEventListener``で追加したイベントリスナーを使い終わったら``removeEventListener``で削除できるよう、以前[タイムピッカー](https://qiita.com/akebi_mh/items/662da8061f588d0afe38)、[回転操作数値入力](https://qiita.com/akebi_mh/items/ebf6cc58ec5fa2427ac7)、[テンキー型数値入力](https://qiita.com/akebi_mh/items/9277305d4306d3a76b34)等、主にUI系のスクリプトで使用していた処理とほぼ同じものです。

**JavaScript**

```js
'use strict';
const
  eventListenerManage = (function() {
    const events = {};
    let id = 1;
    return {
      add: function(target, type, listener, options) {
        target.addEventListener(type, listener, options);
        events[id] = {
          target: target,
          type: type,
          listener: listener,
          options: options
        };
        return id++;
      },
      remove: function(id) {
        if(id in events) {
          const e = events[id];
          e.target.removeEventListener(e.type, e.listener, e.options);
          delete(events[id]);
          return 0;
        }
        return id;
      }
    };
  }());
```

addメソッドでイベントリスナを追加しつつ一意となるidを返却、removeメソッドにidを渡して削除です。

**使用例**

```html:sample.html
<!DOCTYPE html>
<html lang='ja'>
  <head>
    <meta charset='utf-8'>
    <title>eventListenerManage test</title>
    <style>
      #dummy {
        line-height: 200px;
      }
    </style>
    <script src='script.js'></script>
  </head>
  <body>
    <button id='btnTest'>TEST</button><br>
    <button id='btnOn'>ON</button>
    <button id='btnOff'>OFF</button><br>
    ・ON : TESTボタンに対し、クリックしたらalertを表示する処理をイベントリスナに追加<br>
    ・OFF: ONボタンでTESTボタンに対して追加したイベントリスナを削除<br>
    <hr>
    wheel scroll
    <button id='btnScrollOff'>OFF</button>
    <button id='btnScrollOn'>ON</button><br>
    ・OFF: マウスホイールでのスクロール抑制処理をイベントリスナに追加<br>
    ・ON : OFFボタンで追加したイベントリスナを削除
    <hr>
    <div id='dummy'></div>
    <script>
      'use strict';
      window.addEventListener('DOMContentLoaded', function() {
        let tmp = '';
        for(let i = 0; i < 10; i++) {
          tmp += 'DUMMY TEXT<br>';
        }
        document.getElementById('dummy').innerHTML += tmp;

        const
          test = document.getElementById('btnTest'),
          on   = document.getElementById('btnOn'),
          off  = document.getElementById('btnOff'),
          sOn  = document.getElementById('btnScrollOn'),
          sOff = document.getElementById('btnScrollOff');

        let
          alertId  = 0,
          scrollId = 0;

        on.addEventListener('click', function() {
          if(alertId === 0) {
            alertId = eventListenerManage.add(
              test,
              'click',
              function(){
                alert('test button was clicked.');
              }
            );
          }
        });
        off.addEventListener('click', function() {
          if(alertId > 0) {
            alertId = eventListenerManage.remove(alertId);
          }
        });

        sOff.addEventListener('click', function() {
          if(scrollId === 0) {
            scrollId = eventListenerManage.add(
              window,
              'wheel',
              function(e) {
                e.preventDefault();
              },
              {
                passive: false
              }
            );
          }
        });
        sOn.addEventListener('click', function() {
          if(scrollId > 0) {
            scrollId = eventListenerManage.remove(scrollId);
          }
        });
      });
    </script>
  </body>
</html>
```

**[設置デモ(codepen)](https://codepen.io/akebi_mh/pen/eYgvbjV)**