PhotoSwipe: отредактировать функцию parseThumbnailElements для анализа дополнительного элемента разметки

С помощью PhotoSwipe разметка галереи миниатюр выглядит следующим образом:

    <div class="wrap clearfix">
    <div class="my-gallery" itemscope itemtype="http://schema.org/ImageGallery">
    <ul class="gallery-grid">
        <li>
            <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
                <a href="img/dektop/1.jpg" itemprop="contentUrl" data-size="1200x1200">
                    <img src="img/thumb/1.jpg" itemprop="thumbnail" alt="Image description" />
                </a>
                    <figcaption itemprop="caption description">Image caption 1</figcaption>
            </figure>
        </li>
        <li>
            <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
                <a href="img/dektop/2.jpg" itemprop="contentUrl" data-size="1200x1200">
                    <img src="img/thumb/2.jpg" itemprop="thumbnail" alt="Image description" />
                </a>
                    <figcaption itemprop="caption description">Image caption 2</figcaption>
            </figure>
        </li>
    </ul>
</div> <!-- mygallery -->
</div> <!-- wrap -->

Функция для анализа изображений:

var parseThumbnailElements = function(el) {
    var thumbElements = el.childNodes,
        numNodes = thumbElements.length,
        items = [],
        figureEl,
        linkEl,
        size,
        item;

    for(var i = 0; i < numNodes; i++) {

        figureEl = thumbElements[i]; // <figure> element

        // include only element nodes 
        if(figureEl.nodeType !== 1) {
            continue;
        }

        linkEl = figureEl.children[0]; // <a> element

        size = linkEl.getAttribute('data-size').split('x');

        // create slide object
        item = {
            src: linkEl.getAttribute('href'),
            w: parseInt(size[0], 10),
            h: parseInt(size[1], 10)
        };



        if(figureEl.children.length > 1) {
            // <figcaption> content
            item.title = figureEl.children[1].innerHTML; 
        }

        if(linkEl.children.length > 0) {
            // <img> thumbnail element, retrieving thumbnail url
            item.msrc = linkEl.children[0].getAttribute('src');
        } 

        item.el = figureEl; // save link to element for getThumbBoundsFn
        items.push(item);
    }

    return items;
};

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

Как включить элементы галереи-сетки и li в функцию, чтобы она просматривала эти элементы для фигуры и детей.

Совершенно новый для чистого JS, любые намеки или дальнейшее чтение очень приветствуются. К сожалению, с этим я не имею понятия, где даже начать искать.

http://quirksmode.org/dom/core/#gettingelements https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName

Ответ 1

Мне удалось оставить исходную разметку на месте и изменить CSS для галереи миниатюр. Теперь он работает и выглядит следующим образом:

<div class="wrap clearfix">
    <div class="my-gallery gallery-grid" itemscope itemtype="http://schema.org/ImageGallery">
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
            <a href="img/dektop/1.jpg" itemprop="contentUrl" data-size="1200x1200">
                <img src="img/thumb/1.jpg" itemprop="thumbnail" alt="Image description" />
            </a>
                <figcaption itemprop="caption description">Image caption 4</figcaption>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
            <a href="img/dektop/2.jpg" itemprop="contentUrl" data-size="1200x1200">
                <img src="img/thumb/2.jpg" itemprop="thumbnail" alt="Image description" />
            </a>
                <figcaption itemprop="caption description">Image caption 4</figcaption>
        </figure>
    </div> <!-- mygallery -->
</div> <!-- wrap -->

И CSS для сетки эскизов:

/* thumnail gallery grid */
.gallery-grid {
    margin: 35px 0 0 0;
    padding: 0;
    list-style: none;
    position: relative;
    width: 100%;
}

.gallery-grid figure {
    position: relative;
    float: left;
    overflow: hidden;
    width: 16.6666667%; /* Fallback */
    width: -webkit-calc(100% / 6);
    width: calc(100% / 6);
    height: 300px; /* pay attention to this later */
}

.gallery-grid figure a,
.gallery-grid figure a img {
    display: block;
    width: 100%;
    height: auto;
    cursor: pointer;
}

.gallery-grid figure a img {
    width: 100%;
    height: auto;    
}



@media screen and (max-width: 1190px) {
    .gallery-grid figure {
        width: 20%; /* Fallback */
        width: -webkit-calc(100% / 5);
        width: calc(100% / 5);
    }
}

@media screen and (max-width: 945px) {
    .gallery-grid figure {
        width: 25%; /* Fallback */
        width: -webkit-calc(100% / 4);
        width: calc(100% / 4);
    }
}

@media screen and (max-width: 660px) {
    .gallery-grid figure {
        width: 33.3333333%; /* Fallback */
        width: -webkit-calc(100% / 3);
        width: calc(100% / 3);
    }
}

@media screen and (max-width: 660px) {
    .gallery-grid figure {
        width: 33.3333333%; /* Fallback */
        width: -webkit-calc(100% / 3);
        width: calc(100% / 3);
    }
}

@media screen and (max-width: 400px) {
    .gallery-grid figure {
        width: 50%; /* Fallback */
        width: -webkit-calc(100% / 2);
        width: calc(100% / 2);
    }
}

@media screen and (max-width: 300px) {
    .gallery-grid figure {
        width: 100%;
    }
}

Однако на самом деле это не ответ, а обходной путь для первоначальной разметки. Мне все равно очень хотелось бы узнать, как изменить JS для работы с разметкой из моего вопроса.

Я использую пример отсюда: http://photoswipe.com/documentation/getting-started.html Внизу находится CodePen.

Ответ 2

Старый вопрос, и у нас была небольшая разная разметка, но если кто-то пытается понять это как я, это может сработать так, как со мной: https://github.com/akizor/PhotoSwipe-Gallery-Improvement

Все, что вам нужно сделать, это включить библиотеку Photoswipe, добавить тег HTML, который действует как контейнер для всех ваших изображений галереи и использовать этот javascript на вашей странице.

Я использовал div с классом .images-container в качестве контейнера.

var initPhotoSwipeFromDOM = function(gallerySelector) {
              var parseThumbnailElements = function(el) {
                var all = document.querySelectorAll(gallerySelector);
                var items = [];
                for(var j = 0 ; j < all.length; j++){
                  var el = all[j];
                  var thumbElements = el.parentNode.childNodes;
                  var numNodes = thumbElements.length,
                    figureEl,
                    linkEl,
                    size,
                    item;
                  for(var i = 0; i < numNodes; i++) {
                    figureEl = thumbElements[i];

                    if(figureEl.nodeType !== 1) {
                        continue;
                    }
                    linkEl = figureEl.children[0];
                    size = linkEl.getAttribute('data-size').split('x');
                    item = {
                        src: linkEl.getAttribute('href'),
                        w: parseInt(size[0], 10),
                        h: parseInt(size[1], 10),
                        minZoom: 3
                    };
                    if(figureEl.children.length > 1) {
                        item.title = figureEl.children[1].innerHTML;
                    }
                    if(linkEl.children.length > 0) {
                        item.msrc = linkEl.children[0].getAttribute('src');
                    }

                    item.el = figureEl;
                    items.push(item);
                  }
                }
                return items;
              };
              var closest = function closest(el, fn) {
                return el && ( fn(el) ? el : closest(el.parentNode, fn) );
              };
              var onThumbnailsClick = function(e) {
                e = e || window.event;
                e.preventDefault ? e.preventDefault() : e.returnValue = false;
                var eTarget = e.target || e.srcElement;
                var clickedListItem = closest(eTarget, function(el) {
                  return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
                });
                if(!clickedListItem) {
                  return;
                }
                var clickedGallery = clickedListItem.parentNode,
                  childNodes = document.querySelectorAll(gallerySelector),
                  numChildNodes = childNodes.length,
                  nodeIndex = 0,
                  index;
                for (var i = 0; i < numChildNodes; i++) {
                  if(childNodes[i].nodeType !== 1) {
                    continue;
                  }
                  if(childNodes[i] === clickedListItem) {
                    index = nodeIndex;
                    break;
                  }
                  nodeIndex++;
                }
                if(index >= 0) {
                  openPhotoSwipe( index, clickedGallery );
                }
                return false;
              };
              var photoswipeParseHash = function() {
                var hash = window.location.hash.substring(1),
                params = {};
                if(hash.length < 5) {
                  return params;
                }
                var vars = hash.split('&');
                for (var i = 0; i < vars.length; i++) {
                  if(!vars[i]) {
                    continue;
                  }
                  var pair = vars[i].split('=');
                  if(pair.length < 2) {
                    continue;
                  }
                  params[pair[0]] = pair[1];
                }
                if(params.gid) {
                  params.gid = parseInt(params.gid, 10);
                }
                return params;
              };

              var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) {
                var pswpElement = document.querySelectorAll('.pswp')[0],
                  gallery,
                  options,
                  items;
                items = parseThumbnailElements(galleryElement);
                options = {
                  maxSpreadZoom: 5,
                  galleryUID: galleryElement.getAttribute('data-pswp-uid'),
                  getThumbBoundsFn: function(index) {
                    var thumbnail = items[index].el.getElementsByTagName('img')[0],
                      pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
                      rect = thumbnail.getBoundingClientRect();
                    return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
                  },
                  minZoom: 3
                };
                if(fromURL) {
                  if(options.galleryPIDs) {
                    for(var j = 0; j < items.length; j++) {
                      if(items[j].pid == index) {
                        options.index = j;
                        break;
                      }
                    }
                  } else {
                    options.index = parseInt(index, 10) - 1;
                  }
                } else {
                  options.index = parseInt(index, 10);
                }
                if( isNaN(options.index) ) {
                  return;
                }
                if(disableAnimation) {
                  options.showAnimationDuration = 0;
                }
                gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
                return gallery.init();
              };
              var galleryElements = document.querySelectorAll( gallerySelector );
              for(var i = 0, l = galleryElements.length; i < l; i++) {
                galleryElements[i].setAttribute('data-pswp-uid', i+1);
                galleryElements[i].onclick = onThumbnailsClick;
              }
              var hashData = photoswipeParseHash();
              if(hashData.pid && hashData.gid) {
                openPhotoSwipe( hashData.pid ,  galleryElements[ hashData.gid - 1 ], true, true );
              }
            };

            // execute above function
            initPhotoSwipeFromDOM('.images-container figure');