javascript : 커스텀 이벤트를 사용한 이벤트 핸들러 구현

동기 부여, 할 일


  • javascript에 (언제부터) CustomEvent
  • 객체 간 메시징 처리에 사용하고 싶습니다.
  • 항례의 IE 독자 사양이나 이벤트 객체의 detail 프로퍼티에 커스텀 데이터를 건네주는 사양 등은, 내 뇌내의 희소한 작업 공간으로부터 퇴출해 주셨으면 한다.
  • => CustomEvent를 래퍼한 이벤트 처리를 구현하자!

  • 개발 환경



    전제로서 환경은 다음과 같은 느낌.
  • npm
  • webpack3
  • babel
  • es6처럼

  • 구현 (라이브러리)



    아래의 전체 구현을 github 에 올렸습니다. 차이가 있다면 github을 긍정으로 만듭니다. .

    이벤트 처리의 구현 본체는 이런 느낌.

    event.js
    /**
     * 指定したkey名のカスタムイベントを送信する
     * @method send
     * @param  {string} key   カスタムイベント名
     * @param  {object} value データ
     */
    export const dispatch = (key, value) => {
        let ev;
        try {
            ev = new CustomEvent(key, {detail: value});
        } catch(e) { // for IE
            ev = document.createEvent('CustomEvent');
            ev.initCustomEvent(key, false, false, value);
        }
        document.getElementsByTagName('body')[0].dispatchEvent(ev);
    };
    
    /**
     * カスタムイベントのリスナーを登録する
     * @method listen
     * @param  {string}   key      カスタムイベント名
     * @param  {Function} callback イベントリスナーから呼ばれる関数
     */
    export const listen = (key, callback) => {
        document.getElementsByTagName('body')[0].addEventListener(key, callback);
    };
    

    이번은 클래스간의 이벤트 송수신이 목적이었기 때문에, HTML상에서 확실히 존재하는 body 태그를 고정으로 사용해 이벤트 발행을 실시하고 있습니다.

    또, IE만 CustomEvent 생성자를 사용할 수 없는 독자 사양이므로, IE의 실장을 흡수해 줍니다.
    #여기, 출전 사이트를 잊어 버렸기 때문에(qiita내였던 것 같은), 아시는 분은 자칭해 주시면 다행입니다(다른 추천도 가능).

    구현 (이벤트 리스너 측)



    이벤트 리스너 측의 구현은 다음과 같은 느낌.

    listener.js
    import { listen } from './event.js';
    listen('app:ping', (e) => alert(`ping - ${e.detail}`));
    

    구현 (이벤트 발행 측)



    이벤트 발행측은 이런 느낌.
    버튼의 클릭 이벤트로 맞춤 이벤트를 게시합니다.

    dispatcher.js
    import { dispatch } from './event.js';
    document.getElementByTagName('button')[0].onclick = () =>  dispatch('app:ping', 'pong');
    

    구현 (기타)



    빌드의 진입점이 될 app.js를 만듭니다.

    app.js
    require('./listener.js');
    require('./dispatcher.js');
    

    그런 다음 webpack.config.js

    webpack.config.js
    const path = require('path');
    const webpack = require('webpack');
    
    module.exports = {
        entry: {
            'app': './app.js'
        },
        output: {
            path: path.resolve(__dirname, "./"),
            filename: 'static/js/[name].js',
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    exclude: [/node_modules/],
                    use:[{
                        loader: "babel-loader",
                        options:{
                            presets:[
                                ['env', {'modules': false}]
                            ]
                        }
                    }]
                },
            ]
        },
        devServer: {
            contentBase: path.resolve(__dirname, "./"),
            port:3000,
        },
        devtool: 'source-map',
    };
    

    package.json을 적당히 써 둡니다.npm init 에서 생성하고 종속성을 추가하는 등을 유지하십시오.
    이번에는 babel과 webpack, webpack-dev-server를 사용합니다.

    package.json
    {
        "name": "js-customevent",
        "version": "0.0.1",
        "description": "CustomEvent wrapper",
        "main": "index.js",
        "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1",
            "start": "node_modules/.bin/webpack-dev-server"
        },
        "author": "",
        "license": "ISC",
        "devDependencies": {
            "babel-core": "^6.26.0",
            "babel-loader": "^7.1.2",
            "babel-preset-env": "^1.6.1",
            "webpack": "^3.10.0",
            "webpack-dev-server": "^2.11.1"
        }
    }
    

    HTML은 최소한 이런 느낌.

    index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <button type="button">ボタン</button>
    </body>
    <script src="/static/js/app.js"></script>
    </html>
    

    위의 파일을 모두 같은 폴더에 저장하십시오.

    동작 확인



    위의 준비가 완료되면 루트 디렉토리 아래에서 다음을 수행합니다.
    $ npm install
    $ npm start
    

    브라우저에서 http://localhost:3000/로 이동합니다.
    버튼을 눌러 아래와 같은 alert가 표시되면 동작 확인 완료입니다.



    dispatch.js 측에서 전달한 "pong"라는 메시지가 listener.js에서 실행한 이벤트 리스너에 포착되어, alert에 반영했습니다.

    요약



    javascript의 CustomEvent를 사용한 이벤트 핸들링에 대해 소개했습니다. 도움이되면 다행입니다.

    이쪽의 현장에서는 이상입니다.

    좋은 웹페이지 즐겨찾기