Vanilla JS 闹钟:范围和增量问题

Vanilla JS Alarm Clock: Scope and Increment Questions

我的闹钟有 2 个问题。

1)当小时增加或减少到12点以上时,我想从上午切换到下午。问题是我调用 today.getHours(); 的地方是在另一个函数中。我的递增按钮功能(到 increase/decrease)在该功能之外,当移动到时钟功能内并保持 today.getHours() 时,不起作用,所以我不能说小时数何时大于 12,切换到下午。再次调用 getHours 似乎是多余的。有没有人对如何在香草 JS 中解决这个问题有任何建议?有更好的方法吗?

2)点击时,分钟减少增量按钮给出负值。我知道这可能有一个简单的解决方案,但我想我已经盯着它看太久了。

//Select Elements
const alarm_time = document.getElementById('alarmTime');
const set_alarm = document.getElementById('setAlarm');
const alarm_alert = document.getElementById('alarmAlert');
const hr_increase= document.getElementById('hourIncrease');
const hr_decrease = document.getElementById('hourDecrease');
const min_increase= document.getElementById('minuteIncrease');
const min_decrease = document.getElementById('minuteDecrease');
const increment = document.querySelectorAll('.increment');

//Variables
let hr;
let min;
let TOD;
let alarmHr=0;
let alarmMin=0;
let alarmTOD="AM";
let alarmActive=false;

//Alarm Sound
let sound = new Audio("https://res.cloudinary.com/saveallthethings/video/upload/v1565033348/Free%20Music%20Downloads/bensound-hey_vunrwo.mp3");

//Alarm Function
if (alarmHr== hr && parseInt(alarmMin) == min && alarmTOD == TOD){
    sound.play();
    card.classList.add("blinkingAlarm");
}

//Get Time
function clock(){
  //Display Greeting, Time and Date
  let today = new Date();
  let year = today.getFullYear();
  let date = today.getDate();
  let hours = today.getHours(); 
  let minutes = today.getMinutes();

  //Specify Am or PM, and populate greeting
  if (hours >= 17){
    timeofDay = "PM";
  } else if (hours >= 12 && hours < 17){
    timeofDay = "PM";
  } else {
    timeofDay = " AM";
  }

  //Convert Hours to 12hr Format
  if (hours>12){
    hours = hours - 12;
  }
  else if (hours===0){
    hours = 12; 
  }
  
  //For single digit minutes, add a zero 
  if (minutes<10){
    minutes = "0" + minutes;
  }
  else {
    minutes = minutes;
  }
  
  if (alarm_time.classList.contains("blinkingText")){
    alarm_time.innerHTML = (alarmHr + ":" + alarmMin + alarmTOD);
    }else{alarm_time.innerHTML = (hours + ":" + minutes + timeofDay);}

}//Closing Brackets for clock fnc

//Set Interval to Update Time
setInterval('clock()', 500);

//Count Clicks on Set Alarm Btn
let clickCounter = 0;
set_alarm.onclick = function() {
  clickCounter += 1;
  //Second Click sets the alarm, says "Alarm set to"
    if((clickCounter % 2) === 0){
    alarm_time.classList.remove("blinkingText");
    alarmActive = true;  
    if (alarmHr == 0 && alarmMin == 0){
      alarm_alert.innerHTML = "no alarm set";
    }else{
      alarm_alert.innerHTML = "alarm set for  "+  alarmHr +":" + alarmMin + alarmTOD;
    }
    //Loop that disables and hides buttons
    for (var i = 0; i < increment.length; i++) {
      hourIncrease.classList.remove("visibility");
      hourDecrease.classList.remove("visibility");
      minuteIncrease.classList.remove("visibility");
      minuteDecrease.classList.remove("visibility");
      document.getElementById("hourIncrease").disabled = true;
      document.getElementById("hourDecrease").disabled = true;
      document.getElementById("minuteIncrease").disabled = true;
      document.getElementById("minuteDecrease").disabled = true;
        }                    
    } else {
        alarm_time.classList.add("blinkingText");
        //Loop Over the Node List for increment
        for (var i = 0; i < increment.length; i++) {
          hourIncrease.classList.add("visibility");
          hourDecrease.classList.add("visibility");
          minuteIncrease.classList.add("visibility");
          minuteDecrease.classList.add("visibility");
          document.getElementById("hourIncrease").disabled = false;
          document.getElementById("hourDecrease").disabled = false;
          document.getElementById("minuteIncrease").disabled = false;
          document.getElementById("minuteDecrease").disabled = false;
        }                        
    }
  };

//Turn off alarm
dismiss.onclick = function() {
  if(alarmActive = "true"){
    alarmActive ="false"
    alarmHr = 0;
    alarmMin = 0;
    alarmTOD = "AM";   
    alarm_alert.innerHTML = "no alarm set";
    sound.pause();
    alarm_time.classList.remove("blinkingText");
    //Loop that disables and hides buttons
    for (var i = 0; i < increment.length; i++) {
      hourIncrease.classList.remove("visibility");
      hourDecrease.classList.remove("visibility");
      minuteIncrease.classList.remove("visibility");
      minuteDecrease.classList.remove("visibility");
      document.getElementById("hourIncrease").disabled = true;
      document.getElementById("hourDecrease").disabled = true;
      document.getElementById("minuteIncrease").disabled = true;
      document.getElementById("minuteDecrease").disabled = true;
        }                        
  }
};

hr_increase.onclick = function() { 
  alarmHr++;
  if (alarmHr > 12){
    alarmHr= alarmHr - 12;
  }
}

hr_decrease.onclick = function() { 
  alarmHr--;
  if (alarmHr <= 0){
    alarmHr= alarmHr + 12;
  }
  console.log(alarmHr);}; 

min_increase.onclick = function() { 
  alarmMin++;
  if (alarmMin < 10){
      alarmMin= "0" + alarmMin;
    }
  if(alarmMin > 59){
    alarmMin= alarmMin-60 ;
  }
  if(alarmMin == 0){
    alarmMin= "00";
  }

}

min_decrease.onclick = function() { 
  alarmMin--;
  if (alarmMin < 10){
    alarmMin= "0" + minutes;
  }
  if (alarmMin < 0){
    alarmMin= alarmMin % 60;
  }
  }; 
@import url('https://fonts.googleapis.com/css?family=Montserrat:900|Open+Sans:800|Source+Sans+Pro:300');


html, body {
  height: 100%;
  font-family: 'Source Sans Pro', sans-serif;
  font-size:15px;
}

.card_container{
  height:100vh;
}
.center{
    display:flex;
    justify-content:center;
    align-items:center;
}

.card{
  border-radius:15px;
  background-color: rgba(254, 253, 253,0.8);
  box-shadow: 0px 0px 51px -3px rgba(0,0,0,0.13);
  max-width:22rem;
  border:solid rgba(254, 253, 253,0.8) 0.1px;
}

.blinkingAlarm{
  animation:blinkingAlarm 1.2s ease-in-out infinite;
}

@keyframes blinkingAlarm{
      50%{
           border:solid white 7px;}
 }

.card_inner{
  border-radius:15px;
  margin:.75rem;
}


.card_currentContainer{
  border-radius:15px;
  margin-bottom:1rem;
}

.card_alarmContainer {
  color:#7E7E7E;
  background:#fff;
  text-align:center;
}


.card_alarmContainer{
   flex-direction:column;
   border-radius:15px;
}

.alarmOptions{
  display:flex;
  color:#7E7E7E;
  padding-top:.5rem;
  padding-bottom:.5rem;
}

.blinkingText{
  animation:blinkingText 1.6s linear infinite;
}

@keyframes blinkingText{
      50%{opacity:0.3;}
}

.setBox{
  flex-direction:column;
  padding-left:.5rem;
  padding-right:.5rem;
  padding-top:0;
}

.button {
  display:block;
  border-style:none;
  margin: 0px 0px;
  padding:0px;
}

.increment{
  font-size:1rem;
  border:none;
  background: rgba(254, 253, 253,0.8);
  color:#7E7E7E;
  font-family: 'Source Sans Pro', sans-serif;
  cursor: pointer;
  visibility:hidden;
}

.increment:hover{
  cursor:pointer;
  color:black;
  border-style:none;
}

.visibility{
  visibility:visible;
}
.alarmBox{
  padding-bottom:.2rem;
}

.alarmTime{

  font-size:2rem;
  line-height:1rem;
  padding-top:.7rem;
}

.alarmAlert{
  font-size:.8rem;
  text-transform:uppercase;
  padding-top:.5rem;
}

.card_buttonsContainer{
  width:100%;
  margin:1rem 0rem;
  justify-content:space-between;
  flex-wrap:wrap;
}

.btn{
  height:3rem;
  width:8rem;
}

#setAlarm{
  transition: .2s;
  color:#fff; 
  cursor:pointer; 
  border-radius:15px;
    background: linear-gradient(to left, #ff7e5f , #feb47b); 
  padding-right:.5rem;
  padding-left:.5rem;
  font-size:1.5rem; 
  margin-right:0.3rem;
}

#setAlarm:hover{
  border-radius:20px;
  opacity: .8;
}

#dismiss{
  transition: .2s;
  font-size:1.5rem; 
  color:#fff; 
  border-radius:15px; 
  cursor:pointer; 
  background: linear-gradient(to left, #64B1F2 , #00DBF3); 
  padding-right:.5rem;
  padding-left:.5rem;
  margin-left:0.3rem;
}

#dismiss:hover{
  border-radius:20px;
  opacity: .8;
}

/***Media Queries****/
@media only screen and (max-width:332px) {
  .current_greetings{
    text-align:center;
  }
  .card_buttonsContainer{
     justify-content:center;
  }
  .btn{
    margin-bottom:.5rem;
  }
}  
<div class="card_container center">  
  <div class ="card">
    <div class="card_inner">
      <div class="card_alarmContainer center"> 
        <div class="alarmOptions ">
          <div class="setBox center">
            <button class="increment center" id="hourIncrease" disabled>&#x2b;</button>
            <button class="increment center" id="hourDecrease" disabled>&#x2212;</button>
          </div>
          <div class="alarmBox">
          <div class="alarmTime center" id="alarmTime"></div>
          <div class="alarmAlert" id="alarmAlert">no alarm set</div>
            </div>
          <div class="setBox center">
            <button class="increment center" id="minuteIncrease" disabled>&#x2b;</button>
            <button class="increment center" id="minuteDecrease" disabled>&#x2212;</button>
          </div>
          
        </div>
      </div>
      <div class="card_buttonsContainer center">
        <div class ="buttonBox center">
          <div class="btn center" id="setAlarm">Set Alarm</div>
        </div>
        <div class ="buttonBox center">
          <div class="btn center" id="dismiss">Dismiss</div>
        </div>
      </div>
    </div>
  </div>
</div>

在您的代码中,您需要在分钟变化时增加和减少小时。我还建议将小时增加和小时减少提取到函数中(我有一个工作解决方案的示例代码),这样您就可以在分钟增加和减少函数中使用它们来增加或减少时间。我还建议使用一个功能来更改一天中的闹钟时间,这样您就可以在增加小时数和减少小时数的功能中使用它。您的闹钟小时初始值为 0,但没有 0 小时。我建议从 12 开始设置闹钟时间。我在我的示例代码中更新了所有这些

更新 TOD 的方法是在小时增加时检查新小时是否为 12,然后切换 TOD。在减少时,您检查新小时是否为 11,然后切换 TOD。请参阅我的示例工作代码!

//Select Elements
const alarm_time = document.getElementById('alarmTime');
const set_alarm = document.getElementById('setAlarm');
const alarm_alert = document.getElementById('alarmAlert');
const hr_increase= document.getElementById('hourIncrease');
const hr_decrease = document.getElementById('hourDecrease');
const min_increase= document.getElementById('minuteIncrease');
const min_decrease = document.getElementById('minuteDecrease');
const increment = document.querySelectorAll('.increment');

//Variables
let hr;
let min;
let TOD;
let alarmHr=12;
let alarmMin=0;
let alarmTOD="AM";
let alarmActive=false;

//Alarm Sound
let sound = new Audio("https://res.cloudinary.com/saveallthethings/video/upload/v1565033348/Free%20Music%20Downloads/bensound-hey_vunrwo.mp3");

//Alarm Function
if (alarmHr== hr && parseInt(alarmMin) == min && alarmTOD == TOD){
    sound.play();
    card.classList.add("blinkingAlarm");
}

function toggleAlarmTOD() {
  if(alarmTOD === "AM") {
     alarmTOD = "PM"
  } else {
     alarmTOD = "AM"
  }
}

function increaseHr() {
  alarmHr++;
  if(alarmHr === 12) {
    toggleAlarmTOD();
  } else if (alarmHr > 12){
    alarmHr = alarmHr - 12;
  }
}

function decreaseHr() {
  alarmHr--;
  if(alarmHr <= 0) {
    alarmHr = alarmHr + 12;
  } else if(alarmHr === 11) {
    toggleAlarmTOD();
  }
}

//Get Time
function clock(){
  //Display Greeting, Time and Date
  let today = new Date();
  let year = today.getFullYear();
  let date = today.getDate();
  let hours = today.getHours(); 
  let minutes = today.getMinutes();

  //Specify Am or PM, and populate greeting
  if(hours >= 12){
    timeofDay = "PM";
  } else {
    timeofDay = " AM";
  }

  //Convert Hours to 12hr Format
  if (hours>12){
    hours = hours - 12;
  }
  else if (hours===0){
    hours = 12; 
  }
  
  //For single digit minutes, add a zero 
  if (minutes < 10) {
    minutes = "0" + minutes;
  }
  else {
    minutes = minutes;
  }
  
  if (alarm_time.classList.contains("blinkingText")){
    alarm_time.innerHTML = (alarmHr + ":" + (alarmMin < 10 ? "0" + alarmMin : alarmMin) + alarmTOD);
    }else{alarm_time.innerHTML = (hours + ":" + minutes + timeofDay);}

}//Closing Brackets for clock fnc

//Set Interval to Update Time
setInterval('clock()', 500);

//Count Clicks on Set Alarm Btn
let clickCounter = 0;
set_alarm.onclick = function() {
  clickCounter++;
  //Second Click sets the alarm, says "Alarm set to"
    if((clickCounter % 2) === 0){
    alarm_time.classList.remove("blinkingText");
    alarmActive = true;  
    if (alarmHr == 0 && alarmMin == 0){
      alarm_alert.innerHTML = "no alarm set";
    }else{
      alarm_alert.innerHTML = "alarm set for  " + alarmHr + ":" + (alarmMin < 10 ? "0" + alarmMin : alarmMin) + alarmTOD;
    }
    //Loop that disables and hides buttons
    for (var i = 0; i < increment.length; i++) {
      hourIncrease.classList.remove("visibility");
      hourDecrease.classList.remove("visibility");
      minuteIncrease.classList.remove("visibility");
      minuteDecrease.classList.remove("visibility");
      document.getElementById("hourIncrease").disabled = true;
      document.getElementById("hourDecrease").disabled = true;
      document.getElementById("minuteIncrease").disabled = true;
      document.getElementById("minuteDecrease").disabled = true;
        }                    
    } else {
        alarm_time.classList.add("blinkingText");
        //Loop Over the Node List for increment
        for (var i = 0; i < increment.length; i++) {
          hourIncrease.classList.add("visibility");
          hourDecrease.classList.add("visibility");
          minuteIncrease.classList.add("visibility");
          minuteDecrease.classList.add("visibility");
          document.getElementById("hourIncrease").disabled = false;
          document.getElementById("hourDecrease").disabled = false;
          document.getElementById("minuteIncrease").disabled = false;
          document.getElementById("minuteDecrease").disabled = false;
        }                        
    }
  };

//Turn off alarm
dismiss.onclick = function() {
  if(alarmActive = "true") {
    alarmActive ="false"
    alarmHr = 12;
    alarmMin = 0;
    alarmTOD = "AM";   
    alarm_alert.innerHTML = "no alarm set";
    sound.pause();
    alarm_time.classList.remove("blinkingText");
    //Loop that disables and hides buttons
    for (var i = 0; i < increment.length; i++) {
      hourIncrease.classList.remove("visibility");
      hourDecrease.classList.remove("visibility");
      minuteIncrease.classList.remove("visibility");
      minuteDecrease.classList.remove("visibility");
      document.getElementById("hourIncrease").disabled = true;
      document.getElementById("hourDecrease").disabled = true;
      document.getElementById("minuteIncrease").disabled = true;
      document.getElementById("minuteDecrease").disabled = true;
        }                        
  }
};

hr_increase.onclick = function() { 
  increaseHr();
}

hr_decrease.onclick = function() { 
  decreaseHr();
}; 

min_increase.onclick = function() { 
  alarmMin++;
  if(alarmMin > 59){
    alarmMin = 0;
    increaseHr();
  }
}

min_decrease.onclick = function() { 
  alarmMin--;
  if (alarmMin < 0){
    alarmMin = 59;
    decreaseHr();
  }
}; 
@import url('https://fonts.googleapis.com/css?family=Montserrat:900|Open+Sans:800|Source+Sans+Pro:300');


html, body {
  height: 100%;
  font-family: 'Source Sans Pro', sans-serif;
  font-size:15px;
}

.card_container{
  height:100vh;
}
.center{
    display:flex;
    justify-content:center;
    align-items:center;
}

.card{
  border-radius:15px;
  background-color: rgba(254, 253, 253,0.8);
  box-shadow: 0px 0px 51px -3px rgba(0,0,0,0.13);
  max-width:22rem;
  border:solid rgba(254, 253, 253,0.8) 0.1px;
}

.blinkingAlarm{
  animation:blinkingAlarm 1.2s ease-in-out infinite;
}

@keyframes blinkingAlarm{
      50%{
           border:solid white 7px;}
 }

.card_inner{
  border-radius:15px;
  margin:.75rem;
}


.card_currentContainer{
  border-radius:15px;
  margin-bottom:1rem;
}

.card_alarmContainer {
  color:#7E7E7E;
  background:#fff;
  text-align:center;
}


.card_alarmContainer{
   flex-direction:column;
   border-radius:15px;
}

.alarmOptions{
  display:flex;
  color:#7E7E7E;
  padding-top:.5rem;
  padding-bottom:.5rem;
}

.blinkingText{
  animation:blinkingText 1.6s linear infinite;
}

@keyframes blinkingText{
      50%{opacity:0.3;}
}

.setBox{
  flex-direction:column;
  padding-left:.5rem;
  padding-right:.5rem;
  padding-top:0;
}

.button {
  display:block;
  border-style:none;
  margin: 0px 0px;
  padding:0px;
}

.increment{
  font-size:1rem;
  border:none;
  background: rgba(254, 253, 253,0.8);
  color:#7E7E7E;
  font-family: 'Source Sans Pro', sans-serif;
  cursor: pointer;
  visibility:hidden;
}

.increment:hover{
  cursor:pointer;
  color:black;
  border-style:none;
}

.visibility{
  visibility:visible;
}
.alarmBox{
  padding-bottom:.2rem;
}

.alarmTime{

  font-size:2rem;
  line-height:1rem;
  padding-top:.7rem;
}

.alarmAlert{
  font-size:.8rem;
  text-transform:uppercase;
  padding-top:.5rem;
}

.card_buttonsContainer{
  width:100%;
  margin:1rem 0rem;
  justify-content:space-between;
  flex-wrap:wrap;
}

.btn{
  height:3rem;
  width:8rem;
}

#setAlarm{
  transition: .2s;
  color:#fff; 
  cursor:pointer; 
  border-radius:15px;
    background: linear-gradient(to left, #ff7e5f , #feb47b); 
  padding-right:.5rem;
  padding-left:.5rem;
  font-size:1.5rem; 
  margin-right:0.3rem;
}

#setAlarm:hover{
  border-radius:20px;
  opacity: .8;
}

#dismiss{
  transition: .2s;
  font-size:1.5rem; 
  color:#fff; 
  border-radius:15px; 
  cursor:pointer; 
  background: linear-gradient(to left, #64B1F2 , #00DBF3); 
  padding-right:.5rem;
  padding-left:.5rem;
  margin-left:0.3rem;
}

#dismiss:hover{
  border-radius:20px;
  opacity: .8;
}

/***Media Queries****/
@media only screen and (max-width:332px) {
  .current_greetings{
    text-align:center;
  }
  .card_buttonsContainer{
     justify-content:center;
  }
  .btn{
    margin-bottom:.5rem;
  }
}  
<div class="card_container center">  
  <div class ="card">
    <div class="card_inner">
      <div class="card_alarmContainer center"> 
        <div class="alarmOptions ">
          <div class="setBox center">
            <button class="increment center" id="hourIncrease" disabled>&#x2b;</button>
            <button class="increment center" id="hourDecrease" disabled>&#x2212;</button>
          </div>
          <div class="alarmBox">
          <div class="alarmTime center" id="alarmTime"></div>
          <div class="alarmAlert" id="alarmAlert">no alarm set</div>
            </div>
          <div class="setBox center">
            <button class="increment center" id="minuteIncrease" disabled>&#x2b;</button>
            <button class="increment center" id="minuteDecrease" disabled>&#x2212;</button>
          </div>
          
        </div>
      </div>
      <div class="card_buttonsContainer center">
        <div class ="buttonBox center">
          <div class="btn center" id="setAlarm">Set Alarm</div>
        </div>
        <div class ="buttonBox center">
          <div class="btn center" id="dismiss">Dismiss</div>
        </div>
      </div>
    </div>
  </div>
</div>