【问题标题】::: jQuery :: OnChange update timer count down:: jQuery :: OnChange 更新计时器倒计时
【发布时间】:2021-12-29 07:12:47
【问题描述】:

我正在使用简单的 svg 倒数计时器(来源:Mateusz Rybczonec

我想将下面的代码修改为:

  • 选择下拉选项更改计时器值并且计时器必须重置

用下面的代码试过没有运气:(

第一次选择它工作正常,重新选择不同的 值,两个值都在圆圈内。

jsFiddle

HTML:

<select id="settings-select-popup-autoclose">
    <option value="-- Select --" selected="selected">-- Select --</option>
    <option value="5">5 seconds</option>
    <option value="10">10 seconds</option>
    <option value="15">15 seconds</option>
    <option value="20">20 seconds</option>
    <option value="25">25 seconds</option>
    <option value="30">30 seconds</option>
    <option value="35">25 seconds</option>
    <option value="40">40 seconds</option>
    <option value="45">45 seconds</option>
    <option value="50">50 seconds</option>
    <option value="55">55 seconds</option>
    <option value="60">60 seconds</option>
</select>
<div id="popupAutoCloseText"></div>

JS代码:

// Credit: Mateusz Rybczonec

jQuery(document).on('change', '#settings-select-popup-autoclose', function (e) {
    
    jQuery('#popupAutoCloseText #app').remove();

    var __selected_time = jQuery(this).find('option:selected').val();

    const FULL_DASH_ARRAY = 283;
    const WARNING_THRESHOLD = 10;
    const ALERT_THRESHOLD = 5;

    const COLOR_CODES = {
        info: {
            color: "green"
        },
        warning: {
            color: "orange",
            threshold: WARNING_THRESHOLD
        },
        alert: {
            color: "red",
            threshold: ALERT_THRESHOLD
        }
    };

    const TIME_LIMIT = __selected_time;
    let timePassed = 0;
    let timeLeft = TIME_LIMIT;
    let timerInterval = null;
    let remainingPathColor = COLOR_CODES.info.color;

jQuery('#popupAutoCloseText').append(`
            <div id="app">
                <div id="popupAutoCloseText">
                    <span class="timer-text">Popup closes in </span>
                    <span class="base-timer">
                        <svg class="base-timer__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><g class="base-timer__circle"><circle class="base-timer__path-elapsed" cx="50" cy="50" r="45"></circle><path id="base-timer-path-remaining" stroke-dasharray="283" class="base-timer__path-remaining ${remainingPathColor}" d=" M 50, 50 m -45, 0 a 45,45 0 1,0 90,0 a 45,45 0 1,0 -90,0"></path></g></svg>
                        <span id="base-timer-label" class="base-timer__label">${formatTime(timeLeft)}</span>
                    </span>
                    <span class="timer-text">seconds</span>
                </div>
            </div>
        `);

    startTimer();

    function onTimesUp() {
        clearInterval(timerInterval);
    }

    function startTimer() {
        timerInterval = setInterval(() => {
            timePassed = timePassed += 1;
            timeLeft = TIME_LIMIT - timePassed;
            document.getElementById("base-timer-label").innerHTML = formatTime(
                timeLeft
            );
            setCircleDasharray();
            setRemainingPathColor(timeLeft);

            if (timeLeft === 0) {
                onTimesUp();
            }
        }, 1000);
    }

    function formatTime(time) {
        const minutes = Math.floor(time / 60);
        let seconds = time % 60;

        if (seconds < 10) {
            seconds = `0${seconds}`;
        }

        //return `${minutes}:${seconds}`;
        return `${seconds}`;
    }

    function setRemainingPathColor(timeLeft) {
        const { alert, warning, info } = COLOR_CODES;
        if (timeLeft <= alert.threshold) {
            document
                .getElementById("base-timer-path-remaining")
                .classList.remove(warning.color);
            document
                .getElementById("base-timer-path-remaining")
                .classList.add(alert.color);
        } else if (timeLeft <= warning.threshold) {
            document
                .getElementById("base-timer-path-remaining")
                .classList.remove(info.color);
            document
                .getElementById("base-timer-path-remaining")
                .classList.add(warning.color);
        }
    }

    function calculateTimeFraction() {
        const rawTimeFraction = timeLeft / TIME_LIMIT;
        return rawTimeFraction - (1 / TIME_LIMIT) * (1 - rawTimeFraction);
    }

    function setCircleDasharray() {
        const circleDasharray = `${(
            calculateTimeFraction() * FULL_DASH_ARRAY
        ).toFixed(0)} 283`;
        document
            .getElementById("base-timer-path-remaining")
            .setAttribute("stroke-dasharray", circleDasharray);
    }
});

【问题讨论】:

标签: javascript jquery


【解决方案1】:

您需要在每次更改下拉菜单中的选择时清除 setInterval。最简单的方法是为区间声明一个变量

在 .onChange 范围之外的最顶部声明​​它

var inter = null;

在启动计时器之前清除它很重要

 if(inter){
        clearInterval(inter);
  }
 
  inter = startTimer();

最后在 startTimer 函数中返回 timeInterval

function startTimer() {
    timerInterval = setInterval(() => {
        timePassed = timePassed += 1;
        timeLeft = TIME_LIMIT - timePassed;
        document.getElementById("base-timer-label").innerHTML = formatTime(
            timeLeft
        );
        setCircleDasharray();
        setRemainingPathColor(timeLeft);

        if (timeLeft === 0) {
            onTimesUp();
        }
    }, 1000);

return timerInterval;
}

在此处查看工作示例 https://jsfiddle.net/npvL7kcf/2/

【讨论】:

  • 感谢@keysl,我接受并支持您的精彩提示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多