jQuery中心div在父div的可见区域

时间:2016-08-25 17:12:56

标签: javascript jquery html

我有GET /pinning/{type}我试图垂直居中于其父<div>的可见区域。 Here是一个例证我想要完成的事情的图像。子<div>由白色圆圈表示,父<div>为灰色矩形,白色矩形为浏览器的视口。

我遇到的问题是在浏览器滚动或调整大小时编写用于定位子<div>的公式。适用于任何规模的儿童或父母<div>

Center div in visible area of parent examples

<div>

Fiddle

1 个答案:

答案 0 :(得分:0)

我找到了解决方案,可在此处找到一个工作示例https://jsfiddle.net/uzbyy7dw/6/

几乎所有原始计算都被废弃了。我的新方法是确定父<div>的上边缘是否在浏览器的视口之外,然后根据父级的底边是否在视口之外来计算子<div>的垂直中心位置。

请注意,儿童<div>在父<div>

中具有绝对位置

(function($){
var scrollListener = function(){
    $('.child').each(function(){
    var child = $(this),            // child div element
    w=$(window).height(),           // window height
    s=$(window).scrollTop(),        // window scrollTop position
    t=child.parent().offset().top,  // parent top edge
    h=child.parent().height(),      // parent height
    r=(w+s-t),                      // parent's initial visible area
    // parent's bottom edge in relation to the viewport
    // calculated by the parent's height minus it's initial visible area
    b=h-r,                          
    v=0;                            // final value for child position
    if( t<s ){
       /*
       The amount scrolled is greater than the parent's offset
       thus, the parent's top edge is outside the viewport
       */
       if( 0 < b ){
       	    /*
            When the parent's bottom edge is greater than 0 then
            it's bottom edge is below the bottom of the viewport
            
            Since both the top and bottom edge exceed the viewport 
            some middle section of the parent is spanning the
            full height of the viewport.  The child's position will be
            in the middle of viewport, but offset by the amount
            scrolled minus the parent's top offset
            */
            v = (w/2)+s-t;
       }else{
            /*
            The parent's top edge is outside the viewport, but the
            bottom edge is within the viewport
            
            Calculate the middle position by taking the amount scrolled
            minus the parent's offset and the parent's height, which
            will get the remaining visible area of the parent div, then
            divide by two to get the middle
            */
            v = (s-t+h)/2;
       }
    }else{
        /*
        The parent's top edge is greater than the amount scrolled
        thus, the parent top edge has not exceeded the viewport
        */
    	if( 0 < b ){
      	    /*
            When the parent's bottom edge is greater than 0 then
            it is below the bottom of the viewport
            
            Since the parent's top edge has not exceeded the viewport
            and bottom edge HAS exceed the viewport, use the parent's
            initial position determined by adding the window's height
            and the amount scrolled then subtract the parent's offset.
            
            Divide this position by two to get the middle of the
            parent's visible area, unless the parent's top edge is
            below the viewport's bottom edge then the parent is out of
            view and the child will be too
            */
            v = r/2;
        }else{
      	    /*
            Both the top and bottom edges of the parent div are within
            the viewport.  Vertically center the child div within the
            parent by dividing the parent's height by 2 to get its
            middle
            */
            v = h/2;
      }
    }
    
    child.css("top",v);
    });
};

$(window).on("scroll resize",scrollListener);
scrollListener();
})(jQuery);
html,body { background:white; height:100%; }
body{ margin-top:140%; }
.middle-line {
  position:fixed;
  top:50%;
  width:100%;
  z-index:100;
  border-top:1px solid #2495ec;
}
.parent1, .parent2 {
  float:left;
  width:30%;
  margin-left:10px;
  position:relative;
}

.parent1 {
  background:#ccc;
  height:120%;
  margin-top:-50px;
  }
.parent2 {
  background:#aaa;
  height:50%;
}
.child {
  background:#000;
  color:#fff;
  line-height:50px;
  text-align:center;
  position:absolute;
  height:50px;
  width:50px;
  left:50%;
  transform:translate(-50%,-50%);
}
.other-stuff{
  height:800px;
  clear:both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="parent1">
<div class="child"></div>
</div>
<div class="parent2">
<div class="child"></div>
</div>
<div class="other-stuff"></div>
<div class="middle-line"></div>