Skip to content

JS PhotoSwipe 相册插件

给网站的博客图片增加了点击预览功能,使用的 PhotoSwipe 插件。参照 Getting Started 中的代码,实现了点击图片时弹出图片预览功能(预览当前博客中的所有图片)。

1. 引用 CSS 和 JS 文件

这里使用了 BootCDN

html
<link href="https://cdn.bootcss.com/photoswipe/4.1.2/photoswipe.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/photoswipe/4.1.2/default-skin/default-skin.min.css" rel="stylesheet">

<script src="https://cdn.bootcss.com/photoswipe/4.1.2/photoswipe.min.js"></script>
<script src="https://cdn.bootcss.com/photoswipe/4.1.2/photoswipe-ui-default.min.js"></script>

2. 在页面上添加 HTML 代码

html
<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe.
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides.
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)"></button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"></button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

3. 添加初始化的 JS 代码

js
  let initPhotoSwipeFromDOM = function (imgSelector) {
    // parse slide data (url, title, size ...) from DOM elements 
    // (children of imgSelector)
    let parseThumbnailElements = function (els) {
        let items = [];

        for (let i = 0; i < els.length; i++) {
            let el = els[i];
            // create slide object
            let item = {
                src: el.getAttribute('src'),
                w: el.naturalWidth,
                h: el.naturalHeight
            };

            if (el.getAttribute('alt').length > 1) {
                item.title = el.getAttribute('alt');
            }

            item.el = el; // save link to element for getThumbBoundsFn
            items.push(item);
        }

        return items;
    };

    // find nearest parent element
    let closest = function closest(el, fn) {
        return el && (fn(el) ? el : closest(el.parentNode, fn));
    };

    // triggers when user clicks on thumbnail
    let onThumbnailsClick = function (e) {
        e = e || window.event;
        e.preventDefault ? e.preventDefault() : e.returnValue = false;

        let clickedListItem = e.target || e.srcElement;

        if (!clickedListItem) {
            return;
        }

        let imgElements = document.querySelectorAll(clickedListItem.getAttribute('data-pswd-selector'));
        let index = clickedListItem.getAttribute('data-pswp-index');

        if (index >= 0) {
            // open PhotoSwipe if valid index found
            openPhotoSwipe(index, imgElements);
        }
        return false;
    };

    let openPhotoSwipe = function (index, galleryElement, disableAnimation, fromURL) {
        let pswpElement = document.querySelectorAll('.pswp')[0],
            gallery,
            options,
            items;

        items = parseThumbnailElements(galleryElement);

        // define options (if needed)
        options = {
            getThumbBoundsFn: function (index) {
                // See Options -> getThumbBoundsFn section of documentation for more info
                let thumbnail = items[index],
                    pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
                    rect = thumbnail;

                return { x: rect.left, y: rect.top + pageYScroll, w: rect.width };
            }
        };

        // PhotoSwipe opened from URL
        if (fromURL) {
            if (options.galleryPIDs) {
                // parse real index when custom PIDs are used 
                // http://photoswipe.com/documentation/faq.html#custom-pid-in-url
                for (let j = 0; j < items.length; j++) {
                    if (items[j].pid == index) {
                        options.index = j;
                        break;
                    }
                }
            } else {
                // in URL indexes start from 1
                options.index = parseInt(index, 10) - 1;
            }
        } else {
            options.index = parseInt(index, 10);
        }

        // exit if index not found
        if (isNaN(options.index)) {
            return;
        }

        if (disableAnimation) {
            options.showAnimationDuration = 0;
        }

        options.closeOnScroll = false;

        options.shareButtons = [
            { id: 'download', label: '下载图片', url: '{{raw_image_url}}', download: true }
        ],

        // Pass data to PhotoSwipe and initialize it
        gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
        gallery.init();
    };

    // loop through all gallery elements and bind events
    let imgElements = document.querySelectorAll('img');

    for (let i = 0, l = imgElements.length; i < l; i++) {
        // imgElements[i].setAttribute('data-pswp-uid', i + 1);
        imgElements[i].setAttribute('data-pswp-index', i);
        imgElements[i].setAttribute('data-pswd-selector', imgSelector);
        imgElements[i].onclick = onThumbnailsClick;
    }
};

// execute above function
initPhotoSwipeFromDOM('.blog img');

1. Options

可以参照 Options 配置初始化选项。

2. Source

项目地址:https://github.com/dimsemenov/photoswipe

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.