PhotoSwipe: edit parseThumbnailElements function to parse additional markup element

被刻印的时光 ゝ 提交于 2019-12-19 05:16:32

问题


Using PhotoSwipe the thumbnail gallery markup looks like this:

    <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 -->

The function to parse the images is:

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;
};

I have two additional elements between the my-gallery and the figure class. Removing those things work perfect, however with the additional two classes I cannot select the previous or next item, meaning the array is broken.

How can I include the gallery-grid and li elements in the function so that is looks past those elements for figure and children.

Totally new to pure JS, any hints or further reading very welcome. Unfortunately with this one I have no clue where to even start looking.

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


回答1:


I managed by leaving the original markup in place and change the CSS for the thumbnail gallery. It now works and looks like this:

<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 -->

And the CSS for the the thumbnail grid:

/* 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%;
    }
}

However this is not really an answer but a workaround to accommodate for the original markup. I would still very much love to find out about how to change the JS to work with the markup from my question.

I am using the example from here: http://photoswipe.com/documentation/getting-started.html At the bottom there is a CodePen.




回答2:


Old question and we had little bit different markup, but if somebody is trying to figure this out like me this might work as it did to me: https://github.com/akizor/PhotoSwipe-Gallery-Improvement

All you need to do is include Photoswipe library, add a HTML tag that acts as a container for all your gallery images and use this javascript in your page.

I used div with a class .images-container as a 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');


来源:https://stackoverflow.com/questions/33526838/photoswipe-edit-parsethumbnailelements-function-to-parse-additional-markup-elem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!