Bootstrap LightBox Gallery со многими альбомами - PullRequest
1 голос
/ 09 ноября 2019

Я хочу использовать этот код на своей веб-странице галереи, и проблема в том, что когда один слайд альбома закончен, он должен начинаться с первого изображения снова. А также, когда я пытаюсь открыть второй альбом, он не показывает слайды большую часть времени. Я думаю, что есть проблема с подсчетом каждого слайда и текущего слайда.

    <!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
  font-family: Verdana, sans-serif;
  margin: 0;
}

* {
  box-sizing: border-box;
}

.row > .column {
  padding: 0 8px;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}

.column {
  float: left;
  width: 25%;
}

/* The Modal (background) */
.modal {
  display: none;
  position: fixed;
  z-index: 1;
  padding-top: 100px;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: black;
}

/* Modal Content */
.modal-content {
  position: relative;
  background-color: #fefefe;
  margin: auto;
  padding: 0;
  width: 90%;
  max-width: 1200px;
}

/* The Close Button */
.close {
  color: white;
  position: absolute;
  top: 10px;
  right: 25px;
  font-size: 35px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: #999;
  text-decoration: none;
  cursor: pointer;
}

.mySlides {
  display: none;
}

.cursor {
  cursor: pointer;
}

/* Next & previous buttons */
.prev,
.next {
  cursor: pointer;
  position: absolute;
  top: 50%;
  width: auto;
  padding: 16px;
  margin-top: -50px;
  color: white;
  font-weight: bold;
  font-size: 20px;
  transition: 0.6s ease;
  border-radius: 0 3px 3px 0;
  user-select: none;
  -webkit-user-select: none;
}

/* Position the "next button" to the right */
.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
  background-color: rgba(0, 0, 0, 0.8);
}

/* Number text (1/3 etc) */
.numbertext {
  color: #f2f2f2;
  font-size: 12px;
  padding: 8px 12px;
  position: absolute;
  top: 0;
}

img {
  margin-bottom: -4px;
}

.caption-container {
  text-align: center;
  background-color: black;
  padding: 2px 16px;
  color: white;
}

.demo {
  opacity: 0.6;
}

.active,
.demo:hover {
  opacity: 1;
}

img.hover-shadow {
  transition: 0.3s;
}

.hover-shadow:hover {
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
</style>
<body>

<h2 style="text-align:center">Lightbox</h2>

<div class="row">
  <div class="column">
    <img src="https://www.gstatic.com/webp/gallery/1.jpg" style="width:100%" onclick="openModal_1()" class="hover-shadow cursor">
  </div>
  <div class="column">
    <img src="https://www.gstatic.com/webp/gallery/4.jpg" style="width:100%" onclick="openModal_2()" class="hover-shadow cursor">
  </div>
</div>

<div id="myModal_1" class="modal">
  <span class="close cursor" onclick="closeModal_1()">&times;</span>
  <div class="modal-content">

    <div class="mySlides">
      <div class="numbertext">1 / 3</div>
      <img src="https://www.gstatic.com/webp/gallery/1.jpg" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">2 / 3</div>
      <img src="https://www.gstatic.com/webp/gallery/2.jpg" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">3 / 3</div>
      <img src="https://www.gstatic.com/webp/gallery/3.jpg" style="width:100%">
    </div>

    <a class="prev" onclick="plusSlides(-1)">&#10094;</a>
    <a class="next" onclick="plusSlides(1)">&#10095;</a>

    <div class="caption-container">
      <p id="caption"></p>
    </div>
  </div>
</div>
<div id="myModal_2" class="modal">
  <span class="close cursor" onclick="closeModal_2()">&times;</span>
  <div class="modal-content">

    <div class="mySlides">
      <div class="numbertext">1 / 2</div>
      <img src="https://www.gstatic.com/webp/gallery/4.jpg" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">2 / 2</div>
      <img src="https://www.gstatic.com/webp/gallery/5.jpg" style="width:100%">
    </div>

    <a class="prev" onclick="plusSlides(-1)">&#10094;</a>
    <a class="next" onclick="plusSlides(1)">&#10095;</a>

    <div class="caption-container">
      <p id="caption"></p>
    </div>
  </div>
</div>
<script>
function openModal_1() {
  document.getElementById("myModal_1").style.display = "block";
}
function openModal_2() {
  document.getElementById("myModal_2").style.display = "block";
}

function closeModal_1() {
  document.getElementById("myModal_1").style.display = "none";
}
function closeModal_2() {
  document.getElementById("myModal_2").style.display = "none";
}

var slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
  showSlides(slideIndex += n);
}

function currentSlide(n) {
  showSlides(slideIndex = n);
}

function showSlides(n) {
  var i;
  var slides = document.getElementsByClassName("mySlides");
  var dots = document.getElementsByClassName("demo");
  var captionText = document.getElementById("caption");
  if (n > slides.length) {slideIndex = 1}
  if (n < 1) {slideIndex = slides.length}
  for (i = 0; i < slides.length; i++) {
      slides[i].style.display = "none";
  }
  for (i = 0; i < dots.length; i++) {
      dots[i].className = dots[i].className.replace(" active", "");
  }
  slides[slideIndex-1].style.display = "block";
}
</script>

</body>
</html>

здесь работает код

и здесь

1 Ответ

0 голосов
/ 09 ноября 2019

Вот пример того, чего вы хотите достичь, используя Bootstrap 4, который, хотя и не включен в ваш вопрос, использовался в качестве тега вопроса, поэтому я предполагаю, что вы используете его или, по крайней мере, хотитеиспользуйте его:

С вкладками:

/* added for SO example only, you probably don't need it */
.nav.nav-tabs {
  margin: 1rem 0;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

<div class="container">
  <ul class="nav nav-tabs" id="myTab" role="tablist">
    <li class="nav-item">
      <a class="nav-link active" id="slider-1-tab" data-toggle="tab" href="#slider-1" role="tab" aria-controls="slider-1" aria-selected="true">Slider 1</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" id="slider-2-tab" data-toggle="tab" href="#slider-2" role="tab" aria-controls="slider-2" aria-selected="false">Slider 2</a>
    </li>
  </ul>
  <div class="tab-content">
    <div class="tab-pane active" id="slider-1" role="tabpanel" aria-labelledby="slider-1-tab">
      <div id="carouselSlider-1" class="carousel slide" data-ride="carousel">
        <ol class="carousel-indicators">
          <li data-target="#carouselSlider-1" data-slide-to="0" class="active"></li>
          <li data-target="#carouselSlider-1" data-slide-to="1"></li>
          <li data-target="#carouselSlider-1" data-slide-to="2"></li>
        </ol>
        <div class="carousel-inner">
          <div class="carousel-item active">
            <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/1.jpg" alt="First slide">
          </div>
          <div class="carousel-item">
            <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/2.jpg" alt="Second slide">
          </div>
          <div class="carousel-item">
            <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/3.jpg" alt="Third slide">
          </div>
        </div>
        <a class="carousel-control-prev" href="#carouselSlider-1" role="button" data-slide="prev">
          <span class="carousel-control-prev-icon" aria-hidden="true"></span>
          <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#carouselSlider-1" role="button" data-slide="next">
          <span class="carousel-control-next-icon" aria-hidden="true"></span>
          <span class="sr-only">Next</span>
        </a>
      </div>
    </div>
    <div class="tab-pane" id="slider-2" role="tabpanel" aria-labelledby="slider-2-tab">
      <div id="carouselSlider-2" class="carousel slide" data-ride="carousel">
        <ol class="carousel-indicators">
          <li data-target="#carouselSlider-2" data-slide-to="0" class="active"></li>
          <li data-target="#carouselSlider-2" data-slide-to="1"></li>
        </ol>
        <div class="carousel-inner">
          <div class="carousel-item active">
            <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/4.jpg" alt="First slide">
          </div>
          <div class="carousel-item">
            <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/5.jpg" alt="Second slide">
          </div>
        </div>
        <a class="carousel-control-prev" href="#carouselSlider-2" role="button" data-slide="prev">
          <span class="carousel-control-prev-icon" aria-hidden="true"></span>
          <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#carouselSlider-2" role="button" data-slide="next">
          <span class="carousel-control-next-icon" aria-hidden="true"></span>
          <span class="sr-only">Next</span>
        </a>
      </div>
    </div>
  </div>
</div>

Правда, это можно сделать умнее. У вас может быть объект конфигурации, содержащий структуру вашей галереи, и функцию, которая выводит необходимую разметку из вашего объекта.

Общий пример с вкладками и config объектом:

Создает все вкладки + ползунки динамически, во время компиляции, с config:

$(function() {
  const galleryConfig = {
    sliders: [{
      id: 'slider-1',
      title: 'Slider 1',
      slides: [{
        src: 'https://www.gstatic.com/webp/gallery/1.jpg',
        alt: 'First slide'
      }, {
        src: 'https://www.gstatic.com/webp/gallery/2.jpg',
        alt: 'Second slide'
      }, {
        src: 'https://www.gstatic.com/webp/gallery/3.jpg',
        alt: 'Third slide'
      }]
    }, {
      id: 'slider-2',
      title: 'Slider 2',
      slides: [{
        src: 'https://www.gstatic.com/webp/gallery/4.jpg',
        alt: 'First slide'
      }, {
        src: 'https://www.gstatic.com/webp/gallery/5.jpg',
        alt: 'Second slide'
      }]
    }]
  };

  function generateSliders(config) {
    let navs = $('<ul />', {
      role: 'tablist',
      class: 'nav nav-tabs'
    });
    let tabs = $('<div />', {
      class: 'tab-content'
    })
    config.sliders.forEach((slider, index) => {
      let $li = $('<li />', {
        class: 'nav-item',
        html: $('<a />', {
          class: 'nav-link' + (index ? '' : ' active'),
          id: `slider-${index + 1}-tab`,
          'data-toggle': 'tab',
          href: `#slider-${index + 1}`,
          role: 'tab',
          'aria-controls': `#slider-${index + 1}`,
          'aria-selected': index ? 'false' : 'true',
          text: slider.title
        })
      });
      $li.appendTo(navs);
    });
    navs.appendTo($('#galleryContainer'));

    config.sliders.forEach((slider, index) => {
      let $tab = $('<div />', {
        class: 'tab-pane' + (index ? '' : ' active'),
        id: slider.id,
        role: 'tabpanel',
        'aria-labelledby': `${slider.id}-tab`,
        html: $('<div />', {
          class: 'carousel slide',
          'data-ride': 'carousel',
          id: `carouselSlider-${index + 1}`,
          html: $('<ol />', {
            class: 'carousel-indicators',
            html: slider.slides.map((s, i) => $('<li />', {
              'data-target': `#carouselSlider-${index + 1}`,
              'data-slide-to': `${i}`,
              class: i ? '' : 'active'
            })[0].outerHTML).join('')
          })[0].outerHTML
          + $('<div />', {
            class: 'carousel-inner',
            html: slider.slides.map((s, i) => $('<div />', {
              class: 'carousel-item' + (i ? '' : ' active'),
              html: $('<img />', {
                class: 'd-block w-100',
                src: s.src,
                alt: s.alt
              })
            })[0].outerHTML).join('')
          })[0].outerHTML
          + $('<a />', {
            class: 'carousel-control-prev',
            href: `#carouselSlider-${index + 1}`,
            role: 'button',
            'data-slide': 'prev',
            html: $('<span />', {
              class: 'carousel-control-prev-icon',
              'aria-hidden': 'true'
            })[0].outerHTML
            + $('<span />', {
              class: 'sr-only',
              text: 'Previous'
            })[0].outerHTML
          })[0].outerHTML
          + $('<a />', {
            class: 'carousel-control-next',
            href: `#carouselSlider-${index + 1}`,
            role: 'button',
            'data-slide': 'next',
            html: $('<span />', {
              class: 'carousel-control-next-icon',
              'aria-hidden': 'true'
            })[0].outerHTML
            + $('<span />', {
              class: 'sr-only',
              text: 'Next'
            })[0].outerHTML
          })[0].outerHTML
        })
      });
      $tab.appendTo(tabs)
    })
    tabs.appendTo($('#galleryContainer'));
  }

  generateSliders(galleryConfig);
})
/* added for SO example only, you probably don't need it */
.nav.nav-tabs {
  margin: 1rem 0;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

<div class="container">
  <div id="galleryContainer"></div>
</div>

Очевидно, ваш объект конфигурации может быть загружен из внешнего источника. Это просто доказательство концепции. generateSliders() выполняет все ползунки в объекте config и выводит необходимую разметку Bootstrap 4, так что вам не нужно этого делать, тем более что атрибут aria легко пропустить и, IMHO, сделать это вручную следуетпо возможности избегать.


При модальных значениях:

.modal-launchers img {
  width: 100px;
  height: auto;
  display: inline-block;
  margin-right: 1rem;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

<div class="container">
  <div class="row">
    <div class="col modal-launchers">
      <a id="modal-link-1" href="#modal-1" data-toggle="modal" data-target="#modal-1">
        <img src="https://www.gstatic.com/webp/gallery/1.jpg" alt="First slider">
      </a>
      <a id="modal-link-2" href="#modal-2" data-toggle="modal" data-target="#modal-2">
        <img src="https://www.gstatic.com/webp/gallery/4.jpg" alt="Second slider"></a>
    </div>
  </div>
</div>
<div class="modal fade" id="modal-1" tabindex="-1" role="dialog" aria-labelledby="modal-link-1" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">First gallery</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div id="carouselSlider-1" class="carousel slide" data-ride="carousel">
          <ol class="carousel-indicators">
            <li data-target="#carouselSlider-1" data-slide-to="0" class="active"></li>
            <li data-target="#carouselSlider-1" data-slide-to="1"></li>
            <li data-target="#carouselSlider-1" data-slide-to="2"></li>
          </ol>
          <div class="carousel-inner">
            <div class="carousel-item active">
              <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/1.jpg" alt="First slide">
            </div>
            <div class="carousel-item">
              <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/2.jpg" alt="Second slide">
            </div>
            <div class="carousel-item">
              <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/3.jpg" alt="Third slide">
            </div>
          </div>
          <a class="carousel-control-prev" href="#carouselSlider-1" role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
          </a>
          <a class="carousel-control-next" href="#carouselSlider-1" role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
          </a>
        </div>
      </div>
    </div>
  </div>
</div>
<div class="modal fade" id="modal-2" tabindex="-1" role="dialog" aria-labelledby="modal-link-2" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Second gallery</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div id="carouselSlider-2" class="carousel slide" data-ride="carousel">
          <ol class="carousel-indicators">
            <li data-target="#carouselSlider-2" data-slide-to="0" class="active"></li>
            <li data-target="#carouselSlider-2" data-slide-to="1"></li>
          </ol>
          <div class="carousel-inner">
            <div class="carousel-item active">
              <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/4.jpg" alt="First slide">
            </div>
            <div class="carousel-item">
              <img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/5.jpg" alt="Second slide">
            </div>
          </div>
          <a class="carousel-control-prev" href="#carouselSlider-2" role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
          </a>
          <a class="carousel-control-next" href="#carouselSlider-2" role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
          </a>
        </div>
      </div>
    </div>
  </div>
</div>

Опять же, просто пример. Все, что вам нужно сделать, это перейти к документации Bootstrap, взять разметку из примера и применить ее к своему коду.


Общий пример с модалами и config object:

Создает все модалы + ползунки динамически, во время компиляции, от config:

$(function() {
  const galleryConfig = {
    sliders: [{
      id: 'slider-1',
      title: 'Slider 1',
      slides: [{
        src: 'https://picsum.photos/id/230/800/600',
        alt: 'First slide'
      }, {
        src: 'https://picsum.photos/id/231/800/600',
        alt: 'Second slide'
      }, {
        src: 'https://picsum.photos/id/232/800/600',
        alt: 'Third slide'
      }]
    }, {
      id: 'slider-2',
      title: 'Slider 2',
      slides: [{
        src: 'https://picsum.photos/id/233/800/600',
        alt: 'First slide'
      }, {
        src: 'https://picsum.photos/id/234/800/600',
        alt: 'Second slide'
      }, {
        src: 'https://picsum.photos/id/235/800/600',
        alt: 'Third slide'
      }, {
        src: 'https://picsum.photos/id/236/800/600',
        alt: 'Fourth slide'
      }, {
        src: 'https://picsum.photos/id/237/800/600',
        alt: 'Fifth slide'
      }]
    }]
  };

  function generateModals(config) {
    let navs = $('#galleryContainer');
    config.sliders.forEach((slider, i) => {
      let $launcher = $('<a />', {
        id: `modal-link-${i}`,
        href: `#gallery-modal-${i}`,
        'data-target': `#gallery-modal-${i}`,
        'data-toggle': 'modal',
        title: slider.title,
        html: slider.slides.map(image => $('<img />', {
          src: image.src,
          alt: image.title
        })).map(o => o[0].outerHTML).join('')
      });
      $launcher.appendTo(navs);
    });
    navs.appendTo($('#galleryContainer'));

    config.sliders.forEach((slider, i) => {
      let $modalDiv = $('<div />', {
        class: 'modal fade',
        id: `gallery-modal-${i}`,
        role: 'dialog',
        'aria-labelledby': `modal-link-${i}`,
        'aria-hidden': 'true',
        html: $('<div />', {
          class: 'modal-dialog modal-lg',
          role: 'document',
          html: $('<div />', {
            class: 'modal-content',
            html: $('<div />', {
                class: 'modal-header',
                html: $('<h5 />', {
                    class: 'modal-title',
                    text: slider.title
                  })[0].outerHTML +
                  $('<button />', {
                    type: 'button',
                    class: 'close',
                    'data-dismiss': 'modal',
                    'aria-label': 'Close',
                    html: $('<span />', {
                      'aria-hidden': 'true',
                      html: '&times;'
                    })
                  })[0].outerHTML
              })[0].outerHTML +
              $('<div />', {
                class: 'modal-body',
                html: $('<div />', {
                  class: 'carousel slide',
                  'data-ride': 'carousel',
                  id: `carouselSlider-${i}`,
                  html: $('<ol />', {
                      class: 'carousel-indicators',
                      html: slider.slides.map((o, k) => $('<li />', {
                        'data-target': `#carouselSlider-${i}`,
                        'data-slide-to': `${k}`,
                        class: k ? '' : 'active'
                      })[0].outerHTML).join('')
                    })[0].outerHTML +
                    $('<div />', {
                      class: 'carousel-inner',
                      html: slider.slides.map((o, k) => $('<div />', {
                        class: 'carousel-item' + (k ? '' : ' active'),
                        html: $('<img />', {
                          class: 'd-block w-100',
                          src: o.src,
                          alt: o.alt
                        })
                      })[0].outerHTML).join('')
                    })[0].outerHTML +
                    $('<a />', {
                      class: 'carousel-control-prev',
                      href: `#carouselSlider-${i}`,
                      role: 'button',
                      'data-slide': 'prev',
                      html: $('<span />', {
                          class: 'carousel-control-prev-icon',
                          'aria-hidden': 'true'
                        })[0].outerHTML +
                        $('<span />', {
                          class: 'sr-only',
                          text: 'Previous'
                        })[0].outerHTML
                    })[0].outerHTML +
                    $('<a />', {
                      class: 'carousel-control-next',
                      href: `#carouselSlider-${i}`,
                      role: 'button',
                      'data-slide': 'next',
                      html: $('<span />', {
                          class: 'carousel-control-next-icon',
                          'aria-hidden': 'true'
                        })[0].outerHTML +
                        $('<span />', {
                          class: 'sr-only',
                          text: 'Next'
                        })[0].outerHTML
                    })[0].outerHTML
                })
              })[0].outerHTML
          })
        })
      });
      $modalDiv.appendTo($('body'))
    })
  }

  generateModals(galleryConfig);
})
#galleryContainer img {
  height: 72px;
  width: auto;
  display: block;
  margin: 0 1px 1px 0;
}
#galleryContainer a {
  margin: 0 0 -1px;
  padding: .5rem;
  display: flex;
  flex-wrap: wrap; 
  align-items: center;
  justify-content: center;
  transition: background-color .3s ease-out;
  background-color:transparent;
}
#galleryContainer a:hover {
  background-color: #f5f5f5;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

<div class="container">
  <div class="row">
    <div class="col">
      <div id="galleryContainer"></div>
    </div>
  </div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...