Modal

Właściwość slider

Zmiana popupów bez potrzeby zamykania

Slider Interaktywna lista instancji

Funkcjonalność slidera została dodana do modułu, aby wyświetlać kolejne powiązane modale bez potrzeby zamykania aktywnego okna. Jako wartość właściwość slider przyjmuje selektory CSS oraz tablicę dwuwymiarową. W przypadku selektorów, aplikacja pobiera pasujące elementy i wyświetla je jako listę slajdów w kolejności analogicznej z ich pozycją w drzewie DOM. W tej opcji dane potrzebne do wczytania modalu zostają umieszczone w atrybutach data poszczególnych elementów. Drugim sposobem na uruchomienie listy modali jest odpowiednie wypełnienie właściwości slider, umieszczając w niej dwuwymiarową tablicę. Dodatkowo poszczególny index tablicy powinien przechowywać informacje potrzebne do uruchomienia aplikacji. W dalszej części artykułu zostaną przedstawione przykłady użycia aplikacji z włączoną funkcją slidera:

Atrybuty data

Pierwszym sposobem na uruchomienie slidera jest przekazanie parametrów za pośrednictwem atrybutów data oraz stworzenie odpowiedniej instancji. Metoda przekazania danych przy użyciu atrybutów sprawdza się w przypadku kiedy dynamicznie dodajemy elementy do strony. Tworzenie kodu HTML wraz z atrybutami odbywa się w następujący sposób:

<div class="modal-demo-content">
  <button class="modal-slider-open modal-demo-button modal-slider" data-url="https://compsoul.pl/" data-element=".listing-article .listing-item:nth-child(2) .listing-content">Pierwszy slajd</button>
  <button class="modal-slider-open modal-demo-button modal-slider" data-url="https://compsoul.pl/" data-element=".listing-article .listing-item:nth-child(3) .listing-content">Drugi slajd</button>
  <button class="modal-slider-open modal-demo-button modal-slider" data-url="https://compsoul.pl/" data-element=".listing-article .listing-item:nth-child(4) .listing-content">Trzeci slajd</button>
  <button class="modal-slider-open modal-demo-button modal-slider" data-url="https://compsoul.pl/" data-element=".listing-article .listing-item:nth-child(5) .listing-content">Czwarty slajd</button>
  <button class="modal-slider-open modal-demo-button modal-slider" data-url="https://compsoul.pl/" data-element=".listing-article .listing-item:nth-child(6) .listing-content">Czwarty slajd</button>
</div>
.compsoul-modal-container {
  background: #000000BF;
  bottom: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
  position: fixed;
  right: 0;
  top: 0;
  transition: opacity 0.4s;
  will-change: opacity;
  z-index: 6;
}

.compsoul-modal-container.modal-active {
  opacity: 1;
  pointer-events: auto;
}

.compsoul-modal-container.modal-close {
  pointer-events: auto;
}

.modal-unset, .modal-unset:before, .modal-unset:after, .compsoul-modal-container.modal-unset, .compsoul-modal-main.modal-unset {
  animation: unset !important;
  transition: none !important;
}

.compsoul-modal-container:before {
  animation: compsoul-modal-loading 1s infinite;
  border-bottom: 0.5em solid #ffffff00;
  border-left: 0.5em solid #ffffff;
  border-right: 0.5em solid #ffffff;
  border-top: 0.5em solid #ffffff00;
  border-radius: 100%;
  box-sizing: content-box;
  content: "";
  font-size: 4px;
  height: 6em;
  left: 50%;
  opacity: 1;
  position: absolute;
  top: 50%;
  transform: translate3d(-50%, -50%, 0);
  transition: opacity 0.4s;
  will-change: opacity;
  width: 6em;
}

.compsoul-modal-container.modal-ready:before, .compsoul-modal-container.modal-error:before {
  animation-play-state: paused;
  opacity: 0;
}

@keyframes compsoul-modal-loading {
  from {
    transform: translate3d(-50%, -50%, 0) rotate(0deg);
  }

  to {
    transform: translate3d(-50%, -50%, 0) rotate(360deg);
  }
}

.compsoul-modal-container:after {
  color: #ffffff;
  content: "\26A0";
  font-size: 42px;
  font-weight: 200;
  left: 50%;
  margin: -6px 0 0 0;
  opacity: 0;
  position: absolute;
  top: 50%;
  transform: translate3d(-50%, -50%, 0);
  transition: opacity 0.4s;
  will-change: opacity;
}

.compsoul-modal-container.modal-error:after {
  opacity: 1;
}

.compsoul-modal-main {
  left: 50%;
  max-height: calc(2 * 40vh);
  opacity: 0;
  position: absolute;
  top: 50%;
  transform: translate3d(-50%, calc(-50% - 100px), 0);
  transition: transform 0.4s 0.4s, opacity 0.4s 0.4s;
  width: 800px;
  z-index: 1;
  will-change: transform, opacity;
}

.modal-ready.modal-active .compsoul-modal-main {
  opacity: 1;
  transform: translate3d(-50%, -50%, 0);
}

.modal-change .compsoul-modal-main {
  transition: transform 0.4s, opacity 0.4s;
}

.compsoul-modal-main:before {
  background: #fff;
  border-radius: 8px;
  bottom: -32px;
  box-shadow: 0 5px 26px 0 rgba(0, 0, 0, 0.22), 0 20px 28px 0 rgba(0, 0, 0, 0.30);
  content: "";
  left: -32px;
  position: absolute;
  right: -32px;
  top: -32px;
  z-index: -1;
}

.compsoul-modal-content {
  background: #fff;
  line-height: 1.2;
  overflow-y: auto;
  max-height: calc(2 * 40vh);
  padding: 0 32px 0 0;
  position: relative;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.compsoul-modal-content:after {
  content: "";
  display: table;
  clear: both;
}

.compsoul-modal-close {
  right: 8em;
  position: absolute;
  top: 8em;
  z-index: 2;
}

.compsoul-modal-next {
  right: 8em;
  position: absolute;
  top: 50%;
  transform: translate3d(0, -50%, 0);
  z-index: 2;
}

.compsoul-modal-prev {
  left: 8em;
  position: absolute;
  top: 50%;
  transform: translate3d(0, -50%, 0);
  z-index: 2;
}

.compsoul-modal-close, .compsoul-modal-next, .compsoul-modal-prev {
  background: #000000;
  border: none;
  cursor: default;
  font-size: 2.6px;
  height: 16em;
  opacity: 0;
  outline: 1px solid #e7a14f00;
  padding: 0;
  text-align: center;
  transition: opacity 0.4s, outline 0.4s;
  width: 16em;
}

.compsoul-modal-close:focus, .compsoul-modal-close:focus-within, .compsoul-modal-next:focus, .compsoul-modal-next:focus-within, .compsoul-modal-prev:focus, .compsoul-modal-prev:focus-within {
  outline: 1px solid #e7a14fff;
}

.compsoul-modal-close, .compsoul-modal-next.modal-active, .compsoul-modal-prev.modal-active {
  cursor: pointer;
  opacity: 1;
}

.compsoul-modal-close:before, .compsoul-modal-close:after, .compsoul-modal-next:before, .compsoul-modal-prev:before {
  border-top: 1em solid #ffffff;
  border-right: 1em solid #ffffff;
  box-sizing: content-box;
  content: "";
  cursor: pointer;
  display: inline-block;
  height: 4em;
  padding: 0 0 1em 1em;
  transform: rotate(45deg) translate3d(-25%, 25%, 0);
  transition: opacity 0.4s, border 0.4s;
  width: 4em;
}

.compsoul-modal-close:before, .compsoul-modal-close:after {
  height: 3em;
  width: 3em;
}

.compsoul-modal-close:hover:before, .compsoul-modal-close:hover:after, .compsoul-modal-next:hover:before, .compsoul-modal-prev:hover:before {
  border-top: 1em solid #e7a14f;
  border-right: 1em solid #e7a14f;
}

.compsoul-modal-close:after, .compsoul-modal-prev:before {
  transform: rotate(-135deg) translate3d(-25%, 25%, 0);
}

.compsoul-modal-close:before {
  transform: rotate(45deg) translate3d(-7%, 7%, 0);
}

.compsoul-modal-close:after {
  transform: rotate(-135deg) translate3d(-7%, 7%, 0);
}

.compsoul-modal-timer {
  height: 3px;
  left: 0;
  position: absolute;
  top: 0;
  z-index: 5;
  width: 100%;
}

.compsoul-modal-timer:before {
  animation: compsoul-slide-timeline 8s linear forwards;
  animation-play-state: paused;
  background: #e7a14f;
  content: "";
  display: block;
  height: 100%;
  transform: translate3d(-100%, 0, 0);
  width: 100%;
}

.modal-ready .compsoul-modal-timer:before {
  animation-play-state: running;
}

.compsoul-modal-container:hover .compsoul-modal-timer:before {
  animation-play-state: paused;
}

@keyframes compsoul-slide-timeline {
  from {
    transform: translate3d(-100%, 0, 0);
  }

  to {
    transform: translate3d(0, 0, 0);
  }
}

@media only screen and (max-width: 1060px) {
  .compsoul-modal-main {
    width: calc(100% - 94px);
  }

  .compsoul-modal-main:before {
    bottom: -12px;
    left: -12px;
    right: -12px;
    top: -12px;
  }

  .compsoul-modal-close, .compsoul-modal-next, .compsoul-modal-prev {
    font-size: 2px;
  }

  .compsoul-modal-close {
    right: 0;
    top: 0;
  }

  .compsoul-modal-next {
    right: 0;
  }

  .compsoul-modal-prev {
    left: 0;
  }
}

.modal-box {
  background: #fff;
  border-radius: 5px;
  box-shadow: 0 0 32px 0 rgba(0, 0, 0, 0.2);
  box-sizing: border-box;
  display: block;
  font-family: Calibri, Candara, Segoe, Segoe UI, Optima, Arial, sans-serif;
  height: 0;
  margin: 32px auto;
  overflow: hidden;
  transition: height 0.4s;
  width: 264px;
}

.modal-box.modal-active {
  height: 180px;
}

.modal-box-content {
  padding: 24px 32px;
}

.modal-box-open {
  margin: 21px auto;
}
<script src="https://compsoul.pl/uploads/js/compsoul.js"></script><script src="https://compsoul.pl/uploads/js/modal.js"></script><script>
  new Modal().options({
    slider: ".modal-slider",
    open: ".modal-slider-open"
  }).init();
</script>

Tablica

Kolejnym sposobem delegacji danych jest przekazanie tablicy dwuwymiarowej jako listy poszczególnych slajdów. W przypadku tej metody nie potrzebujemy zmian w kodzie HTML, a do poprawnego działania aplikacji wystarczy umieszczenie tablicy dwuwymiarowej jako wartości opcji slider. Przykład zastosowania metody znajduje się poniżej:

<div class="modal-demo-content">
  <button class="modal-slider-array modal-demo-button">Otwórz modal</button>
</div>
.compsoul-modal-container {
  background: #000000BF;
  bottom: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
  position: fixed;
  right: 0;
  top: 0;
  transition: opacity 0.4s;
  will-change: opacity;
  z-index: 6;
}

.compsoul-modal-container.modal-active {
  opacity: 1;
  pointer-events: auto;
}

.compsoul-modal-container.modal-close {
  pointer-events: auto;
}

.modal-unset, .modal-unset:before, .modal-unset:after, .compsoul-modal-container.modal-unset, .compsoul-modal-main.modal-unset {
  animation: unset !important;
  transition: none !important;
}

.compsoul-modal-container:before {
  animation: compsoul-modal-loading 1s infinite;
  border-bottom: 0.5em solid #ffffff00;
  border-left: 0.5em solid #ffffff;
  border-right: 0.5em solid #ffffff;
  border-top: 0.5em solid #ffffff00;
  border-radius: 100%;
  box-sizing: content-box;
  content: "";
  font-size: 4px;
  height: 6em;
  left: 50%;
  opacity: 1;
  position: absolute;
  top: 50%;
  transform: translate3d(-50%, -50%, 0);
  transition: opacity 0.4s;
  will-change: opacity;
  width: 6em;
}

.compsoul-modal-container.modal-ready:before, .compsoul-modal-container.modal-error:before {
  animation-play-state: paused;
  opacity: 0;
}

@keyframes compsoul-modal-loading {
  from {
    transform: translate3d(-50%, -50%, 0) rotate(0deg);
  }

  to {
    transform: translate3d(-50%, -50%, 0) rotate(360deg);
  }
}

.compsoul-modal-container:after {
  color: #ffffff;
  content: "\26A0";
  font-size: 42px;
  font-weight: 200;
  left: 50%;
  margin: -6px 0 0 0;
  opacity: 0;
  position: absolute;
  top: 50%;
  transform: translate3d(-50%, -50%, 0);
  transition: opacity 0.4s;
  will-change: opacity;
}

.compsoul-modal-container.modal-error:after {
  opacity: 1;
}

.compsoul-modal-main {
  left: 50%;
  max-height: calc(2 * 40vh);
  opacity: 0;
  position: absolute;
  top: 50%;
  transform: translate3d(-50%, calc(-50% - 100px), 0);
  transition: transform 0.4s 0.4s, opacity 0.4s 0.4s;
  width: 800px;
  z-index: 1;
  will-change: transform, opacity;
}

.modal-ready.modal-active .compsoul-modal-main {
  opacity: 1;
  transform: translate3d(-50%, -50%, 0);
}

.modal-change .compsoul-modal-main {
  transition: transform 0.4s, opacity 0.4s;
}

.compsoul-modal-main:before {
  background: #fff;
  border-radius: 8px;
  bottom: -32px;
  box-shadow: 0 5px 26px 0 rgba(0, 0, 0, 0.22), 0 20px 28px 0 rgba(0, 0, 0, 0.30);
  content: "";
  left: -32px;
  position: absolute;
  right: -32px;
  top: -32px;
  z-index: -1;
}

.compsoul-modal-content {
  background: #fff;
  line-height: 1.2;
  overflow-y: auto;
  max-height: calc(2 * 40vh);
  padding: 0 32px 0 0;
  position: relative;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.compsoul-modal-content:after {
  content: "";
  display: table;
  clear: both;
}

.compsoul-modal-close {
  right: 8em;
  position: absolute;
  top: 8em;
  z-index: 2;
}

.compsoul-modal-next {
  right: 8em;
  position: absolute;
  top: 50%;
  transform: translate3d(0, -50%, 0);
  z-index: 2;
}

.compsoul-modal-prev {
  left: 8em;
  position: absolute;
  top: 50%;
  transform: translate3d(0, -50%, 0);
  z-index: 2;
}

.compsoul-modal-close, .compsoul-modal-next, .compsoul-modal-prev {
  background: #000000;
  border: none;
  cursor: default;
  font-size: 2.6px;
  height: 16em;
  opacity: 0;
  outline: 1px solid #e7a14f00;
  padding: 0;
  text-align: center;
  transition: opacity 0.4s, outline 0.4s;
  width: 16em;
}

.compsoul-modal-close:focus, .compsoul-modal-close:focus-within, .compsoul-modal-next:focus, .compsoul-modal-next:focus-within, .compsoul-modal-prev:focus, .compsoul-modal-prev:focus-within {
  outline: 1px solid #e7a14fff;
}

.compsoul-modal-close, .compsoul-modal-next.modal-active, .compsoul-modal-prev.modal-active {
  cursor: pointer;
  opacity: 1;
}

.compsoul-modal-close:before, .compsoul-modal-close:after, .compsoul-modal-next:before, .compsoul-modal-prev:before {
  border-top: 1em solid #ffffff;
  border-right: 1em solid #ffffff;
  box-sizing: content-box;
  content: "";
  cursor: pointer;
  display: inline-block;
  height: 4em;
  padding: 0 0 1em 1em;
  transform: rotate(45deg) translate3d(-25%, 25%, 0);
  transition: opacity 0.4s, border 0.4s;
  width: 4em;
}

.compsoul-modal-close:before, .compsoul-modal-close:after {
  height: 3em;
  width: 3em;
}

.compsoul-modal-close:hover:before, .compsoul-modal-close:hover:after, .compsoul-modal-next:hover:before, .compsoul-modal-prev:hover:before {
  border-top: 1em solid #e7a14f;
  border-right: 1em solid #e7a14f;
}

.compsoul-modal-close:after, .compsoul-modal-prev:before {
  transform: rotate(-135deg) translate3d(-25%, 25%, 0);
}

.compsoul-modal-close:before {
  transform: rotate(45deg) translate3d(-7%, 7%, 0);
}

.compsoul-modal-close:after {
  transform: rotate(-135deg) translate3d(-7%, 7%, 0);
}

.compsoul-modal-timer {
  height: 3px;
  left: 0;
  position: absolute;
  top: 0;
  z-index: 5;
  width: 100%;
}

.compsoul-modal-timer:before {
  animation: compsoul-slide-timeline 8s linear forwards;
  animation-play-state: paused;
  background: #e7a14f;
  content: "";
  display: block;
  height: 100%;
  transform: translate3d(-100%, 0, 0);
  width: 100%;
}

.modal-ready .compsoul-modal-timer:before {
  animation-play-state: running;
}

.compsoul-modal-container:hover .compsoul-modal-timer:before {
  animation-play-state: paused;
}

@keyframes compsoul-slide-timeline {
  from {
    transform: translate3d(-100%, 0, 0);
  }

  to {
    transform: translate3d(0, 0, 0);
  }
}

@media only screen and (max-width: 1060px) {
  .compsoul-modal-main {
    width: calc(100% - 94px);
  }

  .compsoul-modal-main:before {
    bottom: -12px;
    left: -12px;
    right: -12px;
    top: -12px;
  }

  .compsoul-modal-close, .compsoul-modal-next, .compsoul-modal-prev {
    font-size: 2px;
  }

  .compsoul-modal-close {
    right: 0;
    top: 0;
  }

  .compsoul-modal-next {
    right: 0;
  }

  .compsoul-modal-prev {
    left: 0;
  }
}

.modal-box {
  background: #fff;
  border-radius: 5px;
  box-shadow: 0 0 32px 0 rgba(0, 0, 0, 0.2);
  box-sizing: border-box;
  display: block;
  font-family: Calibri, Candara, Segoe, Segoe UI, Optima, Arial, sans-serif;
  height: 0;
  margin: 32px auto;
  overflow: hidden;
  transition: height 0.4s;
  width: 264px;
}

.modal-box.modal-active {
  height: 180px;
}

.modal-box-content {
  padding: 24px 32px;
}

.modal-box-open {
  margin: 21px auto;
}
<script src="https://compsoul.pl/uploads/js/compsoul.js"></script><script src="https://compsoul.pl/uploads/js/modal.js"></script><script>
  new Modal("body").options({
    open: ".modal-slider-array", 
    slider: [
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(2) h2"],
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(3) h2"],
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(4) h2"],
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(5) h2"],
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(6) h2"]
          ]
  }).init();
</script>

Po kliknięciu w przycisk możemy zauważyć, że aplikacja wczytuje listę slajdów umieszczoną w tablicy. Ale co w sytuacji, kiedy będziemy chcieli wysłać komuś link do otwartego modalu? Z pomocą przychodzi nam funkcja hash. Zapraszam do kolejnej części artykułu:

Hash

Funkcja modalu została opisana w innym dziele o tej samej nazwie, więc skupmy się na wersji przeznaczonej dla opcji slidera. W celu uruchomienia aplikacji, po wpisaniu odpowiedniej zmiennej na pasku adresu, modal wymaga uzupełnienia wszystkich ustawień opcji slider. Dla zobrazowania działania aplikacji stwórzmy w pełni uzupełnioną instancje, korzystając z metody tablicy:

<script src="https://compsoul.pl/uploads/js/compsoul.js"></script><script src="https://compsoul.pl/uploads/js/modal.js"></script><script>
  new Modal("body").options({
    slider: [
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(2) h2", "h21"],
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(3) h2", "h22"],
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(4) h2", "h23"],
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(5) h2", "h24"],
             ["https://compsoul.pl/", ".listing-article .listing-item:nth-child(6) h2", "h25"]
          ]
  }).init();
</script>

Uruchomienie poszczególnego slajdu następuje poprzez dopisanie do paska adresu zmiennej występującej w tablicy. Przykładowo: aby uruchomić modal ze zmienną "h24" musimy dopisać do paska adresu odpowiedni hash: https://compsoul.pl/modal-popup-wyskakujace-okno-html-js-css/slider-karuzela-popup/#h24

Po uruchomieniu modalu jako pierwszy zostaje aktywowany slajd z numerem cztery. Modal nie pojawi się, jeżeli będziemy mieli aktywny inny modal np. akceptację plików cookies. Funkcjonalność slidera posiada szeroki wachlarz możliwości: od dynamicznego wczytywania listy produktów po zdalną galerię zdjęć. Przykładem użycia modułu jest lista produktów na tej stronie (Pamiętaj o zaakceptowaniu komunikatu o polityce prywatności).

Dziękuję za przeczytanie

Jeżeli spodobał Ci się mój wpis, zachęcam do obserwowania mojego profilu w serwisie facebook. Dodatkowo będzie mi bardzo miło jeżeli zechcesz podzielić się swoimi uwagami w komentarzach i zostawisz łapkę w górę. Jeżeli pilnie potrzebujesz pomocy lub chcesz o coś zapytać, skorzystaj z formularza kontaktowego lub napisz na daniel@compsoul.pl. Jeżeli Twoja sprawa jest naprawdę pilna, możesz zadzwonić na numer: +48 732 846 416