如何在图像上将放大镜效果和灯箱效果结合在一起?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (156)

我想把放大镜和灯箱都应用在图像上,这样当用户在图像上悬停时,放大镜效果就会出现,当他点击时,灯箱就会出现。但在我的情况下,灯箱停止工作时,我激活放大镜。因此,当我删除玻璃CSS灯箱正常工作。

注意:下面的代码片段不起作用是因为某种原因,但Codepen是这样做的

/*!
 * Lightbox v2.10.0
 * by Lokesh Dhakar
 *
 * More info:
 * http://lokeshdhakar.com/projects/lightbox2/
 *
 * Copyright 2007, 2018 Lokesh Dhakar
 * Released under the MIT license
 * https://github.com/lokesh/lightbox2/blob/master/LICENSE
 *
 * @preserve
 */
! function(a, b) {
  "function" == typeof define && define.amd ? define(["jquery"], b) : "object" == typeof exports ? module.exports = b(require("jquery")) : a.lightbox = b(a.jQuery)
}(this, function(a) {
  function b(b) {
    this.album = [], this.currentImageIndex = void 0, this.init(), this.options = a.extend({}, this.constructor.defaults), this.option(b)
  }
  return b.defaults = {
    albumLabel: "Image %1 of %2",
    alwaysShowNavOnTouchDevices: !1,
    fadeDuration: 600,
    fitImagesInViewport: !0,
    imageFadeDuration: 600,
    positionFromTop: 50,
    resizeDuration: 700,
    showImageNumberLabel: !0,
    wrapAround: !1,
    disableScrolling: !1,
    sanitizeTitle: !1
  }, b.prototype.option = function(b) {
    a.extend(this.options, b)
  }, b.prototype.imageCountLabel = function(a, b) {
    return this.options.albumLabel.replace(/%1/g, a).replace(/%2/g, b)
  }, b.prototype.init = function() {
    var b = this;
    a(document).ready(function() {
      b.enable(), b.build()
    })
  }, b.prototype.enable = function() {
    var b = this;
    a("body").on("click", "a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]", function(c) {
      return b.start(a(c.currentTarget)), !1
    })
  }, b.prototype.build = function() {
    if (!(a("#lightbox").length > 0)) {
      var b = this;
      a('<div id="lightboxOverlay" class="lightboxOverlay"></div><div id="lightbox" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" /><div class="lb-nav"><a class="lb-prev" href="" ></a><a class="lb-next" href="" ></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close"></a></div></div></div></div>').appendTo(a("body")), this.$lightbox = a("#lightbox"), this.$overlay = a("#lightboxOverlay"), this.$outerContainer = this.$lightbox.find(".lb-outerContainer"), this.$container = this.$lightbox.find(".lb-container"), this.$image = this.$lightbox.find(".lb-image"), this.$nav = this.$lightbox.find(".lb-nav"), this.containerPadding = {
        top: parseInt(this.$container.css("padding-top"), 10),
        right: parseInt(this.$container.css("padding-right"), 10),
        bottom: parseInt(this.$container.css("padding-bottom"), 10),
        left: parseInt(this.$container.css("padding-left"), 10)
      }, this.imageBorderWidth = {
        top: parseInt(this.$image.css("border-top-width"), 10),
        right: parseInt(this.$image.css("border-right-width"), 10),
        bottom: parseInt(this.$image.css("border-bottom-width"), 10),
        left: parseInt(this.$image.css("border-left-width"), 10)
      }, this.$overlay.hide().on("click", function() {
        return b.end(), !1
      }), this.$lightbox.hide().on("click", function(c) {
        return "lightbox" === a(c.target).attr("id") && b.end(), !1
      }), this.$outerContainer.on("click", function(c) {
        return "lightbox" === a(c.target).attr("id") && b.end(), !1
      }), this.$lightbox.find(".lb-prev").on("click", function() {
        return 0 === b.currentImageIndex ? b.changeImage(b.album.length - 1) : b.changeImage(b.currentImageIndex - 1), !1
      }), this.$lightbox.find(".lb-next").on("click", function() {
        return b.currentImageIndex === b.album.length - 1 ? b.changeImage(0) : b.changeImage(b.currentImageIndex + 1), !1
      }), this.$nav.on("mousedown", function(a) {
        3 === a.which && (b.$nav.css("pointer-events", "none"), b.$lightbox.one("contextmenu", function() {
          setTimeout(function() {
            this.$nav.css("pointer-events", "auto")
          }.bind(b), 0)
        }))
      }), this.$lightbox.find(".lb-loader, .lb-close").on("click", function() {
        return b.end(), !1
      })
    }
  }, b.prototype.start = function(b) {
    function c(a) {
      d.album.push({
        alt: a.attr("data-alt"),
        link: a.attr("href"),
        title: a.attr("data-title") || a.attr("title")
      })
    }
    var d = this,
      e = a(window);
    e.on("resize", a.proxy(this.sizeOverlay, this)), a("select, object, embed").css({
      visibility: "hidden"
    }), this.sizeOverlay(), this.album = [];
    var f, g = 0,
      h = b.attr("data-lightbox");
    if (h) {
      f = a(b.prop("tagName") + '[data-lightbox="' + h + '"]');
      for (var i = 0; i < f.length; i = ++i) c(a(f[i])), f[i] === b[0] && (g = i)
    } else if ("lightbox" === b.attr("rel")) c(b);
    else {
      f = a(b.prop("tagName") + '[rel="' + b.attr("rel") + '"]');
      for (var j = 0; j < f.length; j = ++j) c(a(f[j])), f[j] === b[0] && (g = j)
    }
    var k = e.scrollTop() + this.options.positionFromTop,
      l = e.scrollLeft();
    this.$lightbox.css({
      top: k + "px",
      left: l + "px"
    }).fadeIn(this.options.fadeDuration), this.options.disableScrolling && a("html").addClass("lb-disable-scrolling"), this.changeImage(g)
  }, b.prototype.changeImage = function(b) {
    var c = this;
    this.disableKeyboardNav();
    var d = this.$lightbox.find(".lb-image");
    this.$overlay.fadeIn(this.options.fadeDuration), a(".lb-loader").fadeIn("slow"), this.$lightbox.find(".lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption").hide(), this.$outerContainer.addClass("animating");
    var e = new Image;
    e.onload = function() {
      var f, g, h, i, j, k;
      d.attr({
        alt: c.album[b].alt,
        src: c.album[b].link
      }), a(e), d.width(e.width), d.height(e.height), c.options.fitImagesInViewport && (k = a(window).width(), j = a(window).height(), i = k - c.containerPadding.left - c.containerPadding.right - c.imageBorderWidth.left - c.imageBorderWidth.right - 20, h = j - c.containerPadding.top - c.containerPadding.bottom - c.imageBorderWidth.top - c.imageBorderWidth.bottom - 120, c.options.maxWidth && c.options.maxWidth < i && (i = c.options.maxWidth), c.options.maxHeight && c.options.maxHeight < i && (h = c.options.maxHeight), (e.width > i || e.height > h) && (e.width / i > e.height / h ? (g = i, f = parseInt(e.height / (e.width / g), 10), d.width(g), d.height(f)) : (f = h, g = parseInt(e.width / (e.height / f), 10), d.width(g), d.height(f)))), c.sizeContainer(d.width(), d.height())
    }, e.src = this.album[b].link, this.currentImageIndex = b
  }, b.prototype.sizeOverlay = function() {
    this.$overlay.width(a(document).width()).height(a(document).height())
  }, b.prototype.sizeContainer = function(a, b) {
    function c() {
      d.$lightbox.find(".lb-dataContainer").width(g), d.$lightbox.find(".lb-prevLink").height(h), d.$lightbox.find(".lb-nextLink").height(h), d.showImage()
    }
    var d = this,
      e = this.$outerContainer.outerWidth(),
      f = this.$outerContainer.outerHeight(),
      g = a + this.containerPadding.left + this.containerPadding.right + this.imageBorderWidth.left + this.imageBorderWidth.right,
      h = b + this.containerPadding.top + this.containerPadding.bottom + this.imageBorderWidth.top + this.imageBorderWidth.bottom;
    e !== g || f !== h ? this.$outerContainer.animate({
      width: g,
      height: h
    }, this.options.resizeDuration, "swing", function() {
      c()
    }) : c()
  }, b.prototype.showImage = function() {
    this.$lightbox.find(".lb-loader").stop(!0).hide(), this.$lightbox.find(".lb-image").fadeIn(this.options.imageFadeDuration), this.updateNav(), this.updateDetails(), this.preloadNeighboringImages(), this.enableKeyboardNav()
  }, b.prototype.updateNav = function() {
    var a = !1;
    try {
      document.createEvent("TouchEvent"), a = !!this.options.alwaysShowNavOnTouchDevices
    } catch (a) {}
    this.$lightbox.find(".lb-nav").show(), this.album.length > 1 && (this.options.wrapAround ? (a && this.$lightbox.find(".lb-prev, .lb-next").css("opacity", "1"), this.$lightbox.find(".lb-prev, .lb-next").show()) : (this.currentImageIndex > 0 && (this.$lightbox.find(".lb-prev").show(), a && this.$lightbox.find(".lb-prev").css("opacity", "1")), this.currentImageIndex < this.album.length - 1 && (this.$lightbox.find(".lb-next").show(), a && this.$lightbox.find(".lb-next").css("opacity", "1"))))
  }, b.prototype.updateDetails = function() {
    var b = this;
    if (void 0 !== this.album[this.currentImageIndex].title && "" !== this.album[this.currentImageIndex].title) {
      var c = this.$lightbox.find(".lb-caption");
      this.options.sanitizeTitle ? c.text(this.album[this.currentImageIndex].title) : c.html(this.album[this.currentImageIndex].title), c.fadeIn("fast").find("a").on("click", function(b) {
        void 0 !== a(this).attr("target") ? window.open(a(this).attr("href"), a(this).attr("target")) : location.href = a(this).attr("href")
      })
    }
    if (this.album.length > 1 && this.options.showImageNumberLabel) {
      var d = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);
      this.$lightbox.find(".lb-number").text(d).fadeIn("fast")
    } else this.$lightbox.find(".lb-number").hide();
    this.$outerContainer.removeClass("animating"), this.$lightbox.find(".lb-dataContainer").fadeIn(this.options.resizeDuration, function() {
      return b.sizeOverlay()
    })
  }, b.prototype.preloadNeighboringImages = function() {
    if (this.album.length > this.currentImageIndex + 1) {
      (new Image).src = this.album[this.currentImageIndex + 1].link
    }
    if (this.currentImageIndex > 0) {
      (new Image).src = this.album[this.currentImageIndex - 1].link
    }
  }, b.prototype.enableKeyboardNav = function() {
    a(document).on("keyup.keyboard", a.proxy(this.keyboardAction, this))
  }, b.prototype.disableKeyboardNav = function() {
    a(document).off(".keyboard")
  }, b.prototype.keyboardAction = function(a) {
    var b = a.keyCode,
      c = String.fromCharCode(b).toLowerCase();
    27 === b || c.match(/x|o|c/) ? this.end() : "p" === c || 37 === b ? 0 !== this.currentImageIndex ? this.changeImage(this.currentImageIndex - 1) : this.options.wrapAround && this.album.length > 1 && this.changeImage(this.album.length - 1) : "n" !== c && 39 !== b || (this.currentImageIndex !== this.album.length - 1 ? this.changeImage(this.currentImageIndex + 1) : this.options.wrapAround && this.album.length > 1 && this.changeImage(0))
  }, b.prototype.end = function() {
    this.disableKeyboardNav(), a(window).off("resize", this.sizeOverlay), this.$lightbox.fadeOut(this.options.fadeDuration), this.$overlay.fadeOut(this.options.fadeDuration), a("select, object, embed").css({
      visibility: "visible"
    }), this.options.disableScrolling && a("html").removeClass("lb-disable-scrolling")
  }, new b
});
//# sourceMappingURL=lightbox.min.map


//magnyfing glass


$(function() {

  var native_width = 0;
  var native_height = 0;
  var mouse = {
    x: 0,
    y: 0
  };
  var magnify;
  var cur_img;

  var ui = {
    magniflier: $('.magniflier')
  };

  // Add the magnifying glass
  if (ui.magniflier.length) {
    var div = document.createElement('div');
    div.setAttribute('class', 'glass');
    ui.glass = $(div);

    $('body').append(div);
  }


  // All the magnifying will happen on "mousemove"

  var mouseMove = function(e) {
    var $el = $(this);

    // Container offset relative to document
    var magnify_offset = cur_img.offset();

    // Mouse position relative to container
    // pageX/pageY - container's offsetLeft/offetTop
    mouse.x = e.pageX - magnify_offset.left;
    mouse.y = e.pageY - magnify_offset.top;

    // The Magnifying glass should only show up when the mouse is inside
    // It is important to note that attaching mouseout and then hiding
    // the glass wont work cuz mouse will never be out due to the glass
    // being inside the parent and having a higher z-index (positioned above)
    if (
      mouse.x < cur_img.width() &&
      mouse.y < cur_img.height() &&
      mouse.x > 0 &&
      mouse.y > 0
    ) {

      magnify(e);
    } else {
      ui.glass.fadeOut(100);
    }

    return;
  };

  var magnify = function(e) {

    // The background position of div.glass will be
    // changed according to the position
    // of the mouse over the img.magniflier
    //
    // So we will get the ratio of the pixel
    // under the mouse with respect
    // to the image and use that to position the
    // large image inside the magnifying glass

    var rx = Math.round(mouse.x / cur_img.width() * native_width - ui.glass.width() / 2) * -1;
    var ry = Math.round(mouse.y / cur_img.height() * native_height - ui.glass.height() / 2) * -1;
    var bg_pos = rx + "px " + ry + "px";

    // Calculate pos for magnifying glass
    //
    // Easy Logic: Deduct half of width/height
    // from mouse pos.

    // var glass_left = mouse.x - ui.glass.width() / 2;
    // var glass_top  = mouse.y - ui.glass.height() / 2;
    var glass_left = e.pageX - ui.glass.width() / 2;
    var glass_top = e.pageY - ui.glass.height() / 2;
    //console.log(glass_left, glass_top, bg_pos)
    // Now, if you hover on the image, you should
    // see the magnifying glass in action
    ui.glass.css({
      left: glass_left,
      top: glass_top,
      backgroundPosition: bg_pos
    });

    return;
  };

  $('.magniflier').on('mousemove', function() {
    ui.glass.fadeIn(200);

    cur_img = $(this);

    var large_img_loaded = cur_img.data('large-img-loaded');
    var src = cur_img.data('large') || cur_img.attr('src');

    // Set large-img-loaded to true
    // cur_img.data('large-img-loaded', true)

    if (src) {
      ui.glass.css({
        'background-image': 'url(' + src + ')',
        'background-repeat': 'no-repeat'
      });
    }

    // When the user hovers on the image, the script will first calculate
    // the native dimensions if they don't exist. Only after the native dimensions
    // are available, the script will show the zoomed version.
    //if(!native_width && !native_height) {

    if (!cur_img.data('native_width')) {
      // This will create a new image object with the same image as that in .small
      // We cannot directly get the dimensions from .small because of the 
      // width specified to 200px in the html. To get the actual dimensions we have
      // created this image object.
      var image_object = new Image();

      image_object.onload = function() {
        // This code is wrapped in the .load function which is important.
        // width and height of the object would return 0 if accessed before 
        // the image gets loaded.
        native_width = image_object.width;
        native_height = image_object.height;

        cur_img.data('native_width', native_width);
        cur_img.data('native_height', native_height);

        //console.log(native_width, native_height);

        mouseMove.apply(this, arguments);

        ui.glass.on('mousemove', mouseMove);
      };


      image_object.src = src;

      return;
    } else {

      native_width = cur_img.data('native_width');
      native_height = cur_img.data('native_height');
    }
    //}
    //console.log(native_width, native_height);

    mouseMove.apply(this, arguments);

    ui.glass.on('mousemove', mouseMove);
  });

  ui.glass.on('mouseout', function() {
    ui.glass.off('mousemove', mouseMove);
  });

});
html.lb-disable-scrolling {
  overflow: hidden;
  /* Position fixed required for iOS. Just putting overflow: hidden; on the body is not enough. */
  position: fixed;
  height: 100vh;
  width: 100vw;
}

.lightboxOverlay {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 9999;
  background-color: black;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
  opacity: 0.8;
  display: none;
}

.lightbox {
  position: absolute;
  left: 0;
  width: 100%;
  z-index: 10000;
  text-align: center;
  line-height: 0;
  font-weight: normal;
}

.lightbox .lb-image {
  display: block;
  height: auto;
  max-width: inherit;
  max-height: none;
  border-radius: 3px;
  /* Image border */
  border: 4px solid white;
}

.lightbox a img {
  border: none;
}

.lb-outerContainer {
  position: relative;
  *zoom: 1;
  width: 250px;
  height: 250px;
  margin: 0 auto;
  border-radius: 4px;
  /* Background color behind image.
     This is visible during transitions. */
  background-color: white;
}

.lb-outerContainer:after {
  content: "";
  display: table;
  clear: both;
}

.lb-loader {
  position: absolute;
  top: 43%;
  left: 0;
  height: 25%;
  width: 100%;
  text-align: center;
  line-height: 0;
}

.lb-cancel {
  display: block;
  width: 32px;
  height: 32px;
  margin: 0 auto;
  background: url(../assets/imgs/lightbox/loading.gif) no-repeat;
}

.lb-nav {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  z-index: 10;
}

.lb-container>.nav {
  left: 0;
}

.lb-nav a {
  outline: none;
  background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
}

.lb-prev,
.lb-next {
  height: 100%;
  cursor: pointer;
  display: block;
}

.lb-nav a.lb-prev {
  width: 34%;
  left: 0;
  float: left;
  background: url(../assets/imgs/lightbox/prev.png) left 48% no-repeat;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
  opacity: 0;
  -webkit-transition: opacity 0.6s;
  -moz-transition: opacity 0.6s;
  -o-transition: opacity 0.6s;
  transition: opacity 0.6s;
}

.lb-nav a.lb-prev:hover {
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
  opacity: 1;
}

.lb-nav a.lb-next {
  width: 64%;
  right: 0;
  float: right;
  background: url(../assets/imgs/lightbox/next.png) right 48% no-repeat;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
  opacity: 0;
  -webkit-transition: opacity 0.6s;
  -moz-transition: opacity 0.6s;
  -o-transition: opacity 0.6s;
  transition: opacity 0.6s;
}

.lb-nav a.lb-next:hover {
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
  opacity: 1;
}

.lb-dataContainer {
  margin: 0 auto;
  padding-top: 5px;
  *zoom: 1;
  width: 100%;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}

.lb-dataContainer:after {
  content: "";
  display: table;
  clear: both;
}

.lb-data {
  padding: 0 4px;
  color: #ccc;
}

.lb-data .lb-details {
  width: 85%;
  float: left;
  text-align: left;
  line-height: 1.1em;
}

.lb-data .lb-caption {
  font-size: 13px;
  font-weight: bold;
  line-height: 1em;
}

.lb-data .lb-caption a {
  color: #4ae;
}

.lb-data .lb-number {
  display: block;
  clear: left;
  padding-bottom: 1em;
  font-size: 12px;
  color: #999999;
}

.lb-data .lb-close {
  display: block;
  float: right;
  width: 30px;
  height: 30px;
  background: url(../assets/imgs/lightbox/close.png) top right no-repeat;
  text-align: right;
  outline: none;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
  opacity: 0.7;
  -webkit-transition: opacity 0.2s;
  -moz-transition: opacity 0.2s;
  -o-transition: opacity 0.2s;
  transition: opacity 0.2s;
}

.lb-data .lb-close:hover {
  cursor: pointer;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
  opacity: 1;
}


/* IF you remove this, lightbox will work but not the magnyfing glass */

.glass {
  width: 150px;
  height: 150px;
  position: absolute;
  border-radius: 50%;
  cursor: crosshair;
  /* Multiple box shadows to achieve the glass effect */
  box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
  /* hide the glass by default */
  display: none;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<!--START BOOK PREVIEW-->
<div class="book-preview px-5 py-5 container img-magnifier-container">
  <div class="row">
    <div class="col-lg-4 book">
      <a href="http://subsolardesigns.com/odrin/demo1/wp-content/uploads/sites/8/2017/08/cover_taurus-468x700.png" data-lightbox="image-1" data-title="My caption">
        <img src="http://subsolardesigns.com/odrin/demo1/wp-content/uploads/sites/8/2017/08/cover_taurus-468x700.png" alt="Book" class="img-fluid magniflier" id="book-glass" alt="Responsive image">
      </a>
    </div>

  </div>
</div>
</div>
</div>

提问于
用户回答回答于

问题是你没有单击图像,而是单击.glassdom节点。你需要处理.glass元素上的click事件,然后调用单击图像,以便灯箱插件执行预期的操作。将以下代码添加到你的javascript中,将click事件重定向到你的图片代码。

ui.glass.on('click', function() {
  cur_img.click();
});

扫码关注云+社区

领取腾讯云代金券