Javascript 计数器 – 在重新加载后不要丢弃数值

huangapple go评论48阅读模式
英文:

Javascript Counter - Do not discard the value after a reload

问题

I'm Erik.
I'm starting programming now and I wrote a small code with the help of some tutorials on the internet and chatgpt to modify a button created on one of the platforms I use on a daily basis at work (FOP2, panel for asterisk)

This button monitors the user's status (if available or paused) and changes depending on the user's status. Basically, it monitors the user's state through changes to the selector button, and whenever a change is detected, the counter is reset. Here is the code:

let timer;
let seconds = 0;

function updateTimer() {
    const timerElement = document.querySelector('.pausa-btn__timer');
    timer = setInterval(() => {
        seconds++;
        const formattedTime = formatTime(seconds);
        timerElement.textContent = formattedTime;
    }, 1000);
}

function formatTime(seconds) {
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = seconds % 60;
    return `${padZero(hours)}:${padZero(minutes)}:${padZero(secs)}`;
}

function padZero(number) {
    return number.toString().padStart(2, '0');
}

function handlePresenceChange() {
    clearInterval(timer);
    seconds = 0;
    const presenceValue = document.querySelector('.btn.dropdown-toggle.btn-default').getAttribute('title');
    const pausaBtn = document.querySelector('.pausa-btn');
    const pausaBtnText = document.querySelector('.pausa-btn__text');
    const pausaBtnTimer = document.querySelector('.pausa-btn__timer');
    const pausaBtnIcon = document.querySelector('.pausa-btn__icon i');

    if (presenceValue !== 'Disponível') {
        pausaBtn.classList.remove('pausa-btn--livre');
        pausaBtn.classList.add('pausa-btn--pausado');
        pausaBtnText.textContent = 'Pausado';
        pausaBtnTimer.textContent = '00:00:00';
        pausaBtnIcon.textContent = 'motion_photos_pause';
    } else {
        pausaBtn.classList.remove('pausa-btn--pausado', 'pausa-btn--ocupado');
        pausaBtn.classList.add('pausa-btn--livre');
        pausaBtnText.textContent = 'Disponível';
        pausaBtnTimer.textContent = '00:00:00';
        pausaBtnIcon.textContent = 'task_alt';
    }

    updateTimer();
}

window.onload = function () {
    updateTimer();

    const observer = new MutationObserver(handlePresenceChange);
    const presenceButton = document.querySelector('.btn.dropdown-toggle.btn-default');
    observer.observe(presenceButton, { attributes: true, attributeFilter: ['title'] });
};

The code works fine, but with a small problem - every time the page is restarted, or is discarded by the browser, the counter resets. This causes confusion among users (for example, the user leaves for lunch and pauses, when he returns the count is "still" at zero).

I would like to know if it is possible for the counter value to be stored in localStorage, but that it would only be received in the case of page refreshes/reloads. And that in each change of presence, the value was still reset. For example:

I, user Erik, logged into the platform 10 minutes ago, so my counter is at 00:10:00. If I refresh the page, my counter will still be at 00:10:00. When I set a break (ex: Lunch), my counter will reset because I changed state. If I'm 5 minutes into lunch and I refresh my page, the value will still be at 00:05:00.

Complicated, right? Is this possible? Thanks in advance for all your help!

I tried to store the value in localStorage, and I ended up succeeding. However, in the handle presence change function, I defined that whenever a change was detected, the counter was reset to zero. To make my situation worse, whenever the page is refreshed, the application (FOP2) starts with the user as "Available" and then goes back to the user's state before the page is refreshed, so technically EVERY page refresh will call this function, which will discard the value of local storage and reset the counter.

英文:

I'm Erik.
I'm starting programming now and I wrote a small code with the help of some tutorials on the internet and chatgpt to modify a button created on one of the platforms I use on a daily basis at work (FOP2, panel for asterisk)

This button monitors the user's status (if available or paused) and changes depending on the user's status.
Basically, it monitors the user's state through changes to the selector button, and whenever a change is detected, the counter is reset.
Here is the code:

let timer;
let seconds = 0;
function updateTimer() {
const timerElement = document.querySelector('.pausa-btn__timer');
timer = setInterval(() => {
seconds++;
const formattedTime = formatTime(seconds);
timerElement.textContent = formattedTime;
}, 1000);
}
function formatTime(seconds) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
return `${padZero(hours)}:${padZero(minutes)}:${padZero(secs)}`;
}
function padZero(number) {
return number.toString().padStart(2, '0');
}
function handlePresenceChange() {
clearInterval(timer);
seconds = 0;
const presenceValue = document.querySelector('.btn.dropdown-toggle.btn-default').getAttribute('title');
const pausaBtn = document.querySelector('.pausa-btn');
const pausaBtnText = document.querySelector('.pausa-btn__text');
const pausaBtnTimer = document.querySelector('.pausa-btn__timer');
const pausaBtnIcon = document.querySelector('.pausa-btn__icon i');
if (presenceValue !== 'Disponível') {
pausaBtn.classList.remove('pausa-btn--livre');
pausaBtn.classList.add('pausa-btn--pausado');
pausaBtnText.textContent = 'Pausado';
pausaBtnTimer.textContent = '00:00:00';
pausaBtnIcon.textContent = 'motion_photos_pause';
} else {
pausaBtn.classList.remove('pausa-btn--pausado', 'pausa-btn--ocupado');
pausaBtn.classList.add('pausa-btn--livre');
pausaBtnText.textContent = 'Disponível';
pausaBtnTimer.textContent = '00:00:00';
pausaBtnIcon.textContent = 'task_alt';
}
updateTimer();
}
window.onload = function () {
updateTimer();
const observer = new MutationObserver(handlePresenceChange);
const presenceButton = document.querySelector('.btn.dropdown-toggle.btn-default');
observer.observe(presenceButton, { attributes: true, attributeFilter: ['title'] });
};

The code works fine, but with a small problem - every time the page is restarted, or is discarded by the browser, the counter resets.
This causes confusion among users (for example, the user leaves for lunch and pauses, when he returns the count is "still" at zero).

I would like to know if it is possible for the counter value to be stored in localStorage, but that it would only be received in the case of page refreshes/reloads.

And that in each change of presence, the value was still reset.
For example:

I, user Erik, logged into the platform 10 minutes ago, so my counter is at 00:10:00.
If I refresh the page, my counter will still be at 00:10:00.
When I set a break (ex: Lunch), my counter will reset, because I changed state.
If I'm 5 minutes into lunch and I refresh my page, the value will still be at 00:05:00.

Complicated, right?
Is this possible?
Thanks in advance for all your help!

I tried to store the value in localStorage, and I ended up succeeding.
However, in the handle presence change function, I defined that whenever a change was detected, the counter was reset to zero.

To make my situation worse, whenever the page is refreshed, the application (FOP2) starts with the user as "Available" and then goes back to the user's state before the page is refreshed, so technically EVERY page refresh will call this function, which will discard the value of localstorage and reset the counter.

答案1

得分: 2

我认为你正在寻找的解决方案是事件onBeforeUnload

如果你监听该事件,你可以将计数器存储在LocalStorage中,或在回调函数中执行所需的操作。

例如:

window.addEventListener('beforeunload', () => {
   localStorage.setItem('counter', {your_counter});
});

不幸的是,我不知道浏览器在关闭标签或执行刷新之前给你多少时间。因此,在处理异步函数时可能会出现一些问题。

如果在该事件的回调函数中返回了一些内容,浏览器会显示一个对话框,询问用户是否关闭/重新加载页面。

希望你能找到解决方案。

祝你好运!

英文:

i think the solution you are looking for is the event onBeforeUnload.

If you listen on that event, you can store the counter in the LocalStorage, or perform the needed operation in that callback function.

For example:

window.addEventListener('onbeforeunload', () => {
localStorage.setItem('counter', {your_counter});
});

Unfortunatly, i don't know, ow much time the browser gives you, until it closes the tab, or performs the refresh. So there might be some problems when working with asynchronous functions.

If you return something in the callback function of that event, the browser will show the user an dialog asking, whether to close/reload the page.

I hope you find your solution.

Glhf

答案2

得分: 1

当你声明秒数时,尝试像这样声明它:

let seconds = Number(localStorage.getItem("seconds")) || 0;

如果秒数在本地存储中存在,这将获取该值并将其转换为数字,因为localStorage保存的是字符串,而你需要它作为数值类型。

|| 0 基本上是说如果localStorage中不存在秒数,就将秒数设置为0。

然后将这个函数用作你的updateTimer函数,每次更新时将秒数设置到localStorage中。

function updateTimer() {
    const timerElement = document.querySelector('.pausa-btn__timer');
    timer = setInterval(() => {
        seconds++;
        localStorage.setItem("seconds", seconds);
        const formattedTime = formatTime(seconds);
        timerElement.textContent = formattedTime;
    }, 1000);
}
英文:

When you declare seconds, try declaring it like this instead:

let seconds = Number(localStorage.getItem("seconds")) || 0;

If seconds exists in local storage, this will take that value and convert it to a number because localStorage saves strings and you need that as a numerical type.

The || 0 basically says if seconds doesn't exist in localStorage, set seconds to 0.

Then use this as your updateTimer function to set seconds in the localStorage every time it is updated.

function updateTimer() {
const timerElement = document.querySelector('.pausa-btn__timer');
timer = setInterval(() => {
seconds++;
localStorage.setItem("seconds",seconds);
const formattedTime = formatTime(seconds);
timerElement.textContent = formattedTime;
}, 1000);
}

huangapple
  • 本文由 发表于 2023年7月17日 21:38:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76705033.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定