用户输入未来日期变量的计时器
A timer where user enters variable for future date
如果有人能为我正在进行的学校项目指明正确的方向,那就太好了。下面你会看到一个超级简单的计时器,我在一个名为 Web Dev 的 youtuber 的教程的帮助下制作的。该示例将新年前夜硬编码到脚本中。但我想更进一步,要求用户输入他们的特殊日期 - 例如,让计时器倒计时到他们的生日。
到目前为止,我已经设法使计数器从给定日期开始倒计时,而不仅仅是硬编码日期,而且我已经设法为用户生成的数据创建了输入表单。
但是一旦我试图将两者结合起来,就出了问题。我猜我需要将用户生成的数字输入到其中一个函数中,而不仅仅是将它们列在顶部作为 let、var 和 const?
哦,理想情况下,我应该想出一种方法,让输入表单在用户单击 'enter' 按钮后立即消失。
对于我之前的 Whosebug 问题,有人非常友好地为我编写了完整的答案。但由于这在很大程度上是一个学习过程,如果能提供一些正确方向的提示和指示,我会非常满意。
let userYear = userYearEntered;
let userMonth = userMonthEntered;
let userDay = userDayEntered;
const userDate = new Date(userYear, userMonth, userDay, 0, 0, 0);
const userOccasion = 'I need to present this project';
function enterSpecialDate() {
var userYearEntered = document.getElementById('userYear').value;
console.log(userYearEntered);
var userMonthEntered = document.getElementById('userMonth').value;
console.log(userMonthEntered);
var userDayEntered = document.getElementById('userDay').value;
console.log(userDayEntered);
}
/*create countdown timer using substraction*/
function updateCountdowntime() {
const currentTime = new Date();
const diff = userDate - currentTime;
console.log(diff);
/* we've been given the difference in milliseconds, so some division is needed */
const d = Math.floor(diff / 1000 / 60 / 60 / 24);
const h = Math.floor(diff / 1000 / 60 / 60) % 24;
const m = Math.floor(diff / 1000 / 60) % 60;
const s = Math.floor(diff / 1000) % 60;
/* send values back into HTML document */
document.getElementById('days').innerHTML = d;
document.getElementById('hours').innerHTML = h;
document.getElementById('minutes').innerHTML = m;
document.getElementById('seconds').innerHTML = s;
document.getElementById('userOccasion').innerHTML = userOccasion;
}
setInterval(updateCountdowntime, 1000);
* {
box-sizing: border-box;
}
body {
background-color: rgb(44, 48, 48);
font-family: sans-serif;
color: rgb(239, 239, 239);
font-size: 3em;
font-weight: 300;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
div {
margin-top: 1vh;
}
label {
font-size: 0.4em;
}
<div>
<label for="userYear">year</label>
<input id="userYear" type="number" value="" placeholder="e.g. 2021">
<label for="userMonth">month</label>
<input id="userMonth" type="number" value="" placeholder="e.g. 8">
<label for="userDay">day</label>
<input id="userDay" type="number" value="" placeholder="17">
<button onclick="enterSpecialDate()">Enter</button>
</div>
<div>
<p>there are</p>
<div class="time">
<span id="days"></span>
<span>days</span>
</div>
<div class="time">
<span id="hours"></span>
<span>hours</span>
</div>
<div class="time">
<span id="minutes"></span>
<span>minutes</span>
</div>
<div class="time">
<span id="seconds"></span>
<span>seconds</span>
</div>
<p>until <span id="userOccasion"></span></p>
</div>
您应该能够通过几个简单的提示或文本输入字段来完成此操作。
例如:
要求用户输入一个月,然后是一天,然后是一年。
您将这些输入保存为单独的变量。然后你使用 const newYearTime 但不是使用硬编码日期,而是使用变量作为日期。
现在你有 const newYearTime = new Date('january' ,1,当前年份等...)
根据提示你可以做:
let year = number(prompt: enter year)
let day = number(prompt: enter day)
let month = prompt: enter month
然后您只需将 const newYearTime 更改为
Const newYearTime = new Date(month, day, year)
我知道我的代码不正确。我不在我的电脑前,所以我没有我的编辑来写它应该的样子,但我想你明白我的意思了。
我也是 javascript 的新手,但如果我认为我知道该怎么做,我会尽力提供帮助
Fraku 的回答似乎符合您的要求。为了补充他的回答,您还想使用 LocalStorage。
因此,您可以将用户输入的特殊日期存储到 LocalStorage 中。所以你不需要每次用户进入页面时都询问用户。
以下是如何将数据存储到 LocalStorage 的示例。 dtUserDate 是用户输入的特殊日期。
window.localStorage.setItem("Some Name", JSON.stringify( { "SpecialDate" : dtUserDate } ));
您也可以仅使用一个变量和 .substring JS 方法来解析用户的日期字符串。会有点难以阅读,但如果存储是一个因素,你可以做到这一点。例如,将占位符与要求 MM/DD/YYYY 的输入一起使用,您可以使用:
userDate.substring(0, 2);
= 月
userDate.substring(3, 5);
= 天
userDate.substring(6, userDate.length);
= 年
并获取日期:
var newYearTime = new Date(userDate.substring(6, userDate.length), (userDate.substring(0, 2) - 1), userDate.substring(3, 5));
所以我在我的编辑器中重新创建了您的代码。正如我现在看到的那样,您遇到的问题是当用户按下回车键(或单击它)时它不会更新 html。
你在测试的时候检查过你的主机吗?因为我是第一次尝试打开控制台,马上就发现了问题:
Uncaught ReferenceError: userYearEntered is not defined
有了这个你应该可以自己找到问题的答案。我会给你一点提示:第一次加载页面时,var userYearEntered 没有值。这从一开始就破坏了您的代码。想一想如何改变这一点。这个问题有多种解决方案。
此外,我看到您想在按下或单击输入后立即隐藏输入。这可以很容易地完成,只需在输入的父 div 上添加一个隐藏的 属性。只要 onclick 没有发生,它就是错误的。如果发生了 onclick,则将其更改为 true。
这是为最终用户使用 date input, which is more semantic, accessible and more comfortable to use 的解决方案。
它使用内联样式在表单和倒计时之间切换,但同样可以使用 classList
.toggle()
和 class 来显示或隐藏特定视图。
你还应该实现某种形式的错误处理(例如,现在它在没有设置日期的情况下点击按钮时什么都不做,它还支持过去的日期,导致负数)。
关于 setInterval()
的注释: 这还不够 reliable/exact,可能会导致秒数被跳过或更改得太快。有关此问题的更多背景知识和可靠的解决方案,我推荐视频 "JavaScript 以艰难的方式反击 - HTTP 203
" 在 YouTube 上。该解决方案也可作为 reusable code snippet in this gist。
现在您可以很容易地为场合文本实现额外的输入。
let userDate = null;
const userOccasion = 'I need to present this project';
const userDateInput = document.getElementById('user-date');
const formView = document.getElementById('form-view');
const counterView = document.getElementById('counter-view');
function enterSpecialDate() {
userDate = userDateInput.valueAsDate;
if (userDate) {
// fire the function once, so we start with filled in numbers right away
updateCountdowntime();
// see the note on setInterval() in the answer
setInterval(updateCountdowntime, 1000);
// switch between the form and the counter view
formView.style.display = 'none';
counterView.style.display = 'block';
}
}
/*create countdown timer using substraction*/
function updateCountdowntime() {
const currentTime = new Date();
const diff = userDate - currentTime;
/* we've been given the difference in milliseconds, so some division is needed */
const d = Math.floor(diff / 1000 / 60 / 60 / 24);
const h = Math.floor(diff / 1000 / 60 / 60) % 24;
const m = Math.floor(diff / 1000 / 60) % 60;
const s = Math.floor(diff / 1000) % 60;
/* send values back into HTML document */
document.getElementById('days').innerHTML = d;
document.getElementById('hours').innerHTML = h;
document.getElementById('minutes').innerHTML = m;
document.getElementById('seconds').innerHTML = s;
document.getElementById('userOccasion').innerHTML = userOccasion;
}
* {
box-sizing: border-box;
}
body {
background-color: rgb(44, 48, 48);
font-family: sans-serif;
color: rgb(239, 239, 239);
font-size: 2em;
font-weight: 300;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
div {
margin-top: 1vh;
}
<div id="form-view">
<input type="date" id="user-date">
<button onclick="enterSpecialDate()">Enter</button>
</div>
<div id="counter-view" style="display: none;">
<p>there are</p>
<div class="time">
<span id="days"></span>
<span>days</span>
</div>
<div class="time">
<span id="hours"></span>
<span>hours</span>
</div>
<div class="time">
<span id="minutes"></span>
<span>minutes</span>
</div>
<div class="time">
<span id="seconds"></span>
<span>seconds</span>
</div>
<p>until <span id="userOccasion"></span></p>
</div>
如果有人能为我正在进行的学校项目指明正确的方向,那就太好了。下面你会看到一个超级简单的计时器,我在一个名为 Web Dev 的 youtuber 的教程的帮助下制作的。该示例将新年前夜硬编码到脚本中。但我想更进一步,要求用户输入他们的特殊日期 - 例如,让计时器倒计时到他们的生日。
到目前为止,我已经设法使计数器从给定日期开始倒计时,而不仅仅是硬编码日期,而且我已经设法为用户生成的数据创建了输入表单。 但是一旦我试图将两者结合起来,就出了问题。我猜我需要将用户生成的数字输入到其中一个函数中,而不仅仅是将它们列在顶部作为 let、var 和 const?
哦,理想情况下,我应该想出一种方法,让输入表单在用户单击 'enter' 按钮后立即消失。
对于我之前的 Whosebug 问题,有人非常友好地为我编写了完整的答案。但由于这在很大程度上是一个学习过程,如果能提供一些正确方向的提示和指示,我会非常满意。
let userYear = userYearEntered;
let userMonth = userMonthEntered;
let userDay = userDayEntered;
const userDate = new Date(userYear, userMonth, userDay, 0, 0, 0);
const userOccasion = 'I need to present this project';
function enterSpecialDate() {
var userYearEntered = document.getElementById('userYear').value;
console.log(userYearEntered);
var userMonthEntered = document.getElementById('userMonth').value;
console.log(userMonthEntered);
var userDayEntered = document.getElementById('userDay').value;
console.log(userDayEntered);
}
/*create countdown timer using substraction*/
function updateCountdowntime() {
const currentTime = new Date();
const diff = userDate - currentTime;
console.log(diff);
/* we've been given the difference in milliseconds, so some division is needed */
const d = Math.floor(diff / 1000 / 60 / 60 / 24);
const h = Math.floor(diff / 1000 / 60 / 60) % 24;
const m = Math.floor(diff / 1000 / 60) % 60;
const s = Math.floor(diff / 1000) % 60;
/* send values back into HTML document */
document.getElementById('days').innerHTML = d;
document.getElementById('hours').innerHTML = h;
document.getElementById('minutes').innerHTML = m;
document.getElementById('seconds').innerHTML = s;
document.getElementById('userOccasion').innerHTML = userOccasion;
}
setInterval(updateCountdowntime, 1000);
* {
box-sizing: border-box;
}
body {
background-color: rgb(44, 48, 48);
font-family: sans-serif;
color: rgb(239, 239, 239);
font-size: 3em;
font-weight: 300;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
div {
margin-top: 1vh;
}
label {
font-size: 0.4em;
}
<div>
<label for="userYear">year</label>
<input id="userYear" type="number" value="" placeholder="e.g. 2021">
<label for="userMonth">month</label>
<input id="userMonth" type="number" value="" placeholder="e.g. 8">
<label for="userDay">day</label>
<input id="userDay" type="number" value="" placeholder="17">
<button onclick="enterSpecialDate()">Enter</button>
</div>
<div>
<p>there are</p>
<div class="time">
<span id="days"></span>
<span>days</span>
</div>
<div class="time">
<span id="hours"></span>
<span>hours</span>
</div>
<div class="time">
<span id="minutes"></span>
<span>minutes</span>
</div>
<div class="time">
<span id="seconds"></span>
<span>seconds</span>
</div>
<p>until <span id="userOccasion"></span></p>
</div>
您应该能够通过几个简单的提示或文本输入字段来完成此操作。
例如:
要求用户输入一个月,然后是一天,然后是一年。 您将这些输入保存为单独的变量。然后你使用 const newYearTime 但不是使用硬编码日期,而是使用变量作为日期。
现在你有 const newYearTime = new Date('january' ,1,当前年份等...)
根据提示你可以做:
let year = number(prompt: enter year)
let day = number(prompt: enter day)
let month = prompt: enter month
然后您只需将 const newYearTime 更改为
Const newYearTime = new Date(month, day, year)
我知道我的代码不正确。我不在我的电脑前,所以我没有我的编辑来写它应该的样子,但我想你明白我的意思了。
我也是 javascript 的新手,但如果我认为我知道该怎么做,我会尽力提供帮助
Fraku 的回答似乎符合您的要求。为了补充他的回答,您还想使用 LocalStorage。
因此,您可以将用户输入的特殊日期存储到 LocalStorage 中。所以你不需要每次用户进入页面时都询问用户。
以下是如何将数据存储到 LocalStorage 的示例。 dtUserDate 是用户输入的特殊日期。
window.localStorage.setItem("Some Name", JSON.stringify( { "SpecialDate" : dtUserDate } ));
您也可以仅使用一个变量和 .substring JS 方法来解析用户的日期字符串。会有点难以阅读,但如果存储是一个因素,你可以做到这一点。例如,将占位符与要求 MM/DD/YYYY 的输入一起使用,您可以使用:
userDate.substring(0, 2);
= 月
userDate.substring(3, 5);
= 天
userDate.substring(6, userDate.length);
= 年
并获取日期:
var newYearTime = new Date(userDate.substring(6, userDate.length), (userDate.substring(0, 2) - 1), userDate.substring(3, 5));
所以我在我的编辑器中重新创建了您的代码。正如我现在看到的那样,您遇到的问题是当用户按下回车键(或单击它)时它不会更新 html。
你在测试的时候检查过你的主机吗?因为我是第一次尝试打开控制台,马上就发现了问题:
Uncaught ReferenceError: userYearEntered is not defined
有了这个你应该可以自己找到问题的答案。我会给你一点提示:第一次加载页面时,var userYearEntered 没有值。这从一开始就破坏了您的代码。想一想如何改变这一点。这个问题有多种解决方案。
此外,我看到您想在按下或单击输入后立即隐藏输入。这可以很容易地完成,只需在输入的父 div 上添加一个隐藏的 属性。只要 onclick 没有发生,它就是错误的。如果发生了 onclick,则将其更改为 true。
这是为最终用户使用 date input, which is more semantic, accessible and more comfortable to use 的解决方案。
它使用内联样式在表单和倒计时之间切换,但同样可以使用 classList
.toggle()
和 class 来显示或隐藏特定视图。
你还应该实现某种形式的错误处理(例如,现在它在没有设置日期的情况下点击按钮时什么都不做,它还支持过去的日期,导致负数)。
关于 setInterval()
的注释: 这还不够 reliable/exact,可能会导致秒数被跳过或更改得太快。有关此问题的更多背景知识和可靠的解决方案,我推荐视频 "JavaScript 以艰难的方式反击 - HTTP 203
" 在 YouTube 上。该解决方案也可作为 reusable code snippet in this gist。
现在您可以很容易地为场合文本实现额外的输入。
let userDate = null;
const userOccasion = 'I need to present this project';
const userDateInput = document.getElementById('user-date');
const formView = document.getElementById('form-view');
const counterView = document.getElementById('counter-view');
function enterSpecialDate() {
userDate = userDateInput.valueAsDate;
if (userDate) {
// fire the function once, so we start with filled in numbers right away
updateCountdowntime();
// see the note on setInterval() in the answer
setInterval(updateCountdowntime, 1000);
// switch between the form and the counter view
formView.style.display = 'none';
counterView.style.display = 'block';
}
}
/*create countdown timer using substraction*/
function updateCountdowntime() {
const currentTime = new Date();
const diff = userDate - currentTime;
/* we've been given the difference in milliseconds, so some division is needed */
const d = Math.floor(diff / 1000 / 60 / 60 / 24);
const h = Math.floor(diff / 1000 / 60 / 60) % 24;
const m = Math.floor(diff / 1000 / 60) % 60;
const s = Math.floor(diff / 1000) % 60;
/* send values back into HTML document */
document.getElementById('days').innerHTML = d;
document.getElementById('hours').innerHTML = h;
document.getElementById('minutes').innerHTML = m;
document.getElementById('seconds').innerHTML = s;
document.getElementById('userOccasion').innerHTML = userOccasion;
}
* {
box-sizing: border-box;
}
body {
background-color: rgb(44, 48, 48);
font-family: sans-serif;
color: rgb(239, 239, 239);
font-size: 2em;
font-weight: 300;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
div {
margin-top: 1vh;
}
<div id="form-view">
<input type="date" id="user-date">
<button onclick="enterSpecialDate()">Enter</button>
</div>
<div id="counter-view" style="display: none;">
<p>there are</p>
<div class="time">
<span id="days"></span>
<span>days</span>
</div>
<div class="time">
<span id="hours"></span>
<span>hours</span>
</div>
<div class="time">
<span id="minutes"></span>
<span>minutes</span>
</div>
<div class="time">
<span id="seconds"></span>
<span>seconds</span>
</div>
<p>until <span id="userOccasion"></span></p>
</div>