照片滑动:关闭图库会为错误的矩形(缩略图)添加动画效果

PhotoSwipe: closing gallery animates wrong rectangle (thumbnail)

本文关键字:略图 动画 添加 错误 照片      更新时间:2023-09-26

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

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

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

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

我相信我缺少一些将当前显示的幻灯片与相应的缩略图绑定的代码。我对演示页面的主要问题是:我很难理解原版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());

您可以在GitHub上找到有问题的整页

Codepen 上的 PhotoSwipe 演示

你能帮我找到我错过的东西吗?

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

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

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

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

自己想通了。我真的用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演示页面的反复试验来解决这个问题。