PhotoSwipe:编辑 parseThumbnailElements 函数以解析附加标记元素

Posted

技术标签:

【中文标题】PhotoSwipe:编辑 parseThumbnailElements 函数以解析附加标记元素【英文标题】:PhotoSwipe: edit parseThumbnailElements function to parse additional markup element 【发布时间】:2016-02-05 05:48:02 【问题描述】:

使用 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"  />
                </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"  />
                </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

【问题讨论】:

【参考方案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"  />
            </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"  />
            </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

我使用带有类 .images-container 的 div 作为容器。

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');

【讨论】:

以上是关于PhotoSwipe:编辑 parseThumbnailElements 函数以解析附加标记元素的主要内容,如果未能解决你的问题,请参考以下文章

photoswipe 实现图片的单击放大

移动端图片放大滑动查看-插件photoswipe的使用

jQuery Mobile 1.4.2 + Photoswipe 1.0.11

将 PhotoSwipe 配置为不使用整个窗口?

html photoswipe

html PhotoSwipe - 结构