35

I've developed a couple of alert boxes that display on all site pages.

screenshot of alert boxes

The user is able to close each box separately:

$(document).ready(function() {
  $("#close-alert-box-news").click(function() {
    $("#alert-box-news").hide(800);
  });
  $("#close-alert-box-maintenance").click(function() {
    $("#alert-box-maintenance").hide(800);
  });
});
.alert-box {
  width: 50vw;
  position: relative;
  margin: 20px auto;
  border: 1px solid black;
}
.alert-box-close {
  position: absolute;
  top: -12px;
  right: -12px;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>

<article class="alert-box" id="alert-box-news">
  <h1>News Alerts</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-news">
    <img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>

<article class="alert-box" id="alert-box-maintenance">
  <h1>Site Maintenance</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-maintenance">
    <img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>

jsFiddle

Now I need to make sure that the box the user closes (could be one, could be both), doesn't re-appear as he/she browses the site, or reloads a page.

I'm thinking I could set a PHP cookie to expire in 24 hours. But most of the related posts on this site recommend a JavaScript cookie. Unfortunately, my efforts to implement a JavaScript solution haven't worked (the boxes re-appear after being closed). I've tried various methods, as outlined here:

What would be a simple method to hide each box, sitewide, for 24 hours?

I'm open to jQuery, plain JavaScript, PHP, cookies, sessions or something else.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    What is mean by sitewide. Are you talking about same user on different computers and different browsers or same session on single browser? If we are talking about different computers and browsers then we have some work with serverside else it can be handled on client side using javascript. – Shoaib Konnur Oct 31 '16 at 06:52
  • @ShoaibKonnur, I'm talking about same session on single browser. Simply put, a user closes one or both of these alert boxes during their session. I want their request to be respected on all site pages for a certain time (in my question, I've set expiration to 24 hours). – Michael Benjamin Nov 06 '16 at 12:24

12 Answers12

23

Use localStorage().

Local storage is per origin (per domain and protocol)

  • On click of DIV close, you can get the current time-stamp
  • Add number of hours (24) to that time-stamp
  • Store that value in localStorage as localStorage.setItem('desiredTime', time)
  • Check current time-stamp with that stored time-stamp localStorage.getItem('desiredTime'), based on that show/hide

jQuery

$(document).ready(function(){
        //Get current time
        var currentTime = new Date().getTime();
        //Add hours function
        Date.prototype.addHours = function(h) {    
           this.setTime(this.getTime() + (h*60*60*1000)); 
           return this;   
        }
        //Get time after 24 hours
        var after24 = new Date().addHours(10).getTime();
        //Hide div click
        $('.hide24').click(function(){
            //Hide div
            $(this).hide();
            //Set desired time till you want to hide that div
            localStorage.setItem('desiredTime', after24); 
        });
        //If desired time >= currentTime, based on that HIDE / SHOW
        if(localStorage.getItem('desiredTime') >= currentTime)
        {
            $('.hide24').hide();
        }
        else
        {
            $('.hide24').show();
        }
});

HTML

<div>DIV-1</div>
<div class='hide24'>DIV-2</div>

Things to note

  • You can use $.cookie as well, but that's an older approach now.
  • <div> with class hide24 will be hidden only.
  • Make sure that you put this code in general JavaScript, which loads on every HTTP request of your website.
  • For localStorage, you should have HTML5 browsers.

Web Storage HTML5

Hope this helps.

jacefarm
  • 6,747
  • 6
  • 36
  • 46
Mohit Tanwani
  • 6,608
  • 2
  • 14
  • 32
6

Following on @Loading.. answer:

the alert boxes always re-appear briefly on reload before disappearing. Any ideas?


Why is this?

The functions inside $(document).ready() will execute until the entire DOM is loaded. That's why the alerts are rendered, then as soon as the function runs, it hides them.


Solution:

You can initially hide your alerts with a class just to take advantage that the browser won't render the content until the CSSOM has been built.

The class we are using is just setting the property display: none;.

.hidden {
  display: none;
}

This will of course cause redraw in the browser. (see notes)

Your logic is already showing the alert with

    if (localStorage.getItem('desiredTime') >= currentTime) {
      $('#alert-box-news').hide();
    } else {
      $('#alert-box-news').show();
    }

Because using .show() will add an inline-style display: block; it will have a higher specificity than the .hidden class, showing the alert.


jsFiddle


Notes:

  • Using display: none; will push the content below the alert up or down. You can use other methods if you like, like visibility: hidden; or transform which is not in the scope of this answer.

EDIT:

An illustration will be presented below doing the following steps:

  • Demo counter increased to 20 seconds for testing.
  • We click to dismiss the alert and trigger the localStorage function, setting the desiredTime key.
  • After the key has been set, we refresh the browser and hit run several times to see if the key is working.
  • Finally, just to check that the key is indeed being set, we go to:

    DevTools (F12) -> Application Tab -> Local Storage -> jsFiddle shell.

  • Run is hit one more time, after the countdown has finished, showing the alert again.

Illustration:

Local Storage Demo Illustration


We might need further details to solve the issue with this approach if it is not working live.

Ricky Ruiz
  • 25,455
  • 6
  • 44
  • 53
  • I'm working on implementing your solution into my site. I've awarded the bounty to @Loading.. because he/she answered first, authored the original code, and introduce me to `localStorage`. – Michael Benjamin Oct 31 '16 at 16:09
  • Yeah, @Loading.. is the one that deserves the bounty. My answer's purpose is to complement his/hers, to help you, and possibly others, to get this done faster. – Ricky Ruiz Oct 31 '16 at 16:43
5

As far as I understand your question, hiding the alerts for 24 hours (and then subsequently showing them all again after a day) will be a bad user experience.

I assume you're loading these alerts from some sort of database. If so, the proper answer would be to store a status there. Whether it be a status column or a deleted_at timestamp, the implementations are endless.

Either way, I would store alert state in the database and filter your data when pulling accordingly.

Thus in your view you would have (assuming php here):

<?php

<?php if(!empty($newlyFilteredAlerts)): ?>
    <article class="alert-box" id="alert-box-news">
        <h1>News Alerts</h1>
        <?php foreach(newlyFilteredAlerts as $alert): ?>
            <p><?= $alert ?></p>
        <?php endforeach;?
        <a class="alert-box-close" id="close-alert-box-news">
          <img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt=""  >
        </a>
    </article>
<?php endif; ?>

Then you would accordingly want to add some sort of endpoint to alter that database status:

$(document).ready(function() {
    $("#close-alert-box-news").click(function() {
        $.post({
            url: '/alerts',
            type: 'DELETE',
            success: function () {
                $("#alert-box-news").hide(800);                    
            },
        });
    });
});

NOTE: This answer is meant to point you in the right direction, not write your code . All of the above code is completely untested, so if you simply copy and paste it may not work.

Jason Tolliver
  • 299
  • 4
  • 8
  • So do you mean on every page we need to check php condition? Because there might be the possibility we have 1000 of elements on 1000 of pages with the same class.. – Mohit Tanwani Oct 23 '16 at 09:40
  • Yes, on every page load you would need to check the php condition. It's up to you how you do that though. I'm guessing that by 1000's of elements you mean 1000's of total alert items, not 1000's of groups (in your example I only see 2 groups: "News Alerts" and "Site Maintenance"). No matter what, php can send down a full array each time for your view to render. The issue would still remain if you simply hid the items with javascript. What if a new alert came through after the user hid it? Would they simply not see it? Best to delete on the backend as read so new ones can come through. – Jason Tolliver Oct 27 '16 at 02:15
3

it will not work in stackoverflow. you can test in demo link

Demo

$(document).ready(function() {
  checkCookie("alertDisplayed")
  $("#close-alert-box-news").click(function() {
    setCookie("alertDisplayed", 'yes', 1);
    $(".alert-box").hide(800);
  });
  $("#close-alert-box-maintenance").click(function() {
    setCookie("alertDisplayed", 'yes', 1);
    $(".alert-box").hide(800);
  });
});

function setCookie(cname, cvalue, exdays) {
  var d = new Date();
  d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
  var expires = "expires=" + d.toUTCString();
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

function checkCookie(cname) {
  var name = cname + "=";
  var ca = document.cookie.split(';');
  for (var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      $(".alert-box").hide();
    }
  }
  return;
}
.alert-box {
  width: 50vw;
  position: relative;
  margin: 20px auto;
  border: 1px solid black;
}
.alert-box-close {
  position: absolute;
  top: -12px;
  right: -12px;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>

<article class="alert-box" id="alert-box-news">
  <h1>News Alerts</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-news">
    <img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>

<article class="alert-box" id="alert-box-maintenance">
  <h1>Site Maintenance</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-maintenance">
    <img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>
Mitul
  • 3,431
  • 2
  • 22
  • 35
  • This is a great answer and, with a minor adjustment to make each box function independently, it works perfectly. However, I'm going with the localStorage method instead of cookies. Thanks very much! – Michael Benjamin Nov 07 '16 at 15:44
2

Try this solution jsfiddle and read comments regarding storage path. If you are working on sub domain then you have to specify domain in cookie written like in setCookie() comments. if you are working on localhost then the cookie-domain must be set to "" or NULL or FALSE instead of "localhost". For domain reference you can study this stackoverflow question

function setCookie(cname, cvalue, exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires="+ d.toUTCString();
    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
    // document.cookie = cname + "=" + cvalue + ";" + expires + ";domain=.example.com;path=/"; if you are trying in any sub-domain
} 
function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for(var i = 0; i <ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length,c.length);
        }
    }
    return "";
}
$(document).ready(function() {
  if(getCookie('news')==1) { //check if cookie news exist if exist then hide.
    $("#alert-box-news").hide();
  }
  if(getCookie('maintenance')==1) { //check if cookie maintenance exist if exist then hide.
    $("#alert-box-maintenance").hide();
  }
  $("#close-alert-box-news").click(function() {
    setCookie('news',1,1); // set cookie news to 1 for 1 day = 24 hours here setCookie(key,value,number of cookie expiration day)
    $("#alert-box-news").hide(800);
  });
  $("#close-alert-box-maintenance").click(function() {
    setCookie('maintenance',1,1); // set cookie maintenance to 1 for 1 day = 24 hours here setCookie(key,value,number of cookie expiration day)
    $("#alert-box-maintenance").hide(800);
  });
});
Community
  • 1
  • 1
Rakesh Sojitra
  • 3,538
  • 2
  • 17
  • 34
2

Cookies and local storage serve different purposes. Cookies are primarily for reading server-side, local storage can only be read client-side.

In your case you're wasting bandwidth by sending all the data in each HTTP header. So I recommend you to use HTML local storage instead of cookie.

As per the technical difference and also my understanding:

  • Apart from being an old way of saving data, Cookies give you a limit of 4096 bytes - its per cookie. Local Storage is as big as 5MB per domain
  • localStorage is an implementation of the Storage Interface. It stores data with no expiration date, and gets cleared only through JavaScript, or clearing the Browser Cache / Locally Stored Data - unlike cookie expiry.

https://jsfiddle.net/eath6oyy/33/

$(document).ready(function() {
var currentTime = new Date().getTime();
var timeAfter24 = currentTime + 24*60*60*1000;
  $("#close-alert-box-news").click(function() {
    $("#alert-box-news").hide(800);
    //Set desired time till you want to hide that div
    localStorage.setItem('desiredTime', timeAfter24); 
  });
  if(localStorage.getItem('desiredTime') >= currentTime)
  {
    $('#alert-box-news').hide();
  }else{
    $('#alert-box-news').show();
  }
  
  
  $("#close-alert-box-maintenance").click(function() {
    $("#alert-box-maintenance").hide(800);
    //Set desired time till you want to hide that div
    localStorage.setItem('desiredTime1', timeAfter24); 
  });
  if(localStorage.getItem('desiredTime1') >= currentTime)
  {
    $('#alert-box-maintenance').hide();
  }else{
    $('#alert-box-maintenance').show();
  }
 
});
.alert-box {
  width: 50vw;
  position: relative;
  margin: 20px auto;
  border: 1px solid black;
}

.alert-box-close {
  position: absolute;
  top: -12px;
  right: -12px;
  cursor: pointer;
}
<article class="alert-box" id="alert-box-news">
  <h1>News Alerts</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-news">
    <img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>

<article class="alert-box" id="alert-box-maintenance">
  <h1>Site Maintenance</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-maintenance">
    <img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>
Dhurba Baral
  • 559
  • 5
  • 12
1

My answer is an extension of @Loading's answer. The issue of a flash of content on page load, even when the user has chosen to dismiss the alert(s), is due to the evaluation for localStorage being done after the DOM is loaded.

Therefore, I would recommend hiding the alerts by default, even though this might be an issue for browsers with no JS enabled. This can, however, be circumvented if you use modernizr.js which will add a class to the HTML element when JS is detected, and you can modify the base styles accordingly, e.g.:

.alert-box {
  display: none;
}
.no-js .alert-box {
  display: block;
  /* Other styles */
}

My solution uses localStorage, and relies on storing options as a stringified object: the two keys stored per box is hidden (to store the status of the box) and timestamp (to store the time when the box is dismissed). These can be used to evaluate if (1) the user has chosen to dismiss the alert and (2) the action was performed within 24 hours.

Some modifications I have made to your code:

  1. Use context-dependent selection, so that you don't have to declare multiple similar click event handlers for all alert boxes. This makes the code simpler and less redundant.
  2. Use https for the image URL so that it doesn't mess with JSfiddle's HTTPS :)

The working code is shown as follows, but localStorage does not work on here due to security restrictions: for a functional demo, refer to the updated JSfiddle instead.

$(function() {
  // Check for localStorage
  if (typeof window.localStorage !== typeof undefined) {
    // Loop through all alert boxes
    $('.alert-box').each(function() {
      var $t = $(this),
        key = $t.attr('id');

      // If key exists and it has not expired
      if (window.localStorage.getItem(key)) {
        var json = JSON.parse(window.localStorage.getItem(key));
        if (json.hide && json.timestamp < Date.now() + 1000 * 60 * 60 * 24) {
          $t.hide();
        } else {
          $t.show();
        }
      } else {
        $t.show();
      }
    });
  }

  // Bind click events to alert boxes
  $('.alert-box a.alert-box-close').click(function() {
    var $alertBox = $(this).closest('.alert-box');

    // Hide box
    $alertBox.hide(800);

    // Store option in localStorage, using the box's ID as key
    if (typeof window.localStorage !== typeof undefined) {
      window.localStorage.setItem($alertBox.attr('id'), JSON.stringify({
        hide: true,
        timestamp: Date.now()
      }));
    }
  });

  // For demo purposes only, clear localStorage to ease testing
  $('#clear-localstorage').click(function() {
    window.localStorage.clear();
  });
});
.alert-box {
  display: none;
  width: 50vw;
  position: relative;
  margin: 20px auto;
  border: 1px solid black;
}

.alert-box-close {
  position: absolute;
  top: -12px;
  right: -12px;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<article class="alert-box" id="alert-box-news">
  <h1>News Alerts</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-news">
    <img src="https://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>

<article class="alert-box" id="alert-box-maintenance">
  <h1>Site Maintenance</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-maintenance">
    <img src="https://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>

<button id="clear-localstorage">Clear local storage (for testing)</button>
Community
  • 1
  • 1
Terry
  • 63,248
  • 15
  • 96
  • 118
1

You should simply use local storage.

HTML

<article class="alert-box" id="alert-box-news">
  <h1>News Alerts</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-news">
    <img src="https://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>

<article class="alert-box" id="alert-box-maintenance">
  <h1>Site Maintenance</h1>
  <p>text text text text text text text text text text text text text text</p>
  <a class="alert-box-close" id="close-alert-box-maintenance">
    <img src="https://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
  </a>
</article>

Javascipt

$(document).ready(function() {
  var nd = new Date();
  var md = nd;
  var newsclicked = false;
  var maintenanceclicked = false;
  setInterval(function() {
    newsclicked = (localStorage.getItem("newsclicked")) ? new Date(localStorage.getItem("newsclicked")) : false;
    maintenanceclicked = (localStorage.getItem("maintenanceclicked")) ? new Date(localStorage.getItem("maintenanceclicked")) : false;
    if (maintenanceclicked === false) {
      console.log(maintenanceclicked);
      $("#alert-box-maintenance").show(800);
    } else {
      var mddiff = (md.getTime() - maintenanceclicked.getTime()) / (60 * 60 * 24 * 1000);
      if (mddiff >= 1) {
        $("#alert-box-maintenance").show(800);
      } else {
        $("#alert-box-maintenance").hide(800);
      }
    }
    if (newsclicked === false) {
      $("#alert-box-news").show(800);
    } else {
      var nddiff = (nd.getTime() - newsclicked.getTime()) / (60 * 60 * 24 * 1000);
      if (nddiff >= 1) {
        $("#alert-box-news").show(800);
      } else {
        $("#alert-box-news").hide(800);
      }
    }
  }, 200);
  $("#close-alert-box-news").on("click", function() {
    nd = new Date();
    localStorage.setItem("newsclicked", nd);
    $("#alert-box-news").hide(800);
  });
  $("#close-alert-box-maintenance").on("click", function() {
    md = new Date();
    localStorage.setItem("maintenanceclicked", md);
    $("#alert-box-maintenance").hide(800);
  });
});

CSS

.alert-box {
  width: 50vw;
  position: relative;
  margin: 20px auto;
  border: 1px solid black;
}

.alert-box-close {
  position: absolute;
  top: -12px;
  right: -12px;
  cursor: pointer;
}
#alert-box-news,#alert-box-maintenance{
  display:none; // by default have both elements hidden.
}

Here is an update in your fiddle to test it in action. Refresh the page once you closed a div

  • This solution works perfectly. And the comments were also helpful. Thanks for your time and effort. – Michael Benjamin Nov 06 '16 at 16:34
  • @Michael_B thank you very much :). At first i had not seen that you needed this to be time based for 24 hours. localStorage is a perfect solution for things like this. Try to encrypt data "IF AND WHEN NEEDED" when passing it to localStorage as your last step. –  Nov 06 '16 at 18:10
  • Encryption? This function is intended to hide non-essential, publicly-available information for a set time. The expiration is based on our judgement for best user experience combined with our need to inform. So 24 hours sounds good for now. But I don't think any encryption is necessary. Let me know if you disagree. – Michael Benjamin Nov 06 '16 at 18:14
  • 1
    @Michael_B for non-essential data i agree with you. Earlier comment was for certain case. For "essential" data i would prefer not to have it shown not even encrypted in localStorage or sessionStorage if possible. –  Nov 06 '16 at 18:52
  • I really hoped I could get this to work but unfortunately I couldn't . My use case is a little different. I'd like to remove that 24 hr expiration and make it so after a user closes the info/alert box, they never see it again unless they clear their local storage. Would you mind taking a look at my code to see what i'm doing wrong? The info box isn't closing... https://jsfiddle.net/jord8on/hyohLdm3/ – jord8on May 19 '18 at 18:58
  • Hello @PeterDarmis do you have any thoughts on my issue? – jord8on May 20 '18 at 04:16
  • @jord8on try the updated answer / check the updated fiddle. Open two browser tabs or more and test it, try clearing `localStorage` in your browser after hiding both or one of the elements. –  May 24 '18 at 14:51
1

You can go with the code you have plus setting a cookie which expires in 24 hours:

  1. Install the MDN JavaScript Cookie Framework

  2. On your js set a tomorrow variable holding the expiration date for your cookie:

    var today = new Date();
    var tomorrow = today.setHours(today.getHours() + 24);
    
  3. Set your cookies as follows:

    docCookies.setItem('hide_news', 'true', tomorrow);
    
  4. Conditionally hide the boxes based on the cookie's value

    if (docCookies.getItem('hide_news') == 'true'){
      $("#alert-box-news").add_class('hidden');
    };
    
  5. Define the hidden class on your CSS file

    .hidden {
      display none;
    }
    

You can see it all in action in this codepen.

rebagliatte
  • 2,110
  • 1
  • 20
  • 25
1

It possible to that with sessionStorage of javascript.

For exemple :

Storage the current date ( var currentDate) and date after one minute (var afterOneMinute)in sessionStorage. Each click on a button or reload page, change current date and compare them with afterOneMinute variable and after hide or show box

html File

<head>
    <script src="jquery.js"></script>
</head>
<body>
<button onclick="hideOneMinute()">Hide box while 1 minute </button>
<div id="box" style="border: 1px solid red; display: inherit">
    <h2>Box</h2>
    hello
</div>
<div id="messageBox"></div>
</body>

JS

<script>
    var currentDate, afterOneMinute;
    function addDate(){
        var current = new Date();
        // Converts current date in seconds
        currentDate = current.getHours()*3600+current.getMinutes()*60+current.getSeconds();
        // Current date + 1 minute
        afterOneMinute = currentDate + 1*60;
    }
    addDate();
    console.log(currentDate);
    // verify sessionStorage when page is reloaded    ;
    if(typeof(Storage) !== "undefined") {
        if(sessionStorage.currentDate){
            addDate();
            sessionStorage.currentDate = currentDate;
            if(Number(sessionStorage.currentDate) < Number(sessionStorage.afterOneMinute))
            {
                $('#box').hide();
                console.log('hide');
            }
            else{
                sessionStorage.clear();
                console.log('show');
                $('#box').show();
            }

        }
    }
    function hideOneMinute() {
        if(typeof(Storage) !== "undefined") {
            if(sessionStorage.currentDate){
                addDate();
                sessionStorage.currentDate = currentDate;
                if(Number(sessionStorage.currentDate) < Number(sessionStorage.afterOneMinute))
                {
                    $('#box').hide();
                }
                else{
                    sessionStorage.clear();
                    console.log('show');
                    $('#box').show();
                }

            }else{
                addDate();
                sessionStorage.currentDate = currentDate;
                sessionStorage.afterOneMinute = afterOneMinute;
                console.log('hide');
                $('#box').hide();
            }
            document.getElementById("messageBox").innerHTML = "Box will be shown at " + sessionStorage.afterOneMinute;
        } else {
            document.getElementById("messageBox").innerHTML = "Sorry, your browser does not support web storage...";
        }
    }
</script>
Bobo
  • 462
  • 8
  • 17
1

Updated the script with a 24 hour check

How and where you store the time stamp has more to do with which control you want to have on it.

Since there is a user involved, I would go the server side way, and create i.e. an extra field in the users database table, where these states is kept.

This way, in opposite of the user being able to clear cookies/storage, you control which alerts that should stay hidden and for how long.

A second advantage would be that this can be, on top of time, rolled based, where certain action can be taken based on the users and their credentials.

Either way I would construct the show/hide like this, where you store a class, or an attribute, in i.e. the html tag, which control whether a box will be visual or not.

The advantage this has, is you get rid of the "first show then hide" issue and it will work either you add it server side or using script.

Here is a simple sample using script, plain javascript, and it is by no means optimized, it simply for the logic I wanted to show.

Since this will actually not run as a Stack snippet due to some security issue, here is a fiddle that does: https://jsfiddle.net/essjuj4y/10/

By clicking the For this demo - to clear local storage button, the storage will be cleared and when page will be run again, the boxes will appear.

/*  add an event handler to be able to close a box  */
var alerts = document.querySelectorAll('.alert-box-close');
for (var i = 0; i < alerts.length; i++) {
  alerts[i].addEventListener('click', function(e) {
    var boxtype = e.target.parentElement.id.split('-').pop();
    document.getElementById('alert-box-' + boxtype).style.display = "none";
    localStorage.setItem("al-" + boxtype, new Date());
  })
}

/*  add an event handler to be able to clear storage - for demo purpose  */
document.querySelector('button').addEventListener('click', function(e) {
  localStorage.clear();
})
.alert-box {
  display: none;
  width: 50vw;
  position: relative;
  margin: 20px auto;
  border: 1px solid black;
}

.alert-box-close {
  position: absolute;
  top: -12px;
  right: -12px;
  cursor: pointer;
}

.al-news #alert-box-news,
.al-maintenance #alert-box-maintenance {
  display: block;
}
<html>
  <head>
    <script type='text/javascript'>
      function has24HourPassed(key) {
        var storeval = localStorage.getItem(key);
        if (!storeval) return true;    /*  nothing stored in storage  */
        var T24_HOUR = 24 * 60 * 60 * 1000;
        if ((new Date - new Date(storeval)) < T24_HOUR) return false;        
        localStorage.removeItem(key);  /*  24 hours passed so we can remove stored date  */
        return true;
      }
      (function(d) {
        if (has24HourPassed('al-news')) {
          d.classList.add('al-news');
        }
        if (has24HourPassed('al-maintenance')) {
          d.classList.add('al-maintenance');
        }
      })(document.documentElement);
    </script>
  </head>
  
  <body>
    <article class="alert-box" id="alert-box-news">
      <h1>News Alerts</h1>
      <p>text text text text text text text text text text text text text text</p>
      <a class="alert-box-close" id="close-alert-box-news">
        <img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
      </a>
    </article>

    <article class="alert-box" id="alert-box-maintenance">
      <h1>Site Maintenance</h1>
      <p>text text text text text text text text text text text text text text</p>
      <a class="alert-box-close" id="close-alert-box-maintenance">
        <img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
      </a>
    </article>

    <button>For this demo - to clear local storage</button>

  </body>
</html>
Asons
  • 84,923
  • 12
  • 110
  • 165
-1

My concrete and lendi process I suggesting you maintain back end database(like sql , mysql etc.) table for that can simple hold user_id, alert box display or not this type of 2 columns are create into that table.

1) If your user is registered user are used visit your site using user id or detail you can manage that alert box.

2) If user is not registered that time use MAC Id of visitor.

EKBG
  • 243
  • 1
  • 8
  • 20