[Javascript] 倒數計時刷新條碼圖片(讓ChatGPT撰寫的版本)

countdown change image

前言

最近要在手機版網頁上實作出類似全家App、OpenPoint App的會員條碼

使用情境類似LinePay、街口支付出示結帳條碼給店員那樣:畫面有一張條碼圖片、倒數計時器,還有一個按鈕可以點擊來刷新條碼圖片&重新倒數計時
※條碼圖片具有時效性,這功能是後端產製圖片時就該處理,本文就不展示後端產製圖片的相關程式碼

像這種"常見的小功能模組",雖然上網隨便Google可以查詢出一堆五花八門的實作方法

但時代演變不同了…

懶人工程師現在完成此項功能開發的另一種方式:
把需求&功能要處理的流程,詳細拆分整理後,逐筆寫在程式碼內的註解,丟給AI來幫忙寫程式碼,
懶人工程師再code review並執行測試功能是否正常如期。(感覺比上網Google查找解答還要更有工作效率)

※這技巧貌似叫做與AI溝通的語言邏輯?

實作

我是白鏢黨,以下用的AI是免費版的ChatGPT 3.5
(據說Claude比ChatGPT的處理能力貌似還優越?以此範例我感覺不出差別,只曉得我貼給Claude的程式碼排版會亂掉…)

以下是餵給AI的前端Html+Javascript程式碼,要交給AI撰寫程式碼(懶得自己想自己寫)的功能&需求我都寫在todo註解裡

<html>
<head>
    <title>Javascript 倒數計時更換會員條碼圖片</title>
</head>
<body> 
    <div class="my-container">
        <div><img id="img" src="https://fakeimg.pl/350x200/?text=randomText" /></div>
        <div id="timer">01:00</div>
        <button type="button" id="btnRefresh">刷新圖片</button>
    </div>

    <!--引用jQuery函式庫-->
    <script src="~/Scripts/jquery-3.4.1.js"></script>
    <script type="text/javascript">

        $(function () {
            //畫面DOM全部載入完畢便執行倒數計時函式
            countDown();

            $("#btnRefresh").click(function () {
                //重新倒數計時
                countDown();
            });
        });

        //倒數計時函式
        function countDown() {
            //todo Step 1:重置 timer 的 時間數字為 01:00

            //todo Step 2:<img>的屬性src圖片網址的text querystring隨機置換字串來達到重新從WebServer取得圖片的效果

            //todo Step 3:timer 從 01:00 開始倒數計時至 00:00 便停止倒數

            //todo Step 4:當timer倒數至 00:00 時,隔一秒後,呼叫countDown()函式再重新執行一次
        }
    </script>
</body>
</html>

以下是我給ChatGPT的提示詞

以下是ChatGPT 回覆給我的程式碼,雖然完成度很高,但執行後發現每當點擊"刷新圖片"按鈕後,倒數計時器的數字會亂跳怪怪的

<!DOCTYPE html>
<html>
<head>
    <title>Javascript 倒數計時更換會員條碼圖片</title>
</head>
<body> 
    <div class="my-container">
        <div><img id="img" src="https://fakeimg.pl/350x200/?text=randomText" /></div>
        <div id="timer">01:00</div>
        <button type="button" id="btnRefresh">刷新圖片</button>
    </div>

    <!--引用jQuery函式庫-->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script type="text/javascript">

        $(function () {
            //畫面DOM全部載入完畢便執行倒數計時函式
            countDown();

            $("#btnRefresh").click(function () {
                //重新倒數計時
                countDown();
            });
        });

        //倒數計時函式
        function countDown() {
            // Step 1: 重置 timer 的時間數字為 01:00
            $('#timer').text('01:00');

            // Step 2: <img>的屬性src圖片網址的text querystring隨機置換字串來達到重新從WebServer取得圖片的效果
            var randomText = Math.random().toString(36).substring(7);
            $('#img').attr('src', 'https://fakeimg.pl/350x200/?text=' + randomText);

            // Step 3: timer 從 01:00 開始倒數計時至 00:00 便停止倒數
            var timeLeft = 60; // 60 seconds = 01:00
            var timerInterval = setInterval(function () {
                timeLeft--;
                var minutes = Math.floor(timeLeft / 60);
                var seconds = timeLeft % 60;
                $('#timer').text(minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0'));
                if (timeLeft <= 0) {
                    clearInterval(timerInterval);
                    // Step 4: 當 timer 倒數至 00:00 時,隔一秒後,呼叫 countDown() 函式再重新執行一次
                    setTimeout(countDown, 1000);
                }
            }, 1000);
        }
    </script>
</body>
</html>

原來是Step 1的重置timer的註解,我事情交待得還不夠清楚,這部份再自行手動撰寫小補足或請ChatGPT再修正一下程式碼吧↓


<html>
<head>
    <title>Javascript 倒數計時更換會員條碼圖片</title>
</head>
<body>
    <div class="my-container">
        <div><img id="img" src="https://fakeimg.pl/350x200/?text=randomText" /></div>
        <div id="timer">01:00</div>
        <button type="button" id="btnRefresh">刷新圖片</button>
    </div>

    <!--引用jQuery函式庫-->
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script type="text/javascript">

        $(function () {
            //畫面DOM全部載入完畢便執行倒數計時函式
            countDown();

            $("#btnRefresh").click(function () {
                //重新倒數計時
                countDown();
            });
        });

        //全域變數用來追蹤倒數計時器
        var timerInterval;

        //倒數計時函式
        function countDown() {
            //如果有上一次的計時器,先清除掉
            if (timerInterval) {
                clearInterval(timerInterval);
            }

            // Step 1: 重置 timer 的 時間數字為 01:00
            $('#timer').text('01:00');

            // Step 2: <img>的屬性src圖片網址的text querystring隨機置換字串來達到重新從WebServer取得圖片的效果
            var randomText = Math.random().toString(36).substring(7);
            $('#img').attr('src', 'https://fakeimg.pl/350x200/?text=' + randomText);

            // Step 3: timer 從 01:00 開始倒數計時至 00:00 便停止倒數
            var time = 60;
            timerInterval = setInterval(function () {
                var minutes = Math.floor(time / 60);
                var seconds = time % 60;
                var formattedTime = (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
                $('#timer').text(formattedTime);
                time--;
                if (time <= 0) {
                    clearInterval(timerInterval);
                    // Step 4: 當timer倒數至 00:00 時,隔一秒後,呼叫countDown()函式再重新執行一次
                    setTimeout(function () {
                        countDown();
                    }, 1000);
                }
            }, 1000);
        }
    </script>
</body>
</html>

如此一來,倒數計時刷新圖片的功能便實作完成,至於每次ChatGPT的回覆解答若有些許不同,例如時間格式化的處理,就挑一個自己喜歡的寫法自行修改吧

2024-04-09 追記

以下是個人參考兩次ChatGPT的答覆,整理後的 Final 版程式碼,看起來較好懂,執行起來也更合理。

<html>
<head>
    <title>Javascript 倒數計時刷新條碼圖片</title>
    <!--引用fontawesome 圖示 4.7--> 
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha512-SfTiTlX6kk+qitfevl/7LibUOeJWlt9rbyDn92a1DqWOw9vWG2MFoays0sgObmWazO5BQPiFucnnEAjpAB+/Sw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <style>
    
/*定義旋轉動畫*/
@keyframes my-anime-rotate {
    from {
        transform: rotate(0deg);
    } 
    to {
        transform: rotate(360deg);
    }
}
.my-rotate {
    animation: my-anime-rotate 350ms;
}
    </style>
    
</head>
<body>
    <div class="my-container">
        <div><img class="my-img" src="https://fakeimg.pl/350x200/?text=randomNumber" /></div>
        <div class="timer">01:00</div>
        <button type="button" id="btnRefresh">
          <i class="fa fa-refresh"></i>
          刷新圖片
        </button>
    </div>
    <!--引用jQuery函式庫-->
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script type="text/javascript">

        $(function () {
            //畫面DOM全部載入完畢便執行倒數計時函式
            countDown();

            $("#btnRefresh").click(function () {
                //重新倒數計時
                countDown();
            });
        });



        //全域變數用來追蹤倒數計時器
        let timerInterval;

        //顯示 timer 的 時間
        function showCountDonwNumber(countdown_total_seconds)
        {
            let minutes = Math.floor(countdown_total_seconds / 60);//時間都是60進位
            let seconds = countdown_total_seconds % 60;//時間都是60進位

            $('.timer').text(minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0'));

        }
        //倒數計時函式
        function countDown() {
          /*旋轉圖示播放動畫*/
          let $refreshIcon = $("#btnRefresh > i");
          $refreshIcon.addClass("my-rotate");//播放css animation
          setTimeout(function () {
              $refreshIcon.removeClass("my-rotate");//移除class好讓下次用戶點擊時再度播放css動畫※css animation不像transition會反向播放動畫
          }, 350);//350ms之後,執行一次
 
            //如果有上一次的計時器,先清除掉
            if (timerInterval !== undefined) {
                clearInterval(timerInterval);
            }
            let countdown_total_seconds = 60;//要倒數的總秒數,01:00=60秒、05:00=(60*5)…依此類推
            // Step 1: 重置 timer 的 時間數字為 01:00
            showCountDonwNumber(countdown_total_seconds)

            // Step 2: <img>的屬性src圖片網址的text querystring隨機置換字串來達到重新從WebServer取得圖片的效果
            let randomNumber = Math.random();
            $('.my-img').attr('src', 'https://fakeimg.pl/350x200/?text=' + randomNumber);

            // Step 3: timer 從 01:00 開始倒數計時至 00:00 便停止倒數
            timerInterval = setInterval(function () {
                countdown_total_seconds--;//每經過1秒後先扣掉總秒數後,再顯示timer時間
                showCountDonwNumber(countdown_total_seconds);
                if (countdown_total_seconds <= 0) {
                    clearInterval(timerInterval);//停止倒數計時動作
                    // Step 4: 當timer倒數至 00:00 時,隔一秒後,呼叫countDown()函式再重新執行一次
                    setTimeout(countDown, 1000);
                }
            }, 1000);
        }</script>
</body>
</html>

線上Live Demo:https://jsfiddle.net/ShadowKao/dbfaxgsz/