PhotoSwipe:编辑parseThumbnailElements函数来解析其他标记元素

时间:2015-11-04 16:19:06

标签: javascript html arrays html-parsing photoswipe

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

我在my-gallery和figure类之间有两个额外的元素。删除那些东西是完美的,但是使用额外的两个类我不能选择上一个或下一个项目,这意味着数组已经坏了。

如何在函数中包含gallery-grid和li元素,以便查看图形和子元素的元素。

纯粹JS的新手,任何提示或进一步阅读都非常受欢迎。不幸的是,我不知道哪里可以开始寻找。

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

2 个答案:

答案 0 :(得分:3)

我通过保留原始标记来管理并更改缩略图库的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

答案 1 :(得分:1)

老问题,我们有一些不同的标记,但如果有人试图像我一样想出这个,这可能会像对待我一样: 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');