A Pen by Malcolm Rodrigues on CodePen.
Created
January 4, 2023 10:35
-
-
Save Rod911/2adaeda45f3072706223bf7d3bcb2599 to your computer and use it in GitHub Desktop.
Create Popup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<button class="popup-btn1">Popup</button> | |
<div class="popup-wrapper" id="popup1"> | |
<div class="popup-overlay popup-dismiss"></div> | |
<div class="popup-container"> | |
<button class="popup-close popup-dismiss">×</button> | |
<div class="popup-content"> </div> | |
</div> | |
</div> | |
<button class="popup-btn2">Popup sidemenu</button> | |
<div class="popup-wrapper popup-slide-in" id="popup2"> | |
<div class="popup-overlay popup-dismiss"></div> | |
<div class="popup-container" style="max-width: 350px;"> | |
<button class="popup-close popup-dismiss">×</button> | |
<h3 class="popup-title">Popup</h3> | |
<div class="popup-content"> </div> | |
</div> | |
</div> | |
<button class="popup-btn3">Popup new</button> | |
<script> | |
document.addEventListener("DOMContentLoaded", function() { | |
var popup1 = setUpPopup(document.querySelector("#popup1"), ".popup-btn1"); | |
var popup2 = setUpPopup(document.querySelector("#popup2"), ".popup-btn2"); | |
let newPopup = createPopup({ | |
id: "test", | |
trigger: ".popup-btn3", | |
slideIn: true, | |
}); | |
}); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @param {HTMLElement} popup Popup container | |
* @param {String} trigger Open popup trigger selector | |
* @param {Number} autoOpen Auto Open delay | |
* @returns {{ | |
* popup: HTMLElement, | |
* openPopup: Function, | |
* dismissPopup: Function, | |
* on: { | |
* open: Function, | |
* close: Function | |
* } | |
* }} | |
*/ | |
function setUpPopup(popup, trigger = "", autoOpen = false) { | |
if (!popup) return; | |
if (autoOpen) | |
setTimeout(() => { | |
openPopup(); | |
}, parseInt(autoOpen)); | |
let on = { | |
open: function (obj = null) {}, | |
close: function (obj = null) {} | |
}; | |
popup.querySelectorAll(".popup-dismiss").forEach((dismiss) => { | |
dismiss.addEventListener("click", dismissPopup); | |
}); | |
if (trigger) { | |
document.querySelectorAll(trigger).forEach((triggerElement) => { | |
triggerElement.addEventListener("click", openPopup); | |
}); | |
} | |
/** | |
* @param {MouseEvent} e | |
*/ | |
function dismissPopup(e = null) { | |
popup.classList.add("popup-closing"); | |
setTimeout(() => { | |
popup.classList.remove("popup-active", "popup-closing"); | |
}, 500); | |
document.documentElement.classList.remove("popup-open"); | |
on.close(); | |
window.activePopup = null; | |
} | |
/** | |
* @param {MouseEvent} e | |
*/ | |
function openPopup(e = null) { | |
if (e) e.preventDefault(); | |
let scrollbarWidth = window.innerWidth - document.body.clientWidth + "px"; | |
document.documentElement.setAttribute( | |
"style", | |
"--scrollbar-width: " + scrollbarWidth | |
); | |
if (window.activePopup && window.activePopup.dismissPopup) { | |
window.activePopup.dismissPopup(); | |
} | |
popup.classList.add("popup-active"); | |
document.documentElement.classList.add("popup-open"); | |
on.open(e); | |
window.activePopup = popup; | |
} | |
var popupWrapper = { | |
popup, | |
openPopup, | |
dismissPopup, | |
on | |
}; | |
popup.openPopup = openPopup; | |
popup.dismissPopup = dismissPopup; | |
return popupWrapper; | |
} | |
/** | |
* Create HTMLElement from HTML string | |
* @param {String} htmlString | |
* @returns {HTMLElement} | |
*/ | |
function createElementFromHTML(htmlString) { | |
var div = document.createElement("div"); | |
div.innerHTML = htmlString.trim(); | |
return div.firstChild; | |
} | |
/** | |
* @param {{ | |
* id: String, | |
* trigger: String|null, | |
* autoOpen: number|null, | |
* slideIn: Boolean, | |
* slideFromLeft: Boolean|null, | |
* title: String|null, | |
* popupHTML: String | HTMLElement | null | |
* }} options | |
*/ | |
function createPopup(options) { | |
if (options.popupHTML instanceof Element) { | |
options.popupHTML = options.popupHTML.outerHTML; | |
} | |
let popupTemplate = `<div class="popup-wrapper ${ | |
options.slideIn ? "popup-slide-in" : "" | |
}" data-slide-dir="${ | |
options.slideIn && options.slideFromLeft ? "left" : "right" | |
}" id="${ | |
options.id | |
}"><div class="popup-overlay popup-dismiss"></div><div class="popup-container"><button class="popup-close popup-dismiss">×</button>${ | |
options.title ? `<h3 class="popup-title">${options.title}</h3>` : `` | |
}<div class="popup-content">${ | |
options.popupHTML ? options.popupHTML : "" | |
}</div></div></div>`; | |
let popupElement = createElementFromHTML(popupTemplate); | |
document.body.appendChild(popupElement); | |
let popup = setUpPopup(popupElement, options.trigger, options.autoOpen); | |
return popup; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:root { | |
--scrollbar-width: 1rem; | |
} | |
html.popup-open { | |
overflow: hidden; | |
padding-right: var(--scrollbar-width); | |
} | |
.popup-wrapper { | |
position: fixed; | |
top: 0; | |
left: 0; | |
bottom: 0; | |
right: 0; | |
/* display: none; */ | |
visibility: hidden; | |
z-index: 50; | |
opacity: 0; | |
transition: ease-in-out 0.25s opacity; | |
} | |
.popup-wrapper.popup-closing, | |
.popup-wrapper.popup-active { | |
/* display: block; */ | |
visibility: visible; | |
opacity: 1; | |
} | |
.popup-wrapper .popup-overlay { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
background-color: #000; | |
opacity: 0.6; | |
transition: ease 0.3s opacity; | |
transition-delay: 0.3s; | |
} | |
.popup-wrapper.popup-active .popup-overlay { | |
opacity: 0.8; | |
transition-delay: 0s; | |
} | |
.popup-container { | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
width: 550px; | |
height: 400px; | |
max-width: calc(100% - 20px); | |
max-height: calc(100% - 40px); | |
transform: translate(-50%, -20%); | |
padding: 20px; | |
background-color: #fff; | |
border-radius: 5px; | |
box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.15); | |
transition: ease 0.25s transform 0.2s, ease 0.3s opacity 0s; | |
opacity: 0; | |
} | |
.popup-slide-in .popup-container { | |
top: 0; | |
right: 0; | |
height: 100%; | |
max-height: none; | |
border-radius: 0; | |
left: auto; | |
transform: translate(100%, 0); | |
padding-top: 15px; | |
display: grid; | |
grid-template-rows: 2rem 1fr; | |
} | |
.popup-slide-in[data-slide-dir="left"] .popup-container { | |
left: 0; | |
right: auto; | |
transform: translateX(-100%); | |
} | |
.popup-wrapper.popup-active .popup-container { | |
transform: translate(-50%, -50%); | |
transition-delay: 0s, 0s; | |
opacity: 1; | |
} | |
.popup-slide-in.popup-active .popup-container { | |
transform: translate(0, 0); | |
} | |
.popup-wrapper.popup-closing .popup-overlay { | |
opacity: 0; | |
transition: ease 0.3s opacity; | |
} | |
.popup-wrapper.popup-closing .popup-container { | |
opacity: 0; | |
transform: translate(-50%, -30%); | |
transition: ease 0.25s transform 0s, ease 0.3s opacity 0s; | |
} | |
.popup-slide-in.popup-closing .popup-container { | |
transform: translate(100%, 0); | |
} | |
.popup-slide-in.popup-closing[data-slide-dir="left"] .popup-container { | |
transform: translateX(-100%); | |
} | |
.popup-container .popup-close { | |
position: absolute; | |
top: 20px; | |
right: 20px; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
padding: 0; | |
width: 25px; | |
height: 25px; | |
background-color: #fff; | |
/* border: 1px solid #aaa; */ | |
border: none; | |
color: #999; | |
font-size: 26px; | |
font-weight: 600; | |
border-radius: 50px; | |
transform: translate(45%, -45%); | |
cursor: pointer; | |
} | |
.popup-content { | |
height: 100%; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: space-evenly; | |
overflow: auto; | |
padding: 20px 0; | |
} | |
.popup-slide-in .popup-content { | |
align-items: stretch; | |
justify-content: flex-start; | |
padding-bottom: 10px; | |
} | |
.popup-title { | |
font-weight: 600; | |
font-size: 18px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment