クリックカウンター by domsubi


実装例 / 関数型コード

const jshtml = domsubi.jshtml;
const StreamSink = domsubi.Sodium.StreamSink;
    
// クリックイベント取得用Stream
const sClicked = new StreamSink();

// クリックイベントをカウントするCell
const countClicked = sClicked.accum(0, (u,n) => n + 1);

// クリック5回毎に"red", でなければ"black"を返すCell
const varColor = countClicked.map((n) => n % 5 ? 'black' : 'red');

// click回数を表示するVAR要素
const countClickedVar = {
    var: countClicked,
    $: {
        style: {
            color: varColor,
            fontSize: 'x-large'
        }
    }
};

// DOM全体
const contents = new jshtml([
    { button: 'クリックよろしく!!', $: { onclick: sClicked } },
    { p: ['君は ', countClickedVar, ' 回クリックしている'] }
]);

// マウント先へ
contents.mount(targetNode);

実装例 / カスタム要素利用コード

必要なコードはカスタム要素のコンストラクタに。

const {jshtmlElement} = domsubi
class ClickCounterElement extends jshtmlElement {

    constructor() {
        super();

        // クリックイベント取得用Stream
        const sClicked = new StreamSink();

        // クリックイベントをカウントするCell
        const countClicked = sClicked.accum(0, (u,n) => n + 1);
        
        // CSSカスタムプロパティの宣言
        this.cssVars = {
            // クリック5回毎に"red", でなければ"black"を返すCell
            varColor: countClicked.map((n) => n % 5 ? 'black' : 'red')
        };

        // shadowDOMの中身をjshtmlで宣言
        this.shadowSource = [
            { style: 'var { font-size: x-large; color: var(--varColor); }' },
            { button: 'クリックよろしく!!', $: { onclick: sClicked } },
            { p: ['君は ', { var: countClicked }, ' 回クリックしている'] }
        ];
    }

}
customElements.define('click-counter', ClickCounterElement);

// <click-counter></click-counter>