简体   繁体   中英

How to reuse the same code multiple times - html/css

I want to reuse the modal twice for each button.

Code of the button:

 function popUp_model(){ const pop_up_model = document.getElementById('model'); pop_up_model.classList.toggle('active'); }
 body{ background: black; }.wrapper { display: flex; } #container { display: flex; align-items: center; justify-content: center; margin: 0 100px; }.button { margin-top: 58px; align-content: left; --y: -25; --x: 0; --rotation: 0; --speed: 2; /* REMOVED: --txt: "About Me"; */ --padding: 1rem 1.25rem; cursor: pointer; padding: var(--padding); border: 4px solid; border-color: #00fffe; color: white; /* changed */ font-weight: bold; font-size: 1.25rem; transition: background 0.1s ease; background: hsl(var(--grey), 100%, 50%); animation-name: flow-and-shake; -webkit-animation-duration: calc(var(--speed) * 1s); animation-duration: calc(var(--speed) * 1s); -webkit-animation-iteration-count: infinite; animation-iteration-count: infinite; -webkit-animation-timing-function: ease-in-out; animation-timing-function: ease-in-out; }.button:hover { background: hsl(var(--grey), 100%, 40%); --speed: 0.1; --rotation: -1; --y: -1; --x: 1; } @-webkit-keyframes flow-and-shake { 0%, 100% { transform: translate(calc(var(--x) * -1%), 0) rotate(calc(var(--rotation) * -1deg)); } 50% { transform: translate(calc(var(--x) * 1%), calc(var(--y) * 1%)) rotate(calc(var(--rotation) * 1deg)); } } /* modal*/ *, *::after, *::before { margin: 0; padding: 0; box-sizing: border-box; } body1 { background: transparent; font-family: "Courier New", Courier, monospace; font-size: 18px; display: flex; justify-content: center; align-items: center; min-height: 100vh; }.button { position: relative; } #model { position: absolute; z-index: 1; top: 50%; left: -100%; transform: translate(-50%, -50%); background: #101010; max-width: 450px; padding: 70px 50px; transition: 1s; visibility: hidden; } #model.active { visibility: visible; left: 50%; } #model.model-content { display: flex; justify-content: center; align-items: center; flex-direction: column; } #model.model-content img { width: 80px; } #model.model-content h2 { font-size: 24px; font-weight: 800; margin: 20px 0px; }.model-input { margin-top: 20px; width: 100%; }.model-input input { width: 100%; border: 1px solid; padding: 15px; outline: none; font-size: 18px; }.model-input input[type="submit"] { letter-spacing: 2px; cursor: pointer; }.model-input input[type="submit"]:hover { letter-spacing: 4px; }.close-model { position: absolute; top: 30px; right: 30px; cursor: pointer; }.close-model img { width: 20px; }
 <div id="container"> <div class="button__wrap"> <button class="button" style="--hue: 162.03381670949574" onclick="popUp_model()" >About me</button> </div> <div class="button__wrap"> <button class="button" style="--hue: 162.03381670949574" onclick="popUp_model()">My Projects</button> <div class="button__shadow"></div> </div> </div>

For each of the above buttons, I want the modal to appear on the click.

I want the modal twice. One for the About Me button and then one for the Projects button. The About Me button modal should be different than the Projects button one, as I should be able to add different text for each of the modal's. Any suggestions on how I can reuse the code of the modal twice?

Use a loop to iterate over your open modal button elements. Use the class to select them and then iterate over each one within an event listener. This can be done using a querySelectorAll() method to select the element that opens the modals (your buttons) and a forEach loop to iterate over the button elements. Use the value and key in your forEach loop to handle the modal elements that pair with the buttons modal[key] .

button.forEach((btn, i)=>{ 
   btn.addEventListener(()=>{
      modal[i].style.display = 'block';
      // the rest of the modal open code would go here 
   }) 
}).

This will use the key value i for the iteration of the element being triggered by the event listener. Depending on how you have your modal code set up, the code would vary... Whether you are creating elements or making them visible using CSS...

Below is an example of code that uses an object of modal types and their content to create elements. The key though for your question is how to use a function on each one... A forEach loop embedding an event listener does the trick modalBtn.forEach((el, i) => openModal(el, i)); . In the openModal function there is an event listener that takes the params of the loops value and key .

 const modals = { 0: { type: 'text', buttonName: 'First Modal', header: "Header for the First Modal", footer: "Footer for the first modal", content: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Est tempora, tenetur temporibus voluptatem quaerat facere sapiente quod aliquid veniam culpa itaque eius quibusdam vitae beatae magnam repellendus laborum molestias a.' }, 1: { type: 'image', buttonName: '1st Image', header: false, footer: 'This is a brief explaination of the image.', content: 'http://3.imimg.com/data3/VL/AV/MY-1921873/noida-authority-building-noida-uttar-pradesh-india-500x500.jpg' }, 2: { type: 'image', buttonName: '2nd Image', header: false, footer: 'This is another brief explaination of the image.', content: 'http://3.bp.blogspot.com/-I6NbACJixe4/TcQiPSDyXMI/AAAAAAAAAAo/7rFILVJI5sI/s1600/paisagens-naturais-brasil-2.jpg' }, 3: { type: 'text', buttonName: 'Fourth Modal', header: "This is the fourth Modal", footer: "This is the footer for the fourth modal", content: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Est tempora, tenetur temporibus voluptatem quaerat facere sapiente quod aliquid veniam culpa itaque eius quibusdam vitae beatae magnam repellendus laborum molestias a.' }, } let cont = document.getElementById('modals'); let buttons = document.getElementById('buttons'); let images = document.getElementById('images'); // function to construct a text modal function constTextModal(mod) { let button = document.createElement("BUTTON"); let createModal = document.createElement("DIV"); let createModalContent = document.createElement("DIV"); let createModalHeader = document.createElement("DIV"); let createCloseBtn = document.createElement("SPAN"); let h2 = document.createElement("H2"); let createModalBody = document.createElement("DIV"); let modalPar = document.createElement("P"); let createModalFooter = document.createElement("DIV"); let h3 = document.createElement("H3"); button.classList.add('textBtn'); button.classList.add('modalBtn'); button.textContent = `Open ${modals[mod].buttonName}`; createModal.classList.add('modal'); createModalContent.classList.add('modal-content'); createModalHeader.classList.add('modal-header'); createCloseBtn.classList.add('closeBtn'); createModalBody.classList.add('modal-body'); createModalFooter.classList.add('modal-footer'); buttons.append(button); cont.append(createModal); createModal.append(createModalContent); createModalContent.append(createModalHeader, createModalBody, createModalFooter); createModalHeader.append(createCloseBtn, h2); createModalBody.append(modalPar); createModalFooter.append(h3); createCloseBtn.textContent = 'x'; h2.textContent = modals[mod].header; modalPar.textContent = modals[mod].content; createModalFooter.textContent = modals[mod].footer; } // function to contruct an image modal function constImageModal(mod) { let button = document.createElement("BUTTON"); let createModal = document.createElement("DIV"); let createModalContent = document.createElement("DIV"); let createCloseBtn = document.createElement("SPAN"); let createModalHeader = document.createElement("DIV"); let createModalBody = document.createElement("DIV"); let modalImg = document.createElement("IMG"); let createModalFooter = document.createElement("DIV"); let h3 = document.createElement("H3"); button.classList.add('textBtn'); button.classList.add('modalBtn'); button.textContent = `Open ${modals[mod].buttonName}`; createModalHeader.classList.add('img-header'); createModal.classList.add('modal'); createModalContent.classList.add('modal-content'); createCloseBtn.className = 'closeBtn imgCloseBtn'; createModalBody.classList.add('modal-body'); modalImg.classList.add('modalImg'); createModalFooter.classList.add('modal-footer'); buttons.append(button); cont.append(createModal); createModal.append(createModalContent); createModalHeader.append(createCloseBtn); createModalContent.append(createModalHeader, createModalBody, createModalFooter); createModalBody.style.cssText = 'display: flex; justify-content: center; align-items: center;'; createModalBody.append(modalImg); createModalFooter.append(h3); createCloseBtn.textContent = 'x'; modalImg.src = modals[mod].content; createModalFooter.textContent = modals[mod].footer; } // conditional to check obj type for (let mod in modals) { if (modals[mod].type === 'text') { constTextModal(mod); } else if (modals[mod].type === 'image') { constImageModal(mod); } else { // different type oif medium } } // get the modal element let modal = document.querySelectorAll('.modal'); // get the modal button let modalBtn = document.querySelectorAll('.modalBtn'); // get the close button let closeBtn = document.querySelectorAll('.closeBtn'); // event listener to open the modal modalBtn.forEach((el, i) => openModal(el, i)); // function to open the targeted modal function openModal(el, i) { el.addEventListener('click', () => { modal[i].style.animationName = 'animateModal'; modal[i].style.display = 'flex'; }) } // event listener to close the modal on closeBtn closeBtn.forEach((el, i) => closeButton(el, i)); // function to close the targeted modal function closeButton(el, i) { el.addEventListener('click', () => { modal[i].style.animationName = 'closeModal'; setTimeout(() => { modal[i].style.display = 'none'; }, 500); }) } // event listener to close the modal on window click window.addEventListener('click', clickOutside); // funciton to close the targeted modal on outside click function clickOutside(e) { modal.forEach((el, i) => { if (e.target == el) { modal[i].style.animationName = 'closeModal'; setTimeout(() => { modal[i].style.display = 'none'; }, 500); } }) }
 body{ font-family: Arial, Helvetica, sans-serif; font-size: 17px; line-height: 1.6; }.modalBtn { background: coral; padding: 1em 2em; color: #fff; border: 0; }.imgCloseBtn { padding-right: 20px; }.modalBtn:hover{ background-color: #333; }.modal { display: none; align-items: stretch; position: fixed; z-index: 1; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.5); animation-name: animateModal; animation-duration: 0.7s; animation-timing-function: ease-in-out; }.modal-content { background: #f4f4f4; display: flex; align-items: stretch; flex-direction: column; margin: 20% auto; max-width: 70%; box-shadow: 0 5px 8px 0 rgba(0,0,0,0.2), 0 7px 20px 0 rgba(0,0,0,0.2); animation-name: animateModal; animation-duration: 0.7s; animation-timing-function: ease-in-out; border-radius: 21px; }.modal-header h2, .modal-footer h3 { margin: 0; }.modal-header { background: coral; padding: 15px; color: #f4f4f4; border-top-left-radius: 20px; border-top-right-radius: 20px; }.modal-body { padding: 10px 20px; background-color: #fff; }.modal-footer { background: coral; padding: 10px; color: #fff; text-align: center; border-bottom-left-radius: 20px; border-bottom-right-radius: 20px; }.closeBtn { color: #ccc; font-size: 20px; float: right; }.closeBtn:hover, .closeBtn:focus { color: #000; text-decoration: none; cursor: pointer; } @keyframes animateModal { from { opacity: 0; } to { opacity: 1; } } @keyframes closeModal { from { opacity: 1; } to { opacity: 0; } }
 <div id="buttons"> </div> <div id="images"> </div> <div id="modals"> </div>

NOTE: once I create the button elements in my constModal function/s above, I can then add a class to them using, button.classList.add('modalBtn'); , so my button elements will have the class modalBtn . So when I iterate over that class, I can call on the modals class selector using let modal = document.querySelectorAll('.modal'); and create an event listener within a forEach loop that uses the buttons index, set in the forEach loop, to get the modal element I wish to open, using it's corresponding index => modal[i] .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM