简体   繁体   中英

Problem - function with multiple if else statements

I want to make a function, that replaces element on specific time and changes HTML inside. I'm getting current time in hours and minutes and I'm trying to solve it by logical operators. I don't know, how to solve it properly (I'm not familiar with objects or methods yet), but I tried my best - I will be grateful, if someone shows me how to make it work or some better way to do this (but it should be just JavaScript or jQuery).

 function messageOnSpecificTime(){ var date=new Date(); var hour=date.getHours(); var minutes=date.getMinutes(); // var messageBox=document.getElementsByClassName("iziToast-message"); if (hour>=8 && hour<9 && minutes>=0 && minutes<30){ document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=8 && hour<9 && minutes>=30 && minutes<59){ document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=9 && hour<10 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=9 && hour<10 && minutes>=30 && minutes<59) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=10 && hour<11 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=10 && hour<11 && minutes>=30 && minutes<59){ document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=11 && hour<12 && minutes>=0 && minutes<30){ document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=11 && hour<12 && minutes>=30 && minutes<59) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=12 && hour<13 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=12 && hour<13 && minutes>=30 && minutes<59) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=13 && hour<14 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=13 && hour<14 && minutes>=30 && minutes<59) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=14 && hour<15 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=14 && hour<15 && minutes>=30 && minutes<59) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=15 && hour<16 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=15 && hour<16 && minutes>=30 && minutes<59) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=16 && hour<17 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=16 && hour<17 && minutes>=30 && minutes<59) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=17 && hour<18 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=17 && hour<18 && minutes>=30 && minutes<59) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=18 && hour<19 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=18 && hour<19 && minutes>=30 && minutes<59) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else if (hour>=19 && hour<20 && minutes>=0 && minutes<30) { document.getElementsByClassName("iziToast-message").innerHTML = "Message 8:00 - 8:30" } else { document.getElementsByClassName("iziToast-message").innerHTML = "All for today folks!" } } window.onload = function() { setInterval(messageOnSpecificTime(),6000) }

Using Conditional (ternary) operator .
I've split hour+":"+(minutes<30?"00":"30")+" to "+(hour+(minutes<30?0:1))+":"+(minutes<30?"30":"00") in the code snippet to multiple lines to be able to track the logic.

 function messageOnSpecificTime(date=new Date()){ // var date=new Date(); var hour=date.getHours(); var minutes=date.getMinutes(); var message= hour+":"+ (minutes<30?"00":"30")+ " to "+ (hour+ (minutes<30?0:1) )+ ":"+ (minutes<30?"30":"00") ; return message; }; console.log(messageOnSpecificTime()); console.log(messageOnSpecificTime(new Date("8/8/88 7:00"))); console.log(messageOnSpecificTime(new Date("8/8/88 7:18"))); console.log(messageOnSpecificTime(new Date("8/8/88 7:47"))); console.log(messageOnSpecificTime(new Date("8/8/88 23:47")));

Apart from the fact that this gets an hour and minutes from select list and needs to convert the hour value into a number to add 1 (which wouldn't happen in the actual code as that should already be a number), why not just do:

 function messageOnSpecificTime() { let h = document.getElementById("hours").value; let m = document.getElementById("minutes").value; let msg = ""; if (m < 30) { msg = h + ":00 - " + h + ":30"; } else { msg = h + ":30 - " + (Number(h) + 1) + ":00"; } document.getElementById("message").innerHTML = msg; }
 Pick an hour: <select id="hours"> <option value=0>0</option> <option value=1>1</option> <option value=2>2</option> <option value=3>3</option> <option value=4>4</option> <option value=5>5</option> <option value=6>6</option> <option value=7>7</option> <option value=8>8</option> <option value=9>9</option> <option value=10>10</option> <option value=11>11</option> <option value=12>12</option> <option value=13>13</option> <option value=14>14</option> <option value=15>15</option> <option value=16>16</option> <option value=17>17</option> <option value=18>18</option> <option value=19>19</option> <option value=20>20</option> <option value=21>21</option> <option value=22>22</option> <option value=23>23</option> </select> Pick minutes: <select id="minutes"> <option value=0>0</option> <option value=1>1</option> <option value=2>2</option> <option value=3>3</option> <option value=4>4</option> <option value=5>5</option> <option value=6>6</option> <option value=7>7</option> <option value=8>8</option> <option value=9>9</option> <option value=10>10</option> <option value=11>11</option> <option value=12>12</option> <option value=13>13</option> <option value=14>14</option> <option value=15>15</option> <option value=16>16</option> <option value=17>17</option> <option value=18>18</option> <option value=19>19</option> <option value=20>20</option> <option value=21>21</option> <option value=22>22</option> <option value=23>23</option> <option value=24>24</option> <option value=25>25</option> <option value=26>26</option> <option value=27>27</option> <option value=28>28</option> <option value=29>29</option> <option value=30>30</option> <option value=31>31</option> <option value=32>32</option> <option value=33>33</option> <option value=34>34</option> <option value=35>35</option> <option value=36>36</option> <option value=37>37</option> <option value=38>38</option> <option value=39>39</option> <option value=40>40</option> <option value=41>41</option> <option value=42>42</option> <option value=43>43</option> <option value=44>44</option> <option value=45>45</option> <option value=46>46</option> <option value=47>47</option> <option value=48>48</option> <option value=49>49</option> <option value=50>50</option> <option value=51>51</option> <option value=52>52</option> <option value=53>53</option> <option value=54>54</option> <option value=55>55</option> <option value=56>56</option> <option value=57>57</option> <option value=58>58</option> <option value=59>59</option> </select> <button onclick="messageOnSpecificTime();">Show message</button><br> <br> <span id="message"></span>

Assuming you've an individual message for the each time range, you could build a timer to show the messages, and consider the messages being data instead of them being a part of the code, like they are in your example. In the below code, the messages are stored in a simple object, a key representing the time, and a value being the message itself. The timer takes care of choosing a correct message.

 // Store the messages in an object, like this: const messages = { 80: 'Message shown between 8:00 - 8:30', 85: 'Message shown between 8:30 - 9:00', 90: 'Message shown between 9:00 - 9:30', 95: 'Message shown between 9:30 - 10:00', 100: 'Message shown between 10:00 - 10:30', 105: 'Message shown between 10:30 - 11:00', 110: 'Message shown between 11:00 - 11:30', 115: 'Message shown between 11:30 - 12:00', 120: 'Message shown between 12:00 - 12:30', 125: 'Message shown between 12:30 - 13:00', 130: 'Message shown between 13:00 - 13:30', 135: 'Message shown between 13:30 - 14:00', 140: 'Message shown between 14:00 - 14:30', 145: 'Message shown between 14:30 - 15:00', 150: 'Message shown between 15:00 - 15:30', 155: 'Message shown between 15:30 - 16:00', 160: 'Message shown between 16:00 - 16:30', 165: 'Message shown between 16:30 - 17:00', 170: 'Message shown between 17:00 - 17:30', 175: 'Message shown between 17:30 - 18:00', 180: 'Message shown between 18:00 - 18:30', 185: 'Message shown between 18:30 - 19:00', 190: 'Message shown between 19:00 - 19:30', 0: 'All for today folks!' }; const now = new Date(), // A reference to the element to show the message in pad = document.querySelector('.iziToast-message'); // Time to go before the next half-/full-hour occurs let nextHalf = (((59 - now.getMinutes()) % 30 + 1) * 60 - now.getSeconds()) * 1000, // Index following time, initialized to the nearest half-/full-hour time = 10 * now.getHours() + Math.floor(now.getMinutes() / 30) * 5; // Set the timer, execute the function once immediately to show the current message (function showMessage() { // Set an index matching a key in messages object const key = (time < 80 || time > 190) ? 0 : time; // Rewrite the content of the message on the page pad.textContent = messages[key]; // Increase the time by half an hour in range 0 - 235 (0:00 - 23:30) time = (time + 5) % 240; // Run this function again when the next half-/full-hour occurs setTimeout(showMessage, nextHalf); }()); // Set the delay to take a half an hour, will be used when `showMessage` is called next time nextHalf = 1800000;
 <div class="iziToast-message"></div>

The (function () {...}()); construction is ImmediatelyInvokedFunctionExpression .

The messages are separated from the actual executable part, and are included in the properties of the messages object. The keys of the properties are representing the start time when the message in the property should be shown. It's easier to update the messages in an object when the keys are reflecting the actual time. This could be done using an array too, but with an array, the relationship between the time and the message index is less clear, as a sparse array is best to be avoided.

I've also chosen hard-coded time range in the messages, as it takes less code than a dynamic time range creation, and you've free hands to position the range in the message where ever you want.

At first, the code calculates the time to the next nearest half-/full-hour from the current time ( nextHalf ). Then a simplified time index is created ( time ), the index matches to the keys in the messages object. Then showMessage is called, and the key ( key ) for the current message is calculated. If the current time is out of the range (8:00 - 19:30), the key defaults to 0 . Then the content of the message box is rewritten, and a new time for the next showMessage call is calculated. The new call is delayed so ( nextHalf ), that the timer fires on the next half-/full-hour.

To understand, how the code works, it's essential to know, that setTimeout does not block the execution of the current script. Instead, it's executed immediately, and the callback and delay arguments are passed with their current values. Setting a new value to the variable holding the delay after the setTimeout call, does not have an affect to the previously set timer. The new delay is used only in the delayed future calls of the showMessage function.

The advantage of the relatively complex timer is, that you don't have to re-write the message in short intervals, as the timer calibrates to the actual time, and calls itself half-hourly.

A demo at jsFiddle . In the demo a half an hour takes only a second, it's less boring than to wait for a half an hour to see something to happen.

It's notable, that a simpler, and perhaps even more accurate version of the timer can be written. This function contains all the needed variables, excluding the messages object and the reference to the message box element ( pad ), which are still included in the outer scope.

(function showMessage () {
    const now = new Date(),
      time = 10 * now.getHours() + Math.floor(now.getMinutes() / 30) * 5,
      key = (time < 80 || time > 190) ? 0 : time,
      nextHalf = (((59 - now.getMinutes()) % 30 + 1) * 60 - now.getSeconds()) * 1000;
    pad.textContent = messages[key];
    setTimeout(showMessage, nextHalf);
}());

A demo of this variant , it's not speeded up, though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM