Skip to content

Instantly share code, notes, and snippets.

@ahngoo8Gongi
Last active July 6, 2020 18:44
Show Gist options
  • Save ahngoo8Gongi/7656bfda2724ad1b5cdc323da1923708 to your computer and use it in GitHub Desktop.
Save ahngoo8Gongi/7656bfda2724ad1b5cdc323da1923708 to your computer and use it in GitHub Desktop.

Snippet for a tooltip like popup

For a project I needed a snippet which presents arbitrary HTML code in a tooltip like popup window, when the mouse hovers over an HTML ELement. I couldn't find one solving my complete problem, but on https://www.w3schools.com/howto/howto_js_popup.asp I found a suitable template to build on.

<!DOCTYPE html>
<html>
<head>
<style>
/* copied and slightly modified from w3schools */
.popup_host_class {
  position: relative;
}
.popup_host_class .popup {
  visibility: hidden;
  width: 160px;
  background-color: #555;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 8px 0;
  position: absolute;
  z-index: 1;
  bottom: 125%;
  left: 50%;
  margin-left: -80px;
}
.popup_host_class .popup::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}
.popup_host_class .show {
  visibility: visible;
  -webkit-animation: fadeIn 1s;
  animation: fadeIn 1s
}
.popup_host_class .triggered {
  border-radius: 6px;
  border-width: 1px;
  border-color: #000;
  border-style: solid; 
}

/* Add animation (fade in the popup) */
@-webkit-keyframes fadeIn {
  from {opacity: 0;}
  to {opacity: 1;}
}

@keyframes fadeIn {
  from {opacity: 0;}
  to {opacity:1 ;}
}
</style>
<body>
<div id="popup_host" class="popup_host_class">Hover over me!</div>
<script>
const ENTER_DELAY=1000;
const POPUP_DELAY=1000;

function popup_element() {
  var node = document.createElement("span");
  node.setAttribute("id","PopupElement");
  node.innerHTML="Popuptext";
  return node;
}

var popup_host = document.getElementById("popup_host");
popup_host.addEventListener("mouseenter", function (event) {
    this.classList.add("triggered");
    /* 
     * After the mouse has entered the host, we wait for 
     * ENTER_DELAY ms before we who the popup
     */
    this.mouseover_timeout_fn = setTimeout( function(arg) {
        arg[0].classList.remove("triggered");
        let popup = popup_element();
        popup.classList.add("popup");
        popup.classList.add("show");
        /*
         * We close the popup after we click on it...
         */
        popup.addEventListener("click", function () {
            if (this.fade_out_timer) {
	        clearTimeout(this.fade_out_timer);
                his.fade_out_timer = null;
            }
            this.classList.remove("show");
        });
        /*
         * ...or after POPUP_DELAY has passed, unless...
         */
        popup.addEventListener("mouseout", function () {
            if (this.classList.contains("show")) {
                this.fade_out_timer = setTimeout ( function (iarg) {
                    iarg[0].fade_out_timer = null;
                    iarg[0].classList.remove("show");
                }, POPUP_DELAY, [this]);
            }
        });
        /*
         * ... the mouse is on the popup.
         */
        popup.addEventListener("mouseenter", function () {
            if (this.fade_out_timer) {
                clearTimeout(this.fade_out_timer);
                this.fade_out_timer = null;
            }
        });
        /*
         * we start the initial POPUP_DELAY
         */
        popup.fade_out_timer = setTimeout ( function (iarg) {
            iarg[0].fade_out_timer = null;
            iarg[0].classList.remove("show");
        }, POPUP_DELAY, [popup]);
        /* 
         * and add the popup to its host 
         */
	arg[0].append(popup);
    }, ENTER_DELAY, [this] );
});
/*
 * After the mouse has left the host without
 * ENTER_DELAY having passed, we cancel the popup display
 */
popup_host.addEventListener("mouseout", function (event) {
    if ( this.mouseover_timeout_fn ) {
        this.classList.remove("triggered");
        clearTimeout(this.mouseover_timeout_fn);
        this.mouseover_timeout_fn = null;
    }
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment