1

I want to add a class based on certain time, if the time goes out, then the class will automatically be removed. I tried repeatedly, but couldn't figure it out as I'm new to JavaScript/jQuery. I tried googling for a solution, but couldn't find anything, which led me to StackOverflow. Please refer to my code below.

$(document).ready(function() {
  var hr = new Date().getHours();
  // I want execute this at 20:00 till 04:00
  if (hr < 20) {
    $('#tahajud').addClass('opened-for-codepen');
  }
  // I want execute this at 04:00 till 06:00
  if (hr < 4) {
    $('#fajr').addClass('opened-for-codepen');
  }
  // I want execute this at 08:00 till 10:00
  if (hr < 8) {
    $('#dhuha').addClass('opened-for-codepen');
  }
});
vol7ron
  • 40,809
  • 21
  • 119
  • 172
  • 1
    Look into `else if()` – epascarello Apr 05 '17 at 02:19
  • 1
    Not the problem, but what do you think the `min <= 59` part of each `if` condition is doing? – nnnnnn Apr 05 '17 at 02:40
  • @nnnnnn sorry, it had to use minutes, but does not work at all, im so bad at this, just an student. i just edit my post. thanks – MUHAMMAD NAUFAL AZKIA Apr 05 '17 at 02:47
  • What's the purpose? What are you doing this for? What do you hope to accomplish? You say `timeout`, that means something very specific in JavaScript. – vol7ron Apr 05 '17 at 02:57
  • Muhammad, you don't need to fix your question based on comments. Now my answer looks like it's not related to the question, when I talk about minutes. Stop apologizing and just learn from your mistakes. Everyone makes mistakes. It's part of life. Relax, enjoy and learn. :) – tao Apr 05 '17 at 02:58
  • @vol7ron he clearly doesn't have the terminology. What he meant is (and can be seen in his script) he wants the page to load with some classes between specific hours. Yes, it would be nice to add setTimeout()'s based on those and change the classes when the timeout runs out and set the next one. I admit it crossed my mind, but it's also a bit over the top... :) – tao Apr 05 '17 at 03:01
  • @AndreiGheorghiu do you know this for a fact, or does he want to create a timer that hides and shows based on a countdown? How else will the class "remove" when the "time goes out" – vol7ron Apr 05 '17 at 03:11
  • @vol7ron Look at his original question and see what the problems were at that point. I don't know it for a fact but, considering the question being asked, I just assumed I could be of some help and provided based on this assumption. As per change when the condition changes, let's just assume a page refresh will suffice. – tao Apr 05 '17 at 03:20
  • Assume not young jedi ;) – vol7ron Apr 05 '17 at 03:24
  • 1
    I assume my assumptions, master. :) – tao Apr 05 '17 at 03:26

2 Answers2

0

I think this will do what you want:

$(window).on('load', function(){
  let hr = new Date().getHours(),
      cls = 'opened';

  // I want execute this at 20:00 till 04:00
  $('#tahajud').toggleClass(
    cls, 
    (hr >= 20) || (hr < 5)
  );

  // I want execute this at 04:00 till 06:00
  $('#fajr').toggleClass(
    cls,
    (hr >= 4) && (hr < 6)
  );

  // I want execute this at 08:00 till 10:00
  $('#dhuha').addClass(
    cls, 
    (hr >= 8) && (hr < 10)
  );
});

It uses toggleClass() which can take a yesOrNo expression/function as a second param. If it's true, adds the class. If not, it removes it.

Also, your conditions were a bit off. You don't need to check for minutes, since you always apply the class at sharp hour. Pay attention to my conditions, I'm sure they'll make sense.

To see it in action:

$(window).on('load', function(){
  let hr = new Date().getHours(),
      cls = 'opened';

  // I want execute this at 20:00 till 04:00
  $('#tahajud').toggleClass(
    cls, 
    (hr >= 20) || (hr < 5)
  );

  // I want execute this at 04:00 till 06:00
  $('#fajr').toggleClass(
    cls,
    (hr >= 4) && (hr < 6)
  );

  // I want execute this at 08:00 till 10:00
  $('#dhuha').addClass(
    cls, 
    (hr >= 8) && (hr < 10)
  );
});
#tahajud span::before,
#fajr span::before,
#dhuha span::before {
  content: 'closed for codepen.';
}
#tahajud.opened span::before,
#fajr.opened span::before,
#dhuha.opened span::before {
  content: 'openend for codepen.';
  color: #382;
}
span {
  color: #f50;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="tahajud">Tahajud is now <span></span></div>
<div id="fajr">Fajr is now <span></span></div>
<div id="dhuha">Dhuha is now <span></span></div>
tao
  • 82,996
  • 16
  • 114
  • 150
  • I'd appreciate knowing the reason for the down-vote. Always happy to learn and/or improve my answers. – tao Apr 05 '17 at 02:38
  • I didn't vote, but the answer would be better if it included an explanation of why it works. Wouldn't hurt to briefly explain what was wrong with the OP's code, too. Also, why did you switch from document ready to window onload? – nnnnnn Apr 05 '17 at 02:42
  • @nnnnnn I just thought it's better to push it later. I also assumed seeing the change created by the class applying won't be displeasing, but will actually draw attention to the elements. I thought it's one of those rare cases where faux FOUC is actually a good thing. But, of course, I might be totally wrong, lol. – tao Apr 05 '17 at 02:53
  • @AndreiGheorghiu aa i get it, thank you very much for help and the explanation... – MUHAMMAD NAUFAL AZKIA Apr 05 '17 at 03:14
  • 1
    Check out my answer to the BFC question that you answered earlier: http://stackoverflow.com/questions/43215834/what-is-mean-of-participate-in-definition-of-normal-flow-in-w3-spec/43221955#43221955 – BoltClock Apr 05 '17 at 05:00
0

You can use a series of if and else if to check if your hr falls between the times you want. The CSS is important as it defaults all the div to hidden by default and the class displays whatever div it is added to.

$(document).ready(function() {
  var hr = new Date().getHours();

  // fluff for the example
  $('body').prepend('Setting class for hour ' + hr + '...');


  // adds the class by calling the function after 1.5 seconds
  setTimeout(setCodepenClass.bind(null, hr), 1500);
});

function setCodepenClass(hr) {

  // Adds the class if time is between 04:00 (inclusive) and 06:00 (exclusive)
  if (hr >= 4 && hr < 6) {
    $('#fajr').addClass('opened-for-codepen');
  }
  // Adds the class if time is between 08:00 (inclusive) and 10:00 (exclusive)
  else if (hr >= 8 && hr < 10) {
    $('#dhuha').addClass('opened-for-codepen');
  }
  // Adds the class if time is between 20:00 (inclusive) and 04:00 (exclusive)
  else if (hr >= 20 || hr < 4) {
    $('#tahajud').addClass('opened-for-codepen');
  }
}
div {
  display: none;
}

.opened-for-codepen {
  background: #333;
  border: 2px solid #222;
  color: white;
  display: block;
  font-weight: bold;
  margin: 2em;
  min-width: 200px;
  min-height: 75px;
  padding: 2em;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="tahajud">tahajud</div>
<div id="fajr">fajr</div>
<div id="dhuha">dhuha</div>
vol7ron
  • 40,809
  • 21
  • 119
  • 172
  • You answered 45 minutes after me. This is not about the points, I'm just trying to improve my answers and look at others to learn where I could have done better. I'd appreciate learning from this. Could you tell me what about my answer you found insufficient, that made you add yours? – tao Apr 06 '17 at 23:05
  • @AndreiGheorghiu sure; this will need to be a multi-section comment. (1) Time means nothing to me, I'll start a solution, review posts, format the original post, lookup something, do laundry, then come back and finish a solution without looking at other answers. It shouldn't affect your upvoting or order selection. – vol7ron Apr 06 '17 at 23:15
  • @AndreiGheorghiu (2) Your answer did not have any explanation at all until 3 minutes after I posted my answer. (3) Your answer was just code, it didn't have an in-browser demo snippet until after I posted my answer -- curious if you didn't copy mine and edit it for your answer. I am not offended, but you mentioned time and how you answered first, but lacked a lot of things that mine included until after mine was posted... – vol7ron Apr 06 '17 at 23:20
  • @AndreiGheorghiu (4) I applied a whole different approach, setting all blocks to not display by default and using `else-if` blocks to turn them on. (5) My time windows were inclusive of certain hours (6) I did not display the "closed for codepen" as I am not sure if it was needed – vol7ron Apr 06 '17 at 23:24
  • (2) and (3) are not true. Explanations were added closely after initial answer, ~ 30 minutes before your answer. Please re-check times. Thank you for laying it all out. – tao Apr 06 '17 at 23:26
  • @AndreiGheorghiu (7) I included a `setTimeout` because I was unsuer if he was doing this on a timer. If so this made it easier for him to adjust his `setInterval` and show how to pass along the `hr` as a variable to the `timeout/interval` function using `bind()` (8) I did not toggleClass, though based on the timeout/interval reasoning, I should have shown how to hide all the other elements again (I felt it fluff) – vol7ron Apr 06 '17 at 23:26
  • @AndreiGheorghiu I withdraw the claim about the explanations (2); you did have them they were at the bottom and I missed that; though I do not think your in-code comments or your *explanation* was that descriptive for all that was going on in your answer. – vol7ron Apr 06 '17 at 23:30
  • @AndreiGheorghiu Looking at your edits, I do not agree with your claim that (3) was incorrect. You didn't add the snippet til `3:17:03Z` and my post was at `3:14:36Z` – vol7ron Apr 06 '17 at 23:32
  • I misunderstood (3), because of the *"Your answer was just code"* part. Indeed, it didn't have an example. It only had the `javascript` part and explanations. I now see what you meant. Ok, thank you again for explaining. I envy you (a bit): I wish I could say time means nothing to me. Not there yet. :) – tao Apr 06 '17 at 23:32
  • @AndreiGheorghiu Correct. I'm only doing this because you asked. I don't care about the points. Also, there are different ways to answer on SO. One is to answer for the person asking the question, the other is to answer for the broader audience. In this case, I could think of 5 different ways to solve this with better, more efficient code; but I took the OP's experience into consideration, so I didn't mess too much with the `if` blocks and the `addClass`. This is done so he could more easily recognize the differences, which should be a little more easier for him to comprehend. – vol7ron Apr 06 '17 at 23:35
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/140124/discussion-between-andrei-gheorghiu-and-vol7ron). – tao Apr 06 '17 at 23:36
  • @AndreiGheorghiu While I also think your answer could be made more efficient, I could argue it was the better answer in what it offered. They're both different. – vol7ron Apr 06 '17 at 23:36
  • @AndreiGheorghiu Back to my first point... it seems I edited his question in the time between when you answered and when I answered. That explains some of the time difference, but I have multiple windows open when I'm contributing to SO (as an editor, or adding answers) – vol7ron Apr 06 '17 at 23:40
  • I happen to be very interested in code efficiency (writing lighter and faster code). Since we're here, It'd be very helpful for me to know how you think my answer could be made more efficient. I'm self taught in `js` and I know my code is sub-optimal. – tao Apr 06 '17 at 23:42
  • 1
    @AndreiGheorghiu this would not be the place for that. The reason I left these comments is because they were comments comparing the two different answers (strictly related to the answers). What you are requesting is a code review, which Stack Exchange has a forum for: http://codereview.stackexchange.com/ -- I may have some time to help you, or someone else (possibly more knowledgeable than me, may assist you). If you post there, add a link to a comment under your answer. – vol7ron Apr 07 '17 at 00:08