CSS定位2格-滚动到较短的格的末尾

时间:2018-06-24 09:40:52

标签: javascript jquery html css

我在定位2个div时遇到问题-我不知道哪一个会更长。当我的 #rightcontent div长于 #leftcontent 时,我希望看到 #leftcontent 中的内容结尾停留在屏幕底部,就像这样图片:

screenshot

这是一个代码段:

for(var i=6000;i--;){
	$('#rightcontent').append(i+ ' ');
	$('#leftcontent').append("i ");
}
@font-face {
    font-family: Gill Sans MT;
    src: url("Gill Sans MT.ttf");
}

body{
	margin-top: 0px;
	margin-left: 0px;
	margin-right: 0px;
  margin-bottom: 0px;
}

#header{
	position: fixed;
	text-align: center;
	font-size: 32px;
	background: #f4f4e6;
	padding-top: 2px;
	min-width: 100%;
	min-height: 28px;
}
#content{	
	padding-top: 38px;
	text-align: center;
}
#footer{
	position: fixed;
	text-align: center;
	background: #f4f4e6;
	min-width: 100%;
	font-style: italic;
	font-family: Gill Sans MT;
	letter-spacing: -1;
}
#rightcontent{
	float: right;
	max-width: 55%;
	padding-bottom: 20px;
}
#leftcontent{
	padding-bottom: 20px;
	max-width: 45%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header">
  Worki do odkurzaczy
</div>
<script>
document.write("<div id=content width=" + document.documentElement.clientWidth + "px height=" + (document.documentElement.clientHeight - 64) + "px style=padding-bottom:20px;min-height:" + (document.documentElement.clientHeight - 52) + "px; data-scroll-offset=28>");
</script>
<div id="rightcontent" name="target">
</div>

<div id="leftcontent">
</div>
</div>

<script>
  document.write("<div id=footer style=top:" + (document.documentElement.clientHeight - 22) + "px;>");
  //IDK WHY ON LOCAL TEST IS HERE -32px
</script>

后圣经》

我找到了一个安静的简单答案here,但没有得到这个颜色示例。<​​/ p>

1 个答案:

答案 0 :(得分:1)

您想要的行为是可行的,但需要对数学,数据绑定和事件侦听有一些基本了解。您基本上想要的是检查在scroll对象上触发的每个window事件,

  1. #leftcontent#rightcontent这两个元素中较短的一个,其底部触及视口的底部
  2. 如果是,则较短的元素将具有固定位置,以使其“粘贴”到视口底部
  3. 如果否,则较短的元素将不固定

可以通过添加.fixed类来完成位置固定,该类告诉浏览器在元素上使用position: fixed; bottom: 0;。现在有趣的部分是:您如何知道元素是否触及底部?诀窍很简单:

  1. 您从顶部计算视口的底部。这只是视口高度+从文档顶部开始的视口滚动。
  2. 您从顶部开始计算元素的底部。这是元素的偏移量+元素的高度。

当点#1的值大于点#2时,您知道您已滚动到元素底部之外。考虑到这一点,您只需要一些逻辑来确定两个元素中哪个是较短的:this is already covered in another StackOverflow question,因此我们可以将该逻辑重新用于我们的用途。

最后一点是,我们只想存储元素的偏移量一次:我们使用jQuery的.data()方法存储左偏移量和顶部偏移量及其高度。

以下是可以使用的代码:

function isBottom(el) { 

  // Cache element
  var $el = $(el);

  // Store element's offset and height once only
  var elOffsetTop = $el.offset().top;
  var elOffsetLeft = $el.offset().left;
  var elHeight = $el.height();
  if ($el.data('offsetTop') === void 0)
    $el.data('offsetTop', elOffsetTop);
  if ($el.data('offsetLeft') === void 0)
    $el.data('offsetLeft', elOffsetLeft);
  if ($el.data('height') === void 0)
    $el.data('height', elHeight);

  // Check if element is at bottom of viewport
  var viewportBottom = $(window).height() + $(window).scrollTop();
  var elementBottom = $el.data('offsetTop') + $el.data('height');
  return viewportBottom > elementBottom;
}

$(window).on('scroll', function() {
  // Get the shorter of the two elements
  // From: https://stackoverflow.com/a/13319029/395910
  var shortest = [].reduce.call($('#leftcontent, #rightcontent'), function(sml, cur) {
    return $(sml).height() < $(cur).height() ? sml : cur;
  });

  // If element is bottom, add the class 'fixed'
  $(shortest)
    .toggleClass('fixed', isBottom(shortest))
    .css('left', isBottom(shortest) ? $(shortest).data('offsetLeft') : 'auto');
});

请注意,我们需要分配一个left属性,因为如果右列是较短的一列,则需要知道它最初与左边的偏移量,以便position: fixed定位正确。

.fixed类非常简单:

#header {
    // Other styles
    // Add z-index so the fixed content does not overlay header
    z-index: 1;
}
.fixed {
    position: fixed;
    bottom: 0;
    z-index: 1;
}

提示:出于性能方面的考虑,您可能需要考虑对scroll处理程序回调进行限制/反跳操作。


请参见下面的概念验证示例:

for(var i=1000;i--;){
	$('#rightcontent').append(i+ ' ');
	$('#leftcontent').append("i ");
}

function isBottom(el) { 

  // Cache element
  var $el = $(el);
  
  // Store element's offset and height once only
  var elOffsetTop = $el.offset().top;
  var elOffsetLeft = $el.offset().left;
  var elHeight = $el.height();
  if ($el.data('offsetTop') === void 0)
    $el.data('offsetTop', elOffsetTop);
  if ($el.data('offsetLeft') === void 0)
    $el.data('offsetLeft', elOffsetLeft);
  if ($el.data('height') === void 0)
    $el.data('height', elHeight);
  
  // Check if element is at bottom of viewport
  var viewportBottom = $(window).height() + $(window).scrollTop();
  var elementBottom = $el.data('offsetTop') + $el.data('height');
  return viewportBottom > elementBottom;
}

$(window).on('scroll', function() {
  // Get the shorter of the two elements
  // From: https://stackoverflow.com/a/13319029/395910
  var shortest = [].reduce.call($('#leftcontent, #rightcontent'), function(sml, cur) {
    return $(sml).height() < $(cur).height() ? sml : cur;
  });
 
  // If element is bottom, add the class 'fixed'
  $(shortest)
    .toggleClass('fixed', isBottom(shortest))
    .css('left', isBottom(shortest) ? $(shortest).data('offsetLeft') : 'auto');
});
@font-face {
    font-family: Gill Sans MT;
    src: url("Gill Sans MT.ttf");
}

body{
	margin-top: 0px;
	margin-left: 0px;
	margin-right: 0px;
  margin-bottom: 0px;
}

#header{
	position: fixed;
	text-align: center;
	font-size: 32px;
	background: #f4f4e6;
	padding-top: 2px;
	min-width: 100%;
	min-height: 28px;
  z-index: 2;
}
#content{	
	padding-top: 38px;
	text-align: center;
}
#footer{
	position: fixed;
	text-align: center;
	background: #f4f4e6;
	min-width: 100%;
	font-style: italic;
	font-family: Gill Sans MT;
	letter-spacing: -1;
}
#rightcontent{
	float: right;
	max-width: 55%;
	padding-bottom: 20px;
}
#leftcontent{
	padding-bottom: 20px;
	max-width: 45%;
}

.fixed {
  position: fixed;
  bottom: 0;
  z-index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header">
  Worki do odkurzaczy
</div>
<script>
document.write("<div id=content width=" + document.documentElement.clientWidth + "px height=" + (document.documentElement.clientHeight - 64) + "px style=padding-bottom:20px;min-height:" + (document.documentElement.clientHeight - 52) + "px; data-scroll-offset=28>");
</script>
<div id="rightcontent" name="target">
</div>

<div id="leftcontent">
</div>

<script>
  document.write("<div id=footer style=top:" + (document.documentElement.clientHeight - 22) + "px;>");
  //IDK WHY ON LOCAL TEST IS HERE -32px
</script>