需要帮助实施 EasyZoom jquery 插件

Need help implementing EasyZoom jquery plugin

一般来说,我对 jquery 和 javascript 不太熟悉,所以请耐心等待。但是,我正在尝试使用 EasyZoom:https://i-like-robots.github.io/EasyZoom/ 创建一个在悬停时缩放的图片库。我想实现类似于 link.

中“带有缩略图”的内容

到目前为止,我已经创建了带有图像的 div,从 GitHub 复制了 CSS 和 javascript 文件,并且 link 编辑了我的 HTML给他们分页,具体代码见下方。

但是,我显然在这里遗漏了一些东西。在 JS 文件中,我发现一个地方说 @param {Object} target 我应该在需要 Easyzoom 的地方指定 HTML 中的对象吗?如果是这样,如何?我也很困惑如何指定我想要一个带有 Easyzoom 的图片库。所以,如果有人能帮我解决这个问题,那就太好了。

HTML代码 (我有一个图像列表 links,是我从 'images' 下的 Django 模型中获得的)

       {% for image in images %}
           <div class="slides">
               <div class="easyzoom">
                   <a href="{{image}}">
                       <img src="{{image}}">
                   </a>
               </div>
           </div>
       {% endfor %}

Easyzoom.css

/**
 * EasyZoom core styles
 */
 .easyzoom {
    position: relative;

    /* 'Shrink-wrap' the element */
    display: inline-block;
    *display: inline;
    *zoom: 1;
}

.easyzoom img {
    vertical-align: bottom;
}

.easyzoom.is-loading img {
    cursor: progress;
}

.easyzoom.is-ready img {
    cursor: crosshair;
}

.easyzoom.is-error  img {
    cursor: not-allowed;
}

.easyzoom-notice {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 150;
    width: 10em;
    margin: -1em 0 0 -5em;
    line-height: 2em;
    text-align: center;
    background: #FFF;
    box-shadow: 0 0 10px #888;
}

.easyzoom-flyout {
    position:absolute;
    z-index: 100;
    overflow: hidden;
    background: #FFF;
}

Easyzoom.js

(function (root, factory) {
    'use strict';
    if(typeof define === 'function' && define.amd) {
        define(['jquery'], function($){
            factory($);
        });
    } else if(typeof module === 'object' && module.exports) {
        module.exports = (root.EasyZoom = factory(require('jquery')));
    } else {
        root.EasyZoom = factory(root.jQuery);
    }
}(this, function ($) {

    'use strict';

    var zoomImgOverlapX;
    var zoomImgOverlapY;
    var ratioX;
    var ratioY;
    var pointerPositionX;
    var pointerPositionY;

    var defaults = {

        // The text to display within the notice box while loading the zoom image.
        loadingNotice: 'Loading image',

        // The text to display within the notice box if an error occurs when loading the zoom image.
        errorNotice: 'The image could not be loaded',

        // The time (in milliseconds) to display the error notice.
        errorDuration: 2500,

        // Attribute to retrieve the zoom image URL from.
        linkAttribute: 'href',

        // Prevent clicks on the zoom image link.
        preventClicks: true,

        // Callback function to execute before the flyout is displayed.
        beforeShow: $.noop,

        // Callback function to execute before the flyout is removed.
        beforeHide: $.noop,

        // Callback function to execute when the flyout is displayed.
        onShow: $.noop,

        // Callback function to execute when the flyout is removed.
        onHide: $.noop,

        // Callback function to execute when the cursor is moved while over the image.
        onMove: $.noop

    };

    /**
     * EasyZoom
     * @constructor
     * @param {Object} target
     * @param {Object} options (Optional)
     */
    function EasyZoom(target, options) {
        this.$target = $(target);
        this.opts = $.extend({}, defaults, options, this.$target.data());

        this.isOpen === undefined && this._init();
    }

    /**
     * Init
     * @private
     */
    EasyZoom.prototype._init = function() {
        this.$link   = this.$target.find('a');
        this.$image  = this.$target.find('img');

        this.$flyout = $('<div class="easyzoom-flyout" />');
        this.$notice = $('<div class="easyzoom-notice" />');

        this.$target.on({
            'mousemove.easyzoom touchmove.easyzoom': $.proxy(this._onMove, this),
            'mouseleave.easyzoom touchend.easyzoom': $.proxy(this._onLeave, this),
            'mouseenter.easyzoom touchstart.easyzoom': $.proxy(this._onEnter, this)
        });

        this.opts.preventClicks && this.$target.on('click.easyzoom', function(e) {
            e.preventDefault();
        });
    };

    /**
     * Show
     * @param {MouseEvent|TouchEvent} e
     * @param {Boolean} testMouseOver (Optional)
     */
    EasyZoom.prototype.show = function(e, testMouseOver) {
        var self = this;

        if (this.opts.beforeShow.call(this) === false) return;

        if (!this.isReady) {
            return this._loadImage(this.$link.attr(this.opts.linkAttribute), function() {
                if (self.isMouseOver || !testMouseOver) {
                    self.show(e);
                }
            });
        }

        this.$target.append(this.$flyout);

        var targetWidth = this.$target.outerWidth();
        var targetHeight = this.$target.outerHeight();

        var flyoutInnerWidth = this.$flyout.width();
        var flyoutInnerHeight = this.$flyout.height();

        var zoomImgWidth = this.$zoom.width();
        var zoomImgHeight = this.$zoom.height();

        zoomImgOverlapX = Math.ceil(zoomImgWidth - flyoutInnerWidth);
        zoomImgOverlapY = Math.ceil(zoomImgHeight - flyoutInnerHeight);

        // For when the zoom image is smaller than the flyout element.
        if (zoomImgOverlapX < 0) zoomImgOverlapX = 0;
        if (zoomImgOverlapY < 0) zoomImgOverlapY = 0;

        ratioX = zoomImgOverlapX / targetWidth;
        ratioY = zoomImgOverlapY / targetHeight;

        this.isOpen = true;

        this.opts.onShow.call(this);

        e && this._move(e);
    };

    /**
     * On enter
     * @private
     * @param {Event} e
     */
    EasyZoom.prototype._onEnter = function(e) {
        var touches = e.originalEvent.touches;

        this.isMouseOver = true;

        if (!touches || touches.length == 1) {
            e.preventDefault();
            this.show(e, true);
        }
    };

    /**
     * On move
     * @private
     * @param {Event} e
     */
    EasyZoom.prototype._onMove = function(e) {
        if (!this.isOpen) return;

        e.preventDefault();
        this._move(e);
    };

    /**
     * On leave
     * @private
     */
    EasyZoom.prototype._onLeave = function() {
        this.isMouseOver = false;
        this.isOpen && this.hide();
    };

    /**
     * On load
     * @private
     * @param {Event} e
     */
    EasyZoom.prototype._onLoad = function(e) {
        // IE may fire a load event even on error so test the image dimensions
        if (!e.currentTarget.width) return;

        this.isReady = true;

        this.$notice.detach();
        this.$flyout.html(this.$zoom);
        this.$target.removeClass('is-loading').addClass('is-ready');

        e.data.call && e.data();
    };

    /**
     * On error
     * @private
     */
    EasyZoom.prototype._onError = function() {
        var self = this;

        this.$notice.text(this.opts.errorNotice);
        this.$target.removeClass('is-loading').addClass('is-error');

        this.detachNotice = setTimeout(function() {
            self.$notice.detach();
            self.detachNotice = null;
        }, this.opts.errorDuration);
    };

    /**
     * Load image
     * @private
     * @param {String} href
     * @param {Function} callback
     */
    EasyZoom.prototype._loadImage = function(href, callback) {
        var zoom = new Image();

        this.$target
            .addClass('is-loading')
            .append(this.$notice.text(this.opts.loadingNotice));

        this.$zoom = $(zoom)
            .on('error', $.proxy(this._onError, this))
            .on('load', callback, $.proxy(this._onLoad, this));

        zoom.style.position = 'absolute';
        zoom.src = href;
    };

    /**
     * Move
     * @private
     * @param {Event} e
     */
    EasyZoom.prototype._move = function(e) {

        if (e.type.indexOf('touch') === 0) {
            var touchlist = e.touches || e.originalEvent.touches;
            pointerPositionX = touchlist[0].pageX;
            pointerPositionY = touchlist[0].pageY;
        } else {
            pointerPositionX = e.pageX || pointerPositionX;
            pointerPositionY = e.pageY || pointerPositionY;
        }

        var targetOffset  = this.$target.offset();
        var relativePositionX = pointerPositionX - targetOffset.left;
        var relativePositionY = pointerPositionY - targetOffset.top;
        var moveX = Math.ceil(relativePositionX * ratioX);
        var moveY = Math.ceil(relativePositionY * ratioY);

        // Close if outside
        if (moveX < 0 || moveY < 0 || moveX > zoomImgOverlapX || moveY > zoomImgOverlapY) {
            this.hide();
        } else {
            var top = moveY * -1;
            var left = moveX * -1;

            this.$zoom.css({
                top: top,
                left: left
            });

            this.opts.onMove.call(this, top, left);
        }

    };

    /**
     * Hide
     */
    EasyZoom.prototype.hide = function() {
        if (!this.isOpen) return;
        if (this.opts.beforeHide.call(this) === false) return;

        this.$flyout.detach();
        this.isOpen = false;

        this.opts.onHide.call(this);
    };

    /**
     * Swap
     * @param {String} standardSrc
     * @param {String} zoomHref
     * @param {String|Array} srcset (Optional)
     */
    EasyZoom.prototype.swap = function(standardSrc, zoomHref, srcset) {
        this.hide();
        this.isReady = false;

        this.detachNotice && clearTimeout(this.detachNotice);

        this.$notice.parent().length && this.$notice.detach();

        this.$target.removeClass('is-loading is-ready is-error');

        this.$image.attr({
            src: standardSrc,
            srcset: $.isArray(srcset) ? srcset.join() : srcset
        });

        this.$link.attr(this.opts.linkAttribute, zoomHref);
    };

    /**
     * Teardown
     */
    EasyZoom.prototype.teardown = function() {
        this.hide();

        this.$target
            .off('.easyzoom')
            .removeClass('is-loading is-ready is-error');

        this.detachNotice && clearTimeout(this.detachNotice);

        delete this.$link;
        delete this.$zoom;
        delete this.$image;
        delete this.$notice;
        delete this.$flyout;

        delete this.isOpen;
        delete this.isReady;
    };

    // jQuery plugin wrapper
    $.fn.easyZoom = function(options) {
        return this.each(function() {
            var api = $.data(this, 'easyZoom');

            if (!api) {
                $.data(this, 'easyZoom', new EasyZoom(this, options));
            } else if (api.isOpen === undefined) {
                api._init();
            }
        });
    };

    return EasyZoom;
}));

js 和 CSS 文件基本上是 Github 上的内容的精确副本:https://github.com/i-like-robots/EasyZoom

既然您已经在使用 jQuery,那么在您漂亮的幻灯片中使用 Slick for your slider and integrate EasyZoom 怎么样?

大量很酷的功能,检查它... https://kenwheeler.github.io/slick/

我们可以利用 slick's dots 将点按钮操作成图像缩略图,因此在您的原始标记

中没有额外的 html

阅读我在下面的工作示例和 jsfiddle 中的评论。

Please note the easyzoom does not zoom very much because the demo images we are using are natively only 600px wide.

jsFiddle 版本...https://jsfiddle.net/joshmoto/mdkpnw7g/

工作堆栈示例...

// document ready
$(document).ready(function() {

  // init ez-slider with slick
  $('.ez-slider').on('init', function(slick) {

    // slide var for use timeout
    const slider = this;

    // slight delay so slick init completes render
    setTimeout(function() {

      // init the easy zoom on slider 
      $('FIGURE', slider).addClass('easyzoom').easyZoom();

      // thumb buttons
      let thumbs = $('.slick-dots > LI > BUTTON', slider);

      // each thumbnail button function
      $.each(thumbs, function(i, e) {

        // slide id
        let slide_id = $(this).attr('aria-controls');

        // get thumbnail image src
        let thumb_img = $('#' + slide_id).find('IMG').attr('src');

        // change thumb button inner html too
        $(this).html('<img src="' + thumb_img + '" alt="" />');

      });

    }, 100);

  // then our slick options
  }).slick({
    slidesToShow: 1,
    slidesToScroll: 1,
    dots: true,
    arrows: false,
    adaptiveHeight: true,
    autoplay: false
  });

});
BODY {
  margin: 0;
  padding: 20px;
}

/* The minor fix I added to get demo working */

.ez-slider .easyzoom .easyzoom-flyout {
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

/* Slide demo css not needed */

.ez-slider {
  max-width: 400px;
  margin: 0 auto 20px auto !important;
}

.ez-slider FIGURE {
  margin: 0;
  display: block;
  position: relative;
  overflow: hidden;
}

.ez-slider FIGURE > A {
  height: auto;
  display: block;
  width: 100%;
}

.ez-slider FIGURE > A > IMG {
  height: auto;
  width: 100%;
  display: block;
}

.ez-slider .slick-dots {
  margin: 10px -5px 0 -5px;
  position: relative;
  bottom: 0;
  width: auto;
  display: block;
  
}

.ez-slider .slick-dots LI {
  width: calc(20% - 10px);
  height: auto;
  margin: 0 0 10px 0;
  padding: 0 5px 0 5px;
  display: inline-block;
}

.ez-slider .slick-dots LI.slick-active BUTTON,
.ez-slider .slick-dots LI:hover BUTTON {
  opacity: 1;
}

.ez-slider .slick-dots LI BUTTON {
  overflow: hidden;
  position: relative;
  height: auto;
  padding: 0;
  transition: all .5s ease;
  width: 100%;
  opacity: .8;
}

.ez-slider .slick-dots LI BUTTON IMG {
  display: block;
  height: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}

.ez-slider .slick-dots LI BUTTON:before {
  display: block;
  position: relative;
  content: '';
  width: 100%;
  padding-top: 100%;
  height: auto;
}
<!-- space slider html -->
<div class="ez-slider">
  <figure>
    <a href="https://i.imgur.com/q5Y5RCH.png">
      <img src="https://i.imgur.com/q5Y5RCH.png" alt="" />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/8HjXPXD.png">
      <img src="https://i.imgur.com/8HjXPXD.png" alt="" />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/vUDcfcy.png">
      <img src="https://i.imgur.com/vUDcfcy.png" alt="" />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/okTDHas.png">
      <img src="https://i.imgur.com/okTDHas.png" alt="" />
    </a>
  </figure>
</div>

<!-- ocean slider html -->
<div class="ez-slider">
  <figure>
    <a href="https://i.imgur.com/x7ZYW4i.png">
      <img src="https://i.imgur.com/x7ZYW4i.png" alt="" />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/EYTCssm.png">
      <img src="https://i.imgur.com/EYTCssm.png" alt="" />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/3sAFPmL.png">
      <img src="https://i.imgur.com/3sAFPmL.png" alt="" />
    </a>
  </figure>
</div>

<!-- landscape slider html -->
<div class="ez-slider">
  <figure>
    <a href="https://i.imgur.com/IqLrd0o.png">
      <img src="https://i.imgur.com/IqLrd0o.png" alt="" />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/6JplNl6.png">
      <img src="https://i.imgur.com/6JplNl6.png" alt="" />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/6X5GKWJ.png">
      <img src="https://i.imgur.com/6X5GKWJ.png" alt="" />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/SefTwI1.png">
      <img src="https://i.imgur.com/SefTwI1.png" alt="" />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/qBmDrTU.png">
      <img src="https://i.imgur.com/qBmDrTU.png" alt="" />
    </a>
  </figure>
</div>

<!-- Include Slick CSS library -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" rel="stylesheet"/>

<!-- Include Slick Theme CSS library -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" rel="stylesheet"/>

<!-- Include EasyZoom CSS library -->
<link href="https://cdn.jsdelivr.net/npm/easyzoom@2.5.3/css/easyzoom.css" rel="stylesheet"/>

<!-- Include jQuery library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<!-- Include Slick JS library after jQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>

<!-- Include EasyZoom JS library after jQuery -->
<script src="https://cdn.jsdelivr.net/npm/easyzoom@2.5.3/src/easyzoom.js"></script>

<!-- Make sure you run all your custom JS after libraries -->