Проблемка с модальным окном

197
05 июля 2018, 01:10

Вот есть такое модальное окно:

var num = 15; 
 
var modalBtn = document.querySelector('.open'); 
var closeBtn = document.querySelector('.close'); 
 
var modalContainer = document.querySelector('.modals'); 
var holdModals = document.createDocumentFragment(); 
 
for (var i = 0; i < num; i++) { 
  var div = document.createElement('div'); 
  div.classList.add('modal-drop'); 
  div.style.top = Math.floor((Math.random() * 100)) + 'vh'; 
  div.style.left = Math.floor((Math.random() * 100)) + 'vw'; 
  div.style.transitionDelay = Math.random() + 's'; 
  holdModals.appendChild(div); 
} 
console.log(); 
modalContainer.appendChild(holdModals); 
 
modalBtn.addEventListener('click',function(){ 
  modalContainer.style.display = 'block';   
  window.setTimeout(function(){ 
    modalContainer.classList.add('active'); 
  },0.1); 
}); 
 
closeBtn.addEventListener('click',function(){ 
   modalContainer.classList.remove('active'); 
   
   window.setTimeout(function(){ 
    modalContainer.style.display = 'none'; 
  },3000); 
});
.card { 
  position: relative; 
} 
 
.modals { 
  color: #fff; 
  display: none; 
  position: fixed; 
    top: 0; 
    right: 0; 
    bottom: 0; 
    left: 0; 
   
  &.active {     
    .modal-drop { 
      transform-origin: 50%; 
      transform: scale(1); 
    } 
     
    .modal-content { 
      opacity: 1; 
      transition: 0.5s ease-in 1.5s; 
    } 
  } 
} 
 
.modal-drop { 
  background: hsl(250,30%,10%); 
  border-radius: 50%; 
  width: 150vh; 
  height: 150vh; 
  position: absolute; 
  margin-left: -75vh; 
  margin-top: -75vh; 
  transition: transform 2s cubic-bezier(.25,1,.60,1), transform-origin 0s; 
  transform: scale(0.001); 
  transform-origin: 0 0; 
} 
 
.modal-content { 
  background: hsl(250,30%,10%); 
  position: fixed; 
  top: 0; 
  right: 0; 
  bottom: 0; 
  left: 0; 
  opacity: 0; 
  z-index: 1; 
  transition: 0.5s 0s; 
   
  display: flex; 
  align-items: center; 
  justify-content: center; 
} 
 
.modal-wrap { 
  flex: 1; 
  width: 100%; 
  max-width: 50em;   
} 
 
/* Page Styling */ 
 
$font-size: 18/16*1em; 
 
::selection { 
  background: hsl(40,100%,65%); 
  color: #fff; 
} 
 
::-moz-selection { 
  background: hsl(40,100%,65%); 
  color: #fff; 
} 
 
html, body { 
  height: 100%; 
} 
 
body { 
  background: hsl(30,10%,90%); 
  color: hsl(200,50%,20%); 
  font: #{$font-size}/1.65 'Open Sans', sans-serif; 
  letter-spacing: 0.01em; 
  text-rendering: optimizeLegibility; 
   
  display: flex; 
  align-items: center; 
  justify-content: center; 
} 
 
.card { 
  background: #fff; 
  flex: 1; 
  max-width: 20em; 
  padding: 3em; 
  position: relative; 
  width: 100%; 
   
  &::before { 
    content: ''; 
    border: 1px dotted hsl(165,80%,70%); 
    position: absolute; 
      top: 1.25em; 
      right: 1.25em; 
      bottom: 1.25em; 
      left: 1.25em; 
    pointer-events: none; 
  } 
   
  p { 
    margin: 0.5em 0 1em; 
    padding-bottom: 2em; 
    border-bottom: 1px solid hsl(149,70%,90%); 
    //text-align: center; 
    //font-style: italic; 
    //font-family: 'Playfair Display', serif; 
  } 
} 
 
.open, 
.close { 
  background: linear-gradient(hsl(149,65%,74%),hsl(155,67%,68%)); 
  border: 1px solid hsl(155,67%,68%); 
  border-bottom: 4px solid hsl(165,70%,55%); 
  border-radius: 2px; 
  color: #fff; 
  font-weight: 600; 
  margin-top: 0.5em; 
  padding: 0.5em 1em 0.4em; 
  text-shadow: 1px 1px 0 hsl(165,70%,55%); 
  transition: 0.3s; 
   
  &:hover { 
    filter: brightness(90%) contrast(120%); 
  } 
   
  &:focus { 
    box-shadow: 0 0 10px hsl(149,65%,74%); 
    outline: none; 
  } 
   
  float: right; 
} 
 
.close { 
  background: linear-gradient(hsl(10,95%,59%),hsl(360,95%,59%)); 
  border: 1px solid hsl(360,95%,59%); 
  border-bottom: 4px solid hsl(360,95%,43%); 
  text-shadow: 1px 1px 0 hsl(360,95%,43%); 
   
  &:focus { 
    box-shadow: 0 0 10px hsl(10,95%,59%); 
  } 
}
<div class="card"> 
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt deserunt velit in blanditiis, cupiditate possimus sapiente tenetur porro accusantium animi?</p> 
   
  <button class="open">Modal</button> 
</div> 
 
<div class="modals"> 
  <div class="modal-content"> 
    <div class="modal-wrap"> 
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore ab officiis libero reiciendis voluptas hic quas sit aspernatur exercitationem numquam obcaecati dolore sed voluptates, at aliquam cum harum, necessitatibus, expedita quod et magni? Possimus maiores vero suscipit ipsum veritatis, omnis pariatur magnam voluptatibus quisquam sequi veniam quas, et, dignissimos perspiciatis.</p> 
      <button class="close">Close</button> 
    </div> 
  </div> 
</div>

https://codepen.io/giana/pen/gPGGgE

Но его можно привязать только к одному элементу.
Как сделать так, чтобы при нажатии на несколько разных div, открывалось это модальное окно?
И еще, если не трудно - как сделать чтобы при нажатии на разные div открывались такие же модальные окна, но с разным контентом внутри?

Answer 1

Вот пример того что нужно сделать: https://codepen.io/Telion/pen/jKyWwy

Для того что бы выбрать Все элементы с классом нужно использовать querySelectorAll вместо querySelector. Что бы к нему после этого применить обработчики событий нужно пройтись циклом:

Array.from(modalBtn).forEach(btn => {
    btn.addEventListener('click', function(e) {
      e.preventDefault();
      modalContainer.style.display = 'block';  
      window.setTimeout(function(){
        modalContainer.classList.add('active');
      },0.1);
    });
});

Для серии разных модальных окон вам нужно по сути сделать тоже самое, так есть пройтись массивом и назначить каждое к нужной кнопке. Тем не менее я бы посоветовал добавить аттрибут типа modal-name="modal-menu" и через него знать какой div открывает какое модальное окно. Будут вопросы создайте новый пост, буду рад помочь.

Пример: http://jsfiddle.net/Telion/41j8yro3/

$('.open').on("click", function(e) { 
  e.preventDefault(); 
  let modal = $(this).attr("modal"); 
  $("#"+modal).css({display: 'flex'}).stop().animate({opacity: 1}, 300); 
}); 
 
$('.close').on("click", function(e) { 
  e.preventDefault(); 
  $(this).parents('.modal-content').stop().animate({opacity: 0}, 600, function() {$(this).css({display: 'none'})}); 
})
.card { 
  position: relative; 
} 
 
.modal-content { 
  background: hsl(250,30%,10%); 
  position: fixed; 
  top: 0; 
  right: 0; 
  bottom: 0; 
  left: 0; 
  display: none; 
  opacity: 0; 
  z-index: 1; 
  transition: 0.5s 0s; 
  align-items: center; 
  justify-content: center; 
} 
 
.modal-wrap { 
  flex: 1; 
  width: 100%; 
  max-width: 50em;   
} 
 
/* Page Styling */ 
 
$font-size: 18/16*1em; 
 
::selection { 
  background: hsl(40,100%,65%); 
  color: #fff; 
} 
 
::-moz-selection { 
  background: hsl(40,100%,65%); 
  color: #fff; 
} 
 
html, body { 
  height: 100%; 
} 
 
body { 
  background: hsl(30,10%,90%); 
  color: hsl(200,50%,20%); 
  font: #{$font-size}/1.65 'Open Sans', sans-serif; 
  letter-spacing: 0.01em; 
  text-rendering: optimizeLegibility; 
   
  display: flex; 
  align-items: center; 
  justify-content: center; 
} 
 
.card { 
  background: #fff; 
  flex: 1; 
  max-width: 20em; 
  padding: 3em; 
  position: relative; 
  width: 100%; 
   
  &::before { 
    content: ''; 
    border: 1px dotted hsl(165,80%,70%); 
    position: absolute; 
      top: 1.25em; 
      right: 1.25em; 
      bottom: 1.25em; 
      left: 1.25em; 
    pointer-events: none; 
  } 
   
  p { 
    margin: 0.5em 0 1em; 
    padding-bottom: 2em; 
    border-bottom: 1px solid hsl(149,70%,90%); 
    //text-align: center; 
    //font-style: italic; 
    //font-family: 'Playfair Display', serif; 
  } 
} 
 
.open, 
.close { 
  background: linear-gradient(hsl(149,65%,74%),hsl(155,67%,68%)); 
  border: 1px solid hsl(155,67%,68%); 
  border-bottom: 4px solid hsl(165,70%,55%); 
  border-radius: 2px; 
  color: #fff; 
  font-weight: 600; 
  margin-top: 0.5em; 
  padding: 0.5em 1em 0.4em; 
  text-shadow: 1px 1px 0 hsl(165,70%,55%); 
  transition: 0.3s; 
   
  &:hover { 
    filter: brightness(90%) contrast(120%); 
  } 
   
  &:focus { 
    box-shadow: 0 0 10px hsl(149,65%,74%); 
    outline: none; 
  } 
   
  float: right; 
} 
 
.close { 
  background: linear-gradient(hsl(10,95%,59%),hsl(360,95%,59%)); 
  border: 1px solid hsl(360,95%,59%); 
  border-bottom: 4px solid hsl(360,95%,43%); 
  text-shadow: 1px 1px 0 hsl(360,95%,43%); 
   
  &:focus { 
    box-shadow: 0 0 10px hsl(10,95%,59%); 
  } 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="card"> 
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt deserunt velit in blanditiis, cupiditate possimus sapiente tenetur porro accusantium animi?</p> 
   
  <button class="open" modal="modal1">Modal</button> 
  <button class="open" modal="modal2">Moda2</button> 
</div> 
 
 
<div id="modal2" class="modal-content"> 
  <div class="modal-wrap"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore ab officiis libero reiciendis voluptas hic quas sit aspernatur exercitationem numquam obcaecati dolore sed voluptates, at aliquam cum harum, necessitatibus, expedita quod et magni? Possimus maiores vero suscipit ipsum veritatis, omnis pariatur magnam voluptatibus quisquam sequi veniam quas, et, dignissimos perspiciatis.</p> 
    <button class="close">Close</button> 
  </div> 
</div> 
<div id="modal1" class="modal-content"> 
  <div class="modal-wrap"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore ab officiis libero reiciendis voluptas hic quas sit aspernatur exercitationem numquam obcaecati dolore sed voluptates, at aliquam cum harum, necessitatibus, expedita quod et magni? Possimus maiores vero suscipit ipsum veritatis, omnis pariatur magnam voluptatibus quisquam sequi veniam quas, et, dignissimos perspiciatis.</p> 
    <button class="close">Close</button> 
  </div> 
</div>

READ ALSO
Не работает плагин gulp-sourcemap

Не работает плагин gulp-sourcemap

Имеется такой gulpfile

337
Vuex (Vue.js) - глобальное сообщение об ошибке

Vuex (Vue.js) - глобальное сообщение об ошибке

Как сделать глобальное глобальные ошибки в Vue (через Vuex)?

125
Как сделать спрайтовую анимацию?

Как сделать спрайтовую анимацию?

Как сделать спрайтовую анимацию,чтобы можно было разобраться и удобно настроить (ширину картинки и количество слайдов)? И еще нужно сделать...

338