【问题标题】:How to Make a Fixed Element Stay Relative to the Current Top Scroll Position?如何使固定元素保持相对于当前顶部滚动位置?
【发布时间】:2018-03-04 22:11:53
【问题描述】:

原问题:

我有一个函数可以在提示时打开一个覆盖的 fixed-positioned 元素,我试图弄清楚如何能够在当前 top 位置打开它,而不是跳到顶部每次.no-scroll 类处于活动状态时,页面 (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 类:

html {
  height: initial;
}

body {
  height: auto;
}

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

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

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

  1. html 标签上不需要no-scroll 类。因此,它被删除了。
  2. 我在touchmove 触摸事件中添加了preventDefault(),它可以防止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>

【问题讨论】:

  • @KoshVery 好的,我刚刚在我的原始帖子中提供了一个 sn-p。
  • “要滚动的内容”段落之间有一个图像。这样可以观察到位置跳跃。

标签: javascript jquery position fixed


【解决方案1】:

你快到了:

$(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>

【讨论】:

  • 谢谢!这看起来不错。 #lb-controls 没有关闭窗口有什么原因吗?
  • 太好了,确实全部修复了!最后一个问题由您来回答...这是否兼容移动浏览器,例如 Safari iOS?
  • 实际上,当我在 Safari iOS 浏览器中打开它时,body.no-scroll 类是可滚动的。有什么办法可以限制吗?
  • 不要介意额外的 cmets,我应该将它们包含在我原来的问题中。所以我确保将其标记为解决方案。谢谢!
  • @nrweb,抱歉,我无法在 iOS Safari 中重现它。它不滚动,而只是过度滚动。要摆脱过度滚动效果,请将-webkit-overflow-scrolling:auto 添加到.no-scroll
猜你喜欢
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多