【问题标题】:PhotoSwipe: closing gallery animates wrong rectangle (thumbnail)PhotoSwipe:关闭画廊动画错误的矩形(缩略图)
【发布时间】:2016-04-27 19:55:21
【问题描述】:

我是 Javascript 新手,在实现 PhotoSwipe 插件时遇到问题:

我正在尝试使用 jQuery 为网页实现 PhotoSwipe 插件。其中大部分工作正常(打开画廊,浏览幻灯片)。当我关闭画廊时会出现问题。问题:

我单击图像 1,这将打开 PhotoSwipe 灯箱,然后导航到幻灯片 2,然后关闭图库。这将关闭图库。但是为图像 1 播放关闭动画,而我希望为图像 2 播放它。

它在 PhotoSwipe 演示页面上正常工作,所以这是我的代码中的错误。如果我复制/粘贴演示页面 Javascript 代码,它可以正常工作。

我相信我缺少一些将当前显示的幻灯片与相应缩略图绑定的代码。我对演示页面的主要问题是:我很难理解 vanilla JS 演示,什么部分负责什么动作。 请帮我找到缺少的功能。

这是我的 PhotoSwipe“点击开始图库”事件的代码:

$('.my-gallery').each( function() {
    var $pic     = $(this);
    var items = itemArray;

    var $pswp = $('.pswp')[0];
    $pic.on('click', 'figure', function(event) {
        event.preventDefault();

        var $index = $(this).index();
        var options = {
            index: $index,
            getThumbBoundsFn: function(index) {
                // get element we clicked on to determine its position in window
                var thumbnail = event.target;
                // get position of element relative to viewport
                var rect = thumbnail.getBoundingClientRect();
                // get window scroll Y
                var pageYScroll = window.pageYOffset ||
                    document.documentElement.scrollTop; 
                return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
            }
        }
        // Initialize PhotoSwipe
        var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options);
        lightBox.init();
    });
});

我的画廊(精简到 2 张幻灯片):

<div class="row my-gallery" itemscope itemtype="http://schema.org/ImageGallery" id="img-gallery">
    <figure itemprop="associatedMedia" itemscope="" itemtype="http://schema.org/ImageObject">
        <a href="images/nature/DSC_7216.jpg" itemprop="contentUrl" data-size="1200x795">
            <img src="images/nature/DSC_7216_t.jpg" itemprop="thumbnail">
        </a>
    </figure>
    <figure itemprop="associatedMedia" itemscope="" itemtype="http://schema.org/ImageObject">
        <a href="images/nature/DSC_7218.jpg" itemprop="contentUrl" data-size="1200x795">
            <img src="images/nature/DSC_7218_t.jpg" itemprop="thumbnail">
        </a>
    </figure>
</div>

项目数组是从 JSON 生成的:

[
    {
        "src": "images/nature/DSC_7216.jpg",
        "msrc": "images/nature/DSC_7216_t.jpg",
        "w":1200,
        "h":795
    },
    {
        "src": "images/nature/DSC_7218.jpg",
        "msrc": "images/nature/DSC_7218_t.jpg",
        "w":1200,
        "h":795
    }
]

JSON 被硬编码为 p 元素,使用 jQuery 解析器解析:

var itemArray = jQuery.parseJSON($(imageListSelector).html());

您可以找到full page with problem on GitHub

PhotoSwipe demo on Codepen

你能帮我找到我缺少的东西吗?

编辑: 我已将问题追溯到原始 PhotoSwipe 演示中的这部分代码:

var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail

如果我用固定的缩略图选择器替换这部分(就像我在我的 jQuery 中的那样 - 它包含“事件目标”引用),我可以强制 PhotoSwipe 演示重复我的行为 - 缩小在同一张图像上执行。在我的情况下发生的事情并不完全相同,但足够接近。

现在我只需要弄清楚如何更改我的 getThumbBoundsFn 以使用实际的缩略图引用而不是 event.target... 我可能需要更新我的 itemArray 以包含指向 figure 元素的链接,例如原始 PhotoSwipe 演示。正如我之前所写的,我还是 Javascript 的新手,所以弄清楚一些事情需要时间。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript jquery photoswipe


    【解决方案1】:

    我自己想出来的。我用event.target 真的把事情搞砸了。使用 PhotoSwipe 的正确方法需要我提供实际的 DOM 元素而不是固定的元素(如事件目标)。

    这样做的正确方法就像演示: 创建 itemArray 时保存 DOM 元素(选择器) 使用 itemArray 中的 DOM 元素来提供正确的元素来计算边界矩形。

    正确的 jQuery 代码:

    var gallerySelector = "#img-gallery";
    var imageListSelector = "#imageList";
    // parse server reply (JSON, imitated, saved into a tag)
    var itemArray = jQuery.parseJSON($(imageListSelector).html());
    
    var index = 1;
    // HTML structure of gallery image
    var imageHTML = "<figure class=\"col-xs-12 col-sm-6 col-md-4\" " + 
        "itemprop=\"associatedMedia\" itemscope " + 
        "itemtype=\"http://schema.org/ImageObject\">\n" +
        "<a href=\"{imageSource}\" itemprop=\"contentUrl\" data-size=\"{imageSize}\">\n" +
        "<img class=\"img-responsive\" src=\"{imageThumb}\" itemprop=\"thumbnail\" />\n" +
        "</a>\n</figure>";
    // generate images based on JSON request (imitated) and appended them to the page
    itemArray.forEach(function(item) {
        var imageTags = imageHTML.replace("{imageSource}", item.src);
        var imageTags = imageTags.replace("{imageSize}", (""+item.w+"x"+item.h));
        var imageTags = imageTags.replace("{imageThumb}", item.msrc);
        $(gallerySelector).append(imageTags);
        item.el = $(gallerySelector + " figure:last img")[0];
    });
    
    $('.my-gallery').each( function() {
        var $pic     = $(this);
        var $pswp = $('.pswp')[0];
        $pic.on('click', 'figure', function(event) {
            event.preventDefault();
            var $index = $(this).index();
            var options = {
                index: $index,
                getThumbBoundsFn: function(index) {
                    // get element we clicked on to determine its position in window
                    //var thumbnail = event.target;
                    var thumbnail = itemArray[index].el;
                    // get position of element relative to viewport
                    var rect = thumbnail.getBoundingClientRect();
                    // get window scroll Y
                    var pageYScroll = window.pageYOffset ||
                        document.documentElement.scrollTop; 
                    return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
                }
            }
            // Initialize PhotoSwipe
            var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, itemArray, options);
            lightBox.init();
        });
    });
    

    变更摘要:

    添加了item.el 属性,当它被附加到画廊时保存最后添加的元素(在我的例子中 - figure img,因为我需要 img 对象来计算它的边界矩形)。

    event.target 替换为各自的itemArray[index].el(之前保存的节点)。

    希望这会有所帮助!我花了几个小时和 PhotoSwipe 演示页面的一些试验和错误来解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-11
      • 2016-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-07
      相关资源
      最近更新 更多