1

I have an alert box that I want to use sessionStorage so that it only appears once. When the user clicks to close the alert, I want the box to disappear (display:none) but fade-out.

I read that you have to use two different functions - one that is activated when clicked and starts the transition and another the adds the 'display' style once transitioned. However, I can't get that to work:

<style>

    .ddAlert {
        padding: 20px;
        box-sizing: border-box;
        background-color: #f0ad4e;
        color: #fff;
        opacity: 1;
        transition: opacity 1s;
    }

    .hide {
        opacity: 0;
        display: none;
    }

</style>

<script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function() {
        let dismissed = sessionStorage.getItem("dismissed");
        let alertDiv = document.getElementById("alert");
        let dismissButton = document.getElementById("dismiss");
        if (!dismissed) {
            alertDiv.classList.remove("hide");
        }

        alertDiv.addEventListener("click", function() {
            this.style.display = "block";
        }.bind(alertDiv));

        alertDiv.addEventListener("transitionend", function() {
            if (this.className == "hide") {
                this.style.display = "none";
            }
            sessionStorage.setItem("dismissed", true);
        }.bind(alertDiv));
    });

</script>

<div class="ddAlert hide" id="alert">
    SOME ANNOYING ALERT HERE!
    <button type="button" id="dismiss">X</button>
</div>
DD1229
  • 396
  • 5
  • 16

2 Answers2

1

You are on the right track. Instead of listening on click on the alert, use the button as I assume it is there for that reason. When clicking the button the .hide class should be added to the alert. This will start the transition from opacity: 1; to opacity: 0;.

I suggest that instead of using inline-styles, that you stick to classes. Inline styles are hard to overwrite and prevents you from utilizing the full power of CSS. So I've added some classes in there to help you out.

Try out the example below.

<div class="ddAlert hidden" id="alert">
    SOME ANNOYING ALERT HERE!
    <button type="button" id="dismiss">X</button>
</div>
.ddAlert {
  display: block;
  transition: opacity 1s;
}

.hide {
  opacity: 0;
}

.hidden {
  display: none;
}
document.addEventListener("DOMContentLoaded", function() {
  let dismissed = sessionStorage.getItem("dismissed");
  let alertDiv = document.getElementById("alert");
  let dismissButton = document.getElementById("dismiss");

  if (!dismissed) {
    alertDiv.classList.remove("hidden");
  }

  dismissButton.addEventListener("click", function() {
    alertDiv.classList.add("hide");
  });

  alertDiv.addEventListener("transitionend", function({ target }) {
    if (target.classList.contains("hide")) {
      target.classList.add("hidden");
    }
    sessionStorage.setItem("dismissed", true);
  });

});
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32
0

This answer greatly lends from this SO question titled CSS3 Transition - Fade out effect which notes

When showing the element (by switching to the visible class), we want the visibility:visible to kick in instantly, so it’s ok to transition only the opacity property. And when hiding the element (by switching to the hidden class), we want to delay the visibility:hidden declaration, so that we can see the fade-out transition first. We’re doing this by declaring a transition on the visibility property, with a 0s duration and a delay.

I chose not to mark this question as a duplicate because it also involves the transitionend event. Additionally, I've focused only on the essence of the transition, with a minimal illustration.

The crucial element is the .dismissed-saved class.

let alertDiv = document.getElementById("alert");
let dismissButton = document.getElementById("dismiss");

dismissButton.addEventListener("click", function() {
  // kick in the transition      
  alertDiv.classList.add("dismissed-saved");
  // *this is where state should be committed
});

alertDiv.addEventListener("transitionend", function({
  target
}) {
  if (target === alertDiv) {
    // clean up and show a nifty text message illustrating the event handler.
    target.classList.add("hidden");
    target.classList.remove("dismissed-saved");
    document.getElementById("dismissed").classList.remove('hidden');
  }
});
.ddAlert {
  padding: 20px;
  box-sizing: border-box;
  background-color: #f0ad4e;
  color: #fff;
  opacity: 1;
}

.hidden {
  display: none;
}

.dismissed-saved {
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s 2s, opacity 2s linear;
}
<div class="ddAlert" id="alert">
  SOME ANNOYING ALERT HERE!
  <button type="button" id="dismiss">X</button>
</div>
<div id="dismissed" class="hidden">
  Dismissed!
</div>

Good luck!

RamblinRose
  • 4,883
  • 2
  • 21
  • 33