问题 计算图像的位置以跟随滚动


当用户滚动页面并在其底部有一个箭头时,我想在屏幕上从页面顶部到底部绘制一条线。我不想使用固定位置,以便它始终在同一个位置,我希望它通过确定页面长度等来指示它们在页面上的位置。

我有以下代码可以解决问题。这个问题是当我在中途向下滚动后,箭头从页面底部消失。

我尝试过这段代码的不同变体,但都没有用。有人可以帮忙吗?

//Draw dotted line on scroll - works to certain extent but scrolls off page
    $( window ).scroll(function() {
        if ( $.windowScrollTop() > 10 ) {
            var pos = $.windowScrollTop();
            var scrollHeight = $(window).innerHeight();
            var element = $('#dashes');
            $( '#line' ).css( 'height', pos - scrollHeight / 4 );
            $( '#arrow' ).css( 'top', pos - scrollHeight / 4 );
        } else {
            $( '#line' ).css( 'height', '6px' );
            $( '#arrow' ).css( 'top', '-150px' );
        }
    });

//also tried the below

    $(window).on("scroll", function() {
        var scrollHeight = $(document).height();
        var scrollPosition = $(window).height() + $(window).scrollTop();
        if ((scrollHeight - scrollPosition) / scrollHeight === 0) {
            // when scroll to bottom of the page
            alert('bottom');
        } else {
                $( '#line' ).css( 'height', $(window).scrollTop() );
                $( '#arrow' ).css( 'top', $(window).scrollTop() );      
        }
    });

1200
2018-02-27 12:54


起源

检查一下。 stackoverflow.com/questions/35111425/... - sagar43
好的,所以这使用$(this).offset();但不知道如何将其应用于我的代码 - LeeTee
你可以发布你的标记/ CSS或创建一个简化的例子,以便我们可以玩它 - Huangism


答案:


我们在这里要做的是将文档高度反映到窗口高度的元素中。所以实际的可滚动文档高度将是

    var actualScrollHeight = $(document).height() - $(window).height();
    /* This is the distance we actually scroll */

而我们的 #line 将具有最大可能的高度

    var lineMaxHeight = $(window).height() - topMargin - bottomMargin - arrowHeight;
    /* #arrow is inside #line but we positioned it outside it's height */

不反映滚动进度 #line 元素高度我们需要做的是

    var lineHeight = $(document).scrollTop() / actualScrollHeight * lineMaxHeight;
    /* Super Easy, isn't it? */

最终结果:

你不需要同时定位 #line 和 #arrow。修复 #arrow 在底部 #line 然后只是改变高度 #line 工作得很好。我加了 topMargin 和 bottomMargin 功能使屏幕调整更加自定义。

$(function(){
  var topMargin = 15, bottomMargin = 5;
  var arrowHeight = $('#arrow').height();
  var $lineElement = $('#line');
  $lineElement.height(topMargin);
  $(window).scroll(function() {
    var winHeight = $(window).height();
    var actualScrollHeight = $(document).height() - winHeight;
    var lineMaxHeight = winHeight - topMargin - bottomMargin - arrowHeight;
    var scrollTop = $(document).scrollTop();
    var lineHeight = scrollTop / actualScrollHeight * lineMaxHeight;
    $lineElement.height(topMargin + lineHeight);
  });
});
#logo {
  width: 80px;
  background-color: #53befd;
  padding: 20px;
}

#line {
  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAMCAYAAABBV8wuAAAAFklEQVR42mNgoB74OEXzPzY8sBLUAwB6PmBV1D+CIAAAAABJRU5ErkJggg==);
  position: fixed;
  top: 0px;
  right: 19px;
  z-index: 20;
  width: 3px;
}

#arrow {
  background-color: #f28323;
  height: 40px;
  width: 40px;
  position: absolute;
  bottom: -40px;
  left: -18px;
  border-radius: 20px;
  color: white;
  text-align: center;
  font-size: 32px;
  line-height: 35px;
  padding-top: 3px;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="logo">LOGO </div>
<p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p><p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p><p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p><p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p><p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p><p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p><p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p><p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p><p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p><p>  Page content go here<br /> and here<br /> and here<br /> and here<br /> and here</p>
<div id="line"><div id="arrow">V</div></div>


7
2018-03-01 17:22





你的方法看起来像是在过度思考它。我正在看HTML progress 元素转为180度视觉。然后,设置它 value 当用户滚动时,用JS动态地归属,并且该线基本上看起来像是动画下来的。

// PROGRESS INDICATOR
// Calculate height of main object and the window, set max attr of progress accordingly
var winHeight = $(window).height(),
    sectionHeight = $('#line').height(),
    progressBar = $('progress'),
    max,
    value;

// Set the maximum scrollable area
max = sectionHeight - winHeight;
progressBar.attr('max', sectionHeight);

// Set value attr of progress, changes as user scrolls
$(document).on('scroll', function(){
  value = $(window).scrollTop();
  progressBar.attr('value', value);
});

progress元素的CSS看起来像这样,你将栏放在页面上作为一个固定元素,并动画它以逐步覆盖上面JS的页面。

CSS示例:

progress {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-color: transparent;
  border: none; //firefox fix
  color: green;
  height: 2.5rem;
  margin-top: 20vw;
  position: fixed;
  top: 8rem;
  width: 100vh;

  @media (min-width: 768px) and (max-width: 1200px) {
    display: block;
    transform: rotate(90deg) translateY(1800%);
  }

  @media (min-width: 1200px) {
    display: block;
    transform: rotate(90deg) translateY(1200%); // matches content shift to smaller column
  }
}

我建造了 这在我的一个客户端网站上 如果你想看看是否在野外工作(只能在大约1000px和更高的工作,所以要确保你的窗口足够宽)。


3
2018-03-01 16:44



一个很好的解决方案,但上面的代码更容易使用。谢谢 - LeeTee


使用较少的代码,这是一个更简单的解决方案:

$(function() {
  $(window).scroll(function() {
    var p = ($('body').height() - $(window).height()) / ($(window).height() - 43);
    var scrollTop = $(document).scrollTop() / p;
    $(':root').css('--scroll-top', scrollTop + 43 + "px");
  });
});
:root {
  --scroll-top: 43px;
}

#logo {
  width: 80px;
  background-color: #53befd;
  padding: 20px;
}

.content {
  height: 210vh;
  background: red;
  margin-right: 50px;
}

#line:before {
  content: "V";
  background-color: #f28323;
  height: 40px;
  width: 40px;
  display: inline-block;
  position: absolute;
  right: 0;
  bottom: 0;
  border-radius: 20px;
  color: white;
  text-align: center;
  font-size: 32px;
  line-height: 35px;
  padding-top: 3px;
  cursor: pointer;
}

#line {
  position: fixed;
  top: 0;
  right: 0;
  height: var(--scroll-top);
  width: 40px;
  background: linear-gradient(to bottom, #f28323 50%, transparent 50%) 50% 0/3px 12px repeat-y;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div id="logo">LOGO </div>
<div class="content"></div>

<div id="line"></div>


3
2018-03-02 09:14