I have this array of objects
const GALLERY = [
{
color: "red",
titulo: "Stuff"
},
{
color: "pink",
titulo: "Thing"
},
{
color: "green",
titulo: "Something"
}
];
and these functions with template literals
function galTemplate(gal) {
let modalBtn = gal.color + "-btn";
return `
<div class="content-entry" id="${modalBtn}">
<div href="" style="background-color: ${gal.color};"></div>
<p class="gallery-entry-titulo">${gal.titulo}</p>
</div>
`
}
function galModal(modal) {
let modalModal = modal.color + "-modal";
return `
<div class="popup-bg" id="${modalModal}">
<div class="entry-popup">
<div style="background-color: ${modal.color};></div>
</div>
</div>
`
}
The situation is that I want to use the variables modalBtn and modaModal with their values to create a simple modal function that looks like this
modalBtn.onclick = function() {
modalModal.style.display = "block";
}
Of course, this is an example of the real project. This is the Codepen of the complete example for best comprehension
You can declare variables outside the scope of a function with the keyword var
like this:
var my_global = 1;
function do_something_with_global() {
console.log(my_global++);
}
do_something_with_global(); // will print: 1
console.log(my_global); // will print: 2
They will live in the global space so you can access them from everywhere. This is generally a bad design choice because this stuff will not be garbage collected (in a function-scope the memory will be freed once it is executed).
Besides, globals can be modified from everywhere now, so you don't want that either. There could be hard-to-spot bugs when you accidentially override the variables, too.
Just be aware of this. You may also want to read this here: https://www.w3.org/wiki/JavaScript_best_practices
I would probably choose a different way of creating the elements and rendering them in one go (i.e. createElement()
and then add the listeners and modals in sequence).
However, I wanted to change as few as possible so that you can work with it more easily.
You could and probably should also just toggle a CSS class instead of modifying the individual attributes.
How about the following:
const GALLERY = [{
color: 'red',
titulo: 'Stuff'
},
{
color: 'pink',
titulo: 'Thing'
},
{
color: 'green',
titulo: 'Something'
}
];
function galTemplate(gal) {
let modalBtn = gal.color + '-btn';
return `
<div class="content-entry" id="${modalBtn}">
<div href="" style="background-color: ${gal.color};"></div>
<p class="gallery-entry-titulo">${gal.titulo}</p>
</div>
`;
}
function galModal(modal) {
let modalModal = modal.color + '-modal';
return `
<div class="popup-bg" id="${modalModal}">
<div class="entry-popup">
<div style="background-color: ${modal.color};"></div>
</div>
</div>
`;
}
function addClickListeners(gal) {
let btnId = gal.color + '-btn';
let modalId = gal.color + '-modal';
let elBtn = document.getElementById(btnId);
let elModal = document.getElementById(modalId);
elBtn.onclick = function() {
console.log('click: btn: ' + this.id + ', modal: ' + elModal.id);
elModal.classList.toggle('show-popup');
}
/* to dispose the popup on click */
elModal.onclick = function() {
this.classList.toggle('show-popup');
}
/* --- */
}
document.getElementById("my-content").innerHTML = `
<div class="content">
${GALLERY.map(galTemplate).join('')}
</div>
${GALLERY.map(galModal).join('')}
`;
GALLERY.map(addClickListeners);
body {
background: #01235f;
color: white;
}
.content {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-gap: 0px;
grid-auto-rows: 1fr;
}
.content-entry {
width: 150px;
height: 150px;
position: relative;
cursor: pointer;
}
.content-entry div {
width: 100%;
height: 100%;
}
.gallery-entry-titulo {
position: absolute;
bottom: 10px;
left: 50%;
transform: translate(-50%, -30%);
cursor: pointer;
}
.popup-bg {
display: none;
position: fixed;
z-index: 3;
left: 0;
top: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(5px);
}
.show-popup {
display: block;
}
.entry-popup {
position: absolute;
z-index: 9;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 50%;
height: 80%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
padding: 60px;
}
.entry-popup div {
width: 100%;
height: 100%;
margin: 20px auto;
}
<div class="content" id="my-content"></div>