需要帮助实施 EasyZoom jquery 插件

Posted

技术标签:

【中文标题】需要帮助实施 EasyZoom jquery 插件【英文标题】:Need help implementing EasyZoom jquery plugin 【发布时间】:2021-02-04 18:43:07 【问题描述】:

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

到目前为止,我已经创建了包含图像的 div,从 GitHub 复制了 CSS 和 javascript 文件,并将我的 html 页面链接到它们,请参见下面的具体代码。

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

HTML 代码 (我有一个从 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

【问题讨论】:

【参考方案1】:

既然您已经在使用 jQuery,那么如何将 Slick 用于您的滑块并将 EasyZoom 集成到您的光滑幻灯片中?

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

我们可以利用slick's dots 将点按钮操作为图像缩略图,因此您的原始标记中没有额外的 html ??

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

请注意,easyzoom 不会放大太多,因为我们使用的演示图像本身只有 600 像素宽。

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 + '"  />');

      );

    , 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"  />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/8HjXPXD.png">
      <img src="https://i.imgur.com/8HjXPXD.png"  />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/vUDcfcy.png">
      <img src="https://i.imgur.com/vUDcfcy.png"  />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/okTDHas.png">
      <img src="https://i.imgur.com/okTDHas.png"  />
    </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"  />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/EYTCssm.png">
      <img src="https://i.imgur.com/EYTCssm.png"  />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/3sAFPmL.png">
      <img src="https://i.imgur.com/3sAFPmL.png"  />
    </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"  />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/6JplNl6.png">
      <img src="https://i.imgur.com/6JplNl6.png"  />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/6X5GKWJ.png">
      <img src="https://i.imgur.com/6X5GKWJ.png"  />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/SefTwI1.png">
      <img src="https://i.imgur.com/SefTwI1.png"  />
    </a>
  </figure>
  <figure>
    <a href="https://i.imgur.com/qBmDrTU.png">
      <img src="https://i.imgur.com/qBmDrTU.png"  />
    </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 -->

【讨论】:

所以我尝试将 CSS 修复添加到我的样式表中,包括所有三个 CSS 和 JS 文件,然后在另一个 js 文件中,我写了$('FIGURE','.slides').addClass('easyzoom').easyZoom(); 但是,当我转到网页时,它仍然是'不工作,光标样式和东西没有改变@joshmoto @RenaW 查看我的缩略图版本的新更新答案 @RenaW 如果您正在努力调试当前环境,我们可以进行实时聊天,您可以与我分享您的问题的链接或更多详细信息。 现在可以在线聊天了吗?我仍然认为它不起作用 好的,我会回来的 tmrw

以上是关于需要帮助实施 EasyZoom jquery 插件的主要内容,如果未能解决你的问题,请参考以下文章

oAuth 实施:当前域重要吗?

如何根据我的主题实现粘性菜单?

jquery validate表单验证插件-推荐

需要将 jQuery 验证插件与 jsf 集成

同位素过滤器实施后 jQuery 调用不起作用

Wordpress 插件“无限滚动”(jQuery)破解帮助