簡易ストップウォッチを作ってみる[Visualforce]

概要

Visualforceで簡易ストップウォッチを作成します。
setTimeoutで1000ミリ秒毎に秒数をカウントアップします。

ソースコード

SimpleStopwatch.vfp

<apex:page docType="html-5.0" LightningStylesheets="true">
    <html lang="ja">
        <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>簡易ストップウォッチ</title>
            <apex:slds />
        </head>
        <body>
            <div class="slds-align_absolute-center">
                <div class="slds-size_2-of-3">
                    <apex:pageBlock >
                    <div class="slds-grid slds-einstein-header slds-card__header">
                        <header class="slds-media slds-media_center slds-has-flexi-truncate">
                            <div class="slds-grid slds-grid_vertical-align-center slds-size_3-of-4 slds-medium-size_2-of-3">
                                <h1 class="slds-truncate" title="簡易ストップウォッチ">
                                    <span class="slds-text-heading_large">簡易ストップウォッチ</span>
                                </h1>
                            </div>
                            <div class="slds-einstein-header__figure slds-size_1-of-4 slds-medium-size_1-of-3"></div>
                        </header>
                    </div>
                    <div class="slds-align_absolute-center">
                        <div class="slds-m-top_large">
                        <header class="slds-col slds-size_1-of-1 slds-align_absolute-center" >
                            <div class="curentTime slds-text-heading_large">00:00</div>
                        </header>
                        <main class="slds-align_absolute-center">
                            <div class="slds-button-group slds-m-vertical_medium" role="group">
                                <button id="start" class="slds-button slds-button_neutral slds-text-heading_medium slds-p-around_small">スタート</button>
                                <button id="stop" class="slds-button slds-button_neutral slds-text-heading_medium slds-p-around_small" disabled="true">ストップ</button>
                                <button id="reset" class="slds-button slds-button_text-destructive slds-text-heading_medium slds-p-around_small">リセット</button>
                            </div>
                        </main>
                        </div>
                    </div>
                    </apex:pageBlock>
                </div>
            </div>
            <apex:include pageName="SimpleStopwatchJs"/> 
        </body>
    </html>
</apex:page>

SimpleStopwatchJs.vfp

<apex:page >
    <script>
    const stopwatchButton = document.querySelectorAll('.slds-button'),
          startButton = document.querySelector('#start'),
          stopButton = document.querySelector('#stop'),
          curentTimeText = document.querySelector('.curentTime');
    
    let sec = 0, // 秒
        min = 0, // 分
        timerId; // clearTimeout用のID
        
    stopwatchButton.forEach(function (button) {
        button.addEventListener('click', event => {
            let clickedButtonId = event.currentTarget.id;
            if(clickedButtonId === 'start') {
                // 計測開始 
                startTimmer();
            } else if(clickedButtonId === 'stop') {
                // 計測終了
                stopTimmer();
            } else {
                // 計測リセット
                resetTimmer();
            }
        })
    })
        
    // 計測開始
    function startTimmer() {
        startButton.disabled = true;
        stopButton.disabled = false;
        
        // 1秒毎に計測する
        countUp();
    }
    
    // 計測終了
    function stopTimmer() {
        startButton.disabled = false;
        stopButton.disabled = true;
        clearTimeout(timerId);
    }
 
    // 計測リセット
    function resetTimmer() {
        startButton.disabled = false;
        stopButton.disabled = true;
        clearTimeout(timerId);
        
        curentTimeText.textContent = "00:00";
        min = 0;
        sec = 0;
    }
    
    // 計測時間を分に変換する    
    function convertTime(){
        sec++;
        if (sec >= 60) {
            sec = 0;
            min++;
        }
    }
    
    // 1秒毎に計測する
    function countUp(){
        timerId = setTimeout(function(){
            // 計測時間を分に変換する   
            convertTime();
            
            // 桁数を固定
            min = ('0' + min).slice(-2); 
            sec = ('0' + sec).slice(-2);
            
            // 計測時間を表示
            curentTimeText.textContent = min + ":" + sec;
            
            // 1秒毎に計測する
            countUp();
        },1000);
    }
    </script>
</apex:page>