如何使固定元素相对于当前顶部滚动位置保持不变?

How to Make a Fixed Element Stay Relative to the Current Top Scroll Position?

原题:

我有一个函数可以在出现提示时打开覆盖 fixed 定位的元素,我正在尝试弄清楚如何能够在当前 top 位置打开它,而不是每次 .no-scroll class 激活时跳转到页面顶部 (top: 0)。

这是我到目前为止取得的进展:

var o = 0;
$("img.click").click(function() {
  var s = $("html, body");
  o = $(window).scrollTop(), s.css("position", "fixed"), s.css("background-position", "0 -" + o + "px");
  var i = $(this).attr("src");
  s.find("#img-open").attr("src", i), s.addClass("no-scroll"), $("#img-view").addClass("target");
});

而且我还向 htmlbody 标签应用了 .no-scroll class:

html {
  height: initial;
}

body {
  height: auto;
}

body.no-scroll,
html.no-scroll {
  overflow: hidden;
  -webkit-overflow-scrolling: touch;
}

更新(对片段的应用答案 + 附加说明):

感谢 ,我能够调整一些额外的东西:

  1. html 标签上不需要 no-scroll class。因此,它被删除了。
  2. 我将 preventDefault() 添加到 touchmove 触摸事件,这使得 body 背景内容不会在 iOS Safari 等移动浏览器上滚动(截至 2018 年) .

$(document).ready(function() {
  $("a.lbimg > img.lb-click").click(function() {
    $("#lb-view").addClass("target");
    var o = document.documentElement.scrollTop || document.body.scrollTop;
    $('body').addClass('no-scroll');
    document.documentElement.scrollTop = document.body.scrollTop = o;
    $('body').bind('touchmove', function(e) {
      e.preventDefault();
    });
  });
  $(".lbimg-wrap, #lb-controls").on("click", function(s) {
    $("#lb-view").removeClass("target");
    $('body').removeClass('no-scroll');
    $('body').unbind('touchmove');
  });
});
body {
  height: auto;
}

body,
html {
  width: 100%;
  background-size: cover;
  background-repeat: no-repeat;
}

body {
  background: #808080;
  margin: 0;
  padding: 0;
  border: 0;
}

body.no-scroll {
  overflow: hidden;
}

p.content {
  color: white;
}

img {
  padding: 5px;
  border: 1px solid;
  box-sizing: border-box;
  z-index: 1;
}

.img-wrap {
  display: block;
}

.img-wrap img {
  line-height: 0;
  display: block;
}

a.lbimg {
  cursor: pointer;
  display: block;
  line-height: 0;
}

a.lbimg img {
  margin: 0 auto;
  padding: 0;
  border: 0;
}

.lb-click {
  width: 25%;
  height: auto;
}

.customlightbox {
  top: 0;
  bottom: 0;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  position: fixed;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.7);
  opacity: 0;
  z-index: -1;
}

.lbimg-wrap {
  width: 100%;
  height: 100%;
  padding: 47px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  position: relative;
  text-align: center;
}

.customlightbox img {
  border-color: white;
  width: auto;
  margin: auto;
  max-width: 100%;
  max-height: 100%;
  opacity: 0;
  position: relative;
  top: 50%;
  -webkit-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
}

#lb-controls {
  cursor: pointer;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  position: fixed;
  height: 50px;
  width: 50px;
  top: -50px;
  right: -3px;
  border-left: 1px solid;
  border-bottom: 1px solid;
  border-color: white;
  z-index: 3;
}

#lb-close {
  display: block;
  position: absolute;
  overflow: hidden;
  height: 30px;
  width: 30px;
  right: 10px;
  top: 10px;
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
}

#lb-close:before,
#lb-close:after {
  content: '';
  display: block;
  position: absolute;
  background: white;
  -webkit-border-radius: 2px;
  -moz-border-radius: 2px;
  border-radius: 2px;
}

#lb-close:before {
  width: 2px;
  height: 0;
  top: 0;
  left: 14px;
}

#lb-close:after {
  width: 0;
  height: 2px;
  top: 14px;
  left: 0;
}

.customlightbox.target {
  display: inline-block;
  z-index: 2;
}

.customlightbox.target,
.customlightbox.target img {
  opacity: 1;
}

.customlightbox.target~#lb-controls {
  top: -3px;
}

.customlightbox.target~#lb-controls #lb-close:after {
  width: 30px;
}

.customlightbox.target~#lb-controls #lb-close:before {
  height: 30px;
}

.lb-animate {
  -webkit-transition: 0.5s ease-in-out;
  -o-transition: 0.5s ease-in-out;
  transition: 0.5s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>

  <p class="content">
    Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll.
  </p>

  <div class="img-wrap">
    <a class="lbimg">
      <img class="lb-click" src="https://78.media.tumblr.com/8b1b8cbb2b963ab64eb2341f608638bf/tumblr_p4wbo7ZLJS1qccr26o1_1280.jpg">
    </a>
    <div class="customlightbox lb-animate" id="lb-view">
      <div class="lbimg-wrap">
        <img class="lb-animate" id="lbimg-open" src="https://78.media.tumblr.com/8b1b8cbb2b963ab64eb2341f608638bf/tumblr_p4wbo7ZLJS1qccr26o1_1280.jpg">
      </div>
    </div>
    <div id="lb-controls" class="lb-animate">
      <a id="lb-close" class="lb-animate"></a>
    </div>
  </div>

  <p class="content">
    Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll.
  </p>

</body>

你快到了:

$(document).ready(function() {

  $("a.lbimg > img.lb-click").click(function() {
    $("#lb-view").addClass("target");
    var o = document.documentElement.scrollTop || document.body.scrollTop;
    $('html, body').addClass('no-scroll');
    document.documentElement.scrollTop = document.body.scrollTop = o;
  });

  $(".lbimg-wrap, #lb-controls").on("click", function(s) {
      $("#lb-view").removeClass("target");
      $('html, body').removeClass('no-scroll');
  });
  
});
html {
  height: initial;
}

body {
  height: auto;
}

body,
html {
  width: 100%;
  background-size: cover;
  background-repeat: no-repeat;
}

body {
  background: #808080;
  margin: 0;
  padding: 0;
  border: 0;
}

body.no-scroll,
html.no-scroll {
  overflow: hidden;
}

p.content {
  color: white;
}

img {
  padding: 5px;
  border: 1px solid;
  box-sizing: border-box;
  z-index: 1;
}

.img-wrap {
  display: block;
}

.img-wrap img {
  line-height: 0;
  display: block;
}

a.lbimg {
  cursor: pointer;
  display: block;
  line-height: 0;
}

a.lbimg img {
  margin: 0 auto;
  padding: 0;
  border: 0;
}

.lb-click {
  width: 25%;
  height: auto;
}

.customlightbox {
  top: 0;
  bottom: 0;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  position: fixed;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.7);
  opacity: 0;
  z-index: -1;
}

.lbimg-wrap {
  width: 100%;
  height: 100%;
  padding: 47px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  position: relative;
  text-align: center;
}

.customlightbox img {
  border-color: rgba(255, 255, 255, .5);
  width: auto;
  margin: auto;
  max-width: 100%;
  max-height: 100%;
  opacity: 0;
  position: relative;
  top: 50%;
  -webkit-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
}

#lb-controls {
  cursor: pointer;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  position: fixed;
  height: 50px;
  width: 50px;
  top: -50px;
  right: -3px;
  border-left: 1px solid;
  border-bottom: 1px solid;
  opacity: .7;
  border-color: rgba(255, 255, 255, .7) !important;
  z-index: 3;
}

#lb-close {
  display: block;
  position: absolute;
  overflow: hidden;
  height: 30px;
  width: 30px;
  right: 10px;
  top: 10px;
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
}

#lb-close:before,
#lb-close:after {
  content: '';
  display: block;
  position: absolute;
  background: white;
  -webkit-border-radius: 2px;
  -moz-border-radius: 2px;
  border-radius: 2px;
}

#lb-close:before {
  width: 2px;
  height: 0;
  top: 0;
  left: 14px;
}

#lb-close:after {
  width: 0;
  height: 2px;
  top: 14px;
  left: 0;
}

.customlightbox.target {
  opacity: 1;
  display: inline-block;
  z-index: 2;
}

.customlightbox.target img {
  opacity: 1;
}

.customlightbox.target~#lb-controls {
  top: -3px;
}

.customlightbox.target~#lb-controls #lb-close:after {
  width: 30px;
}

.customlightbox.target~#lb-controls #lb-close:before {
  height: 30px;
}

.lb-animate {
  -webkit-transition: 0.5s ease-in-out;
  -o-transition: 0.5s ease-in-out;
  transition: 0.5s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>

  <p class="content">
    Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll.
  </p>

  <div class="img-wrap">
    <a class="lbimg">
      <img class="lb-click" src="https://78.media.tumblr.com/8b1b8cbb2b963ab64eb2341f608638bf/tumblr_p4wbo7ZLJS1qccr26o1_1280.jpg">
    </a>
    <div class="customlightbox lb-animate" id="lb-view">
      <div class="lbimg-wrap">
        <img class="lb-animate" id="lbimg-open" src="https://78.media.tumblr.com/8b1b8cbb2b963ab64eb2341f608638bf/tumblr_p4wbo7ZLJS1qccr26o1_1280.jpg">
      </div>
    </div>
    <div id="lb-controls" class="lb-animate">
      <a id="lb-close" class="lb-animate"></a>
    </div>
  </div>

  <p class="content">
    Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content
    to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll. Content to scroll.
  </p>

</body>