Search code examples
javascriptjquerymagnific-popup

Display Title and Caption for Magnific Popup


please check out the example below (fullscreen view recommended). We have a Slider with a title, image and sometimes even a caption. I managed to get the title and caption from the attributes and put it in the titleSrc of Magnific Popup.

I don't need the title and caption in the titleSrc, but I want the same markup as in the slider => Title (h3), Image (img) and Caption (p) under each other.

Unfortunately, Magnific Popup does not provide a title and caption element. Can anybody think of a way to achieve this?

Thanks in advance, Marc

$(".slider__wrapper").each(function() {
  let $slider_wrapper = $(this);
  let $slider = $slider_wrapper.find(".slider");
  let $slider_items = $slider.find(".slider__items");
  var options = {
    adaptiveHeight: true,
    infinite: true
  }

  $slider_items.slick(options);

  $slider_items.magnificPopup({
    delegate: ":not(.slick-cloned) a",
    type: "image",
    gallery: {
      enabled: true,
      tCounter: ""
    },
    image: {
      titleSrc: function(item) {
        var markup = '';
        if (item.el[0].hasAttribute("title")) {
          markup += '<h3>' + item.el.attr('title') + '</h3>';
        }

        if (item.el[0].hasAttribute("caption")) {
          markup += '<p>' + item.el.attr('caption') + '</p>';
        }
        return markup
      }
    },
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.js"></script>


<div class="slider__wrapper">
  <div class="slider__wrapper__item">
    <div class="slider">
      <div class="slider__items">
        <div class="slider__item">
          <h3>Title 1</h3>
          <a href='https://placeimg.com/640/480/nature' title="Title 1" caption='Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum' class="slider__item__image">

            <img src="https://placeimg.com/640/480/nature">
          </a>
          <p> Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum</p>
        </div>
        <div class="slider__item">
          <h3>Title 2</h3>
          <a href='https://placeimg.com/640/480/people' title="Title 2" class="slider__item__image">

            <img src='https://placeimg.com/640/480/people'></a>
        </div>
      </div>
    </div>
  </div>
</div>
</div>


Solution

  • If you just don't want anything appears when hovering the image,then how about using data-attribute instead of title and caption?

    $(".slider__wrapper").each(function() {
      let $slider_wrapper = $(this);
      let $slider = $slider_wrapper.find(".slider");
      let $slider_items = $slider.find(".slider__items");
      var options = {
        adaptiveHeight: true,
        infinite: true
      }
    
      $slider_items.slick(options);
    
      $slider_items.magnificPopup({
        delegate: ":not(.slick-cloned) a",
        type: "image",
        gallery: {
          enabled: true,
          tCounter: ""
        },
        image: {
          titleSrc: function(item) {
            var markup = '';
            if (item.el[0].hasAttribute("data-title")) {
              markup += '<h3>' + item.el.attr('data-title') + '</h3>';
            }
    
            if (item.el[0].hasAttribute("data-caption")) {
              markup += '<p>' + item.el.attr('data-caption') + '</p>';
            }
            return markup
          }
        },
      });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.js"></script>
    
    
    <div class="slider__wrapper">
      <div class="slider__wrapper__item">
        <div class="slider">
          <div class="slider__items">
            <div class="slider__item">
              <h3>Title 1</h3>
              <a href='https://placeimg.com/640/480/nature' data-title="Title 1" data-caption='Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum' class="slider__item__image">
    
                <img src="https://placeimg.com/640/480/nature">
              </a>
              <p> Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum</p>
            </div>
            <div class="slider__item">
              <h3>Title 2</h3>
              <a href='https://placeimg.com/640/480/people' data-title="Title 2" class="slider__item__image">
    
                <img src='https://placeimg.com/640/480/people'></a>
            </div>
          </div>
        </div>
      </div>
    </div>
    </div>

    Or...you really need those attribute removed, then just using an array to storage all images information and change the titleSrc function.

    var picInfo = [{
        title: 'Title 1',
        caption: 'Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum'
      },
      {
        title: 'Title 2',
        caption: 'Foo?'
      },
      {
        title: 'Title 3',
        caption: 'Bar!'
      }
    ]
    
    $(".slider__wrapper").each(function() {
      let $slider_wrapper = $(this);
      let $slider = $slider_wrapper.find(".slider");
      let $slider_items = $slider.find(".slider__items");
      var options = {
        adaptiveHeight: true,
        infinite: true
      }
    
      $slider_items.slick(options);
    
      $slider_items.magnificPopup({
        delegate: ":not(.slick-cloned) a",
        type: "image",
        gallery: {
          enabled: true,
          tCounter: ""
        },
        image: {
          titleSrc: function(item) {
            var index = $(item.el[0]).index('.slider__item__image') - 1
            index = index == -1 ? index + picInfo.length : index
            index %= picInfo.length;
            var top = $('figure').height()
            var title = '<h3 id="pic_title" style="display:none">' + picInfo[index].title + '</h3>';
            var caption = '<p>' + picInfo[index].caption + '</p>';
            var markup = title + caption;
            return markup;
          },
        },
        callbacks: {
          updateStatus: function(data) {
            SetTitleTop(data)
          },
          resize: function(data) {
            SetTitleTop(data)
          },
        }
      });
    });
    
    function SetTitleTop(data) {
      if (data) {
        if (data.status == "ready") {
          var top = $('.mfp-img').height()
          if (top) {
            $('#pic_title').css({
              top: -top - 50,
              position: "absolute",
              display: "block"
            })
          }
        }
      }
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.js"></script>
    
    
    <div class="slider__wrapper">
      <div class="slider__wrapper__item">
        <div class="slider">
          <div class="slider__items">
            <div class="slider__item">
              <h3>Title 1</h3>
              <a href='https://placeimg.com/640/480/nature' class="slider__item__image">
    
                <img src="https://placeimg.com/640/480/nature">
              </a>
              <p> Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum</p>
            </div>
            <div class="slider__item">
              <h3>Title 2</h3>
              <a href='https://placeimg.com/640/480/people' class="slider__item__image">
    
                <img src='https://placeimg.com/640/480/people'></a>
            </div>
            <div class="slider__item">
              <h3>Title 3</h3>
              <a href='https://placeimg.com/640/480/any' class="slider__item__image">
    
                <img src='https://placeimg.com/640/480/any'></a>
            </div>
          </div>
        </div>
      </div>
    </div>
    </div>

    As per comment, I add two callback to adjust the title's position. See more API