如果超出视口,如何移动绝对定位元素?

时间:2017-09-20 11:27:26

标签: javascript jquery html css css3

我有很多不同宽度的盒子。所有这些都显示为inline-block,因此随着窗口宽度的变化,它们将以不同的方式分布。

每个方框都有一个很大的工具提示,会在悬停时显示。这些工具提示具有固定的宽度和高度,所有框都相同。

这些工具提示在框上方为position:absolute,并以:

为中心
left: 50%;
margin-left: -halfwidth; 

我的问题是,如果盒子靠近窗口向左或向右,它们将被部分隐藏(我没有顶部和底部的问题,它们永远不会到达那些边缘)

有没有简单的方法用javascript(更好的是jquery)来检测元素何时不在视口中,然后相应地更改left属性以防止它?

任何帮助,提示或评论都会大大减少。谢谢

JSFIDDLE

html, body {margin:0;padding:0;height:100%;}
ul {
  width:100%; 
  text-align:center;
  position:relative;
  top:50%;
  transform:translateY(-50%);
  padding:0;
  }
li {
  display: inline-block;
  background-color: red;
  width: 100px;
  height: 25px;
  margin-right: 10px;
  position: relative;
}

.hover-element {
  position: absolute;
  background-color: yellow;
  z-index: 9999;
  width: 350px;
  height: 175px;
  left: 50%;
  margin-left: -175px;
  bottom:25px;
  display: none;
  border:1px solid #000;
}

li:hover .hover-element {
  display: block;
}
.hover-element:hover {
  visibility: hidden;
}
<ul>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
</ul>

5 个答案:

答案 0 :(得分:3)

这就是你所需要的,我检测到div的偏移左侧位置,并将类添加到li并在CSS中进行了一些小调整。

$("li").mouseenter(function(){
 var f = $(this).find('.hover-element');
    var rightEdge = f.width() + f.offset().left;
    var leftEdge = f.offset().left;
    var screenWidth = $(window).width();
    if(leftEdge < 0){
    $(this).addClass("left");
    $(this).removeClass("right");
    }
    else if(rightEdge > screenWidth){
    $(this).addClass("right");
    $(this).removeClass("left");
    }
    else{
    $(this).removeClass("right lefft");
    }


});

$("li").mouseleave(function(){
$(this).removeClass("right lefft");
}) 
html, body {margin:0;padding:0;height:100%;}
ul {
  width:100%; 
  text-align:center;
  position:relative;
  top:50%;
  transform:translateY(-50%);
  padding:0;
  }
li {
  display: inline-block;
  background-color: red;
  width: 100px;
  height: 25px;
  margin-right: 10px;
  position: relative;
}

.hover-element {
  position: absolute;
  background-color: yellow;
  z-index: 9999;
  width: 350px;
  height: 175px;
  left: 50%;
  margin-left: -175px;
  bottom:25px;
  display: none;
  border:1px solid #000;
}
li.left .hover-element{
    left: 0;
    margin-left: 0;
}
li.right .hover-element{
    margin-left: 0;
    left: auto;
    right: 0;
}
li:hover .hover-element {
  display: block;
}
.hover-element:hover {
  visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
</ul>

答案 1 :(得分:2)

看看:

&#13;
&#13;
var windowWidth = document.body.scrollWidth || window.innerWidth;
$('li').on('mouseenter', function(e){
  var $hover = $(this).find('.hover-element');
  var coords = $hover[0] && $hover[0].getBoundingClientRect();
  var rightDistance = 0;
  
  if (coords.left <= 0) {
    $hover.css({
      'left': ($hover.css('left').split('px')[0] - coords.left) + 'px'
    })
  }
  rightDistance = windowWidth - coords.left - $hover.width() - 2 * $hover.css('borderWidth').split('px')[0];
  if (rightDistance < 0) {
    $hover.css({
      'left': ($hover.css('left').split('px')[0] - (-rightDistance)) + 'px'
    })
  }
  $('p').html($hover.css('left') + '/' + coords.left)
})
&#13;
html, body {margin:0;padding:0;height:100%;overflow-x: hidden;}
ul {
  width:100%; 
  text-align:center;
  position:relative;
  top:50%;
  transform:translateY(-50%);
  padding:0;
  }
li {
  display: inline-block;
  background-color: red;
  width: 100px;
  height: 25px;
  margin-right: 10px;
  position: relative;
}

.hover-element {
  position: absolute;
  background-color: yellow;
  z-index: 9999;
  width: 350px;
  height: 175px;
  left: 50%;
  margin-left: -175px;
  bottom:25px;
  display: none;
  border:1px solid #000;
}

li:hover .hover-element {
  display: block;
}
.hover-element:hover {
  visibility: hidden;
}
&#13;
<script
  src="https://code.jquery.com/jquery-2.2.4.min.js"
  integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
  crossorigin="anonymous"></script>
<ul>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
  <li>
    <div class="hover-element"></div>
  </li>
</ul>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

以下链接是您问题的起点(如果不是实际答案)。

  

有没有简单的方法用javascript(更好的是jquery)来检测元素何时离开视口然后相应地更改左属性以防止它?

How to tell if a DOM element is visible in the current viewport?

Absolute position of an element on the screen using jQuery

答案 3 :(得分:1)

我要提到这里的步骤。如果您需要代码,只需要它。我目前在移动设备上,因此输入代码会变得很难!

的步骤

  • 为了简化包含JS,请使用JS更改display属性。使用每个列表项上的鼠标事件来完成此操作,这会更改其各自的工具提示的显示属性。 (Here's如何访问相应的孩子)

在同一个悬停事件中,请执行以下操作:

  • 更改显示后,检查工具提示元素是否在视口中。您可以参考Victor Medeiros提供的链接。

  • 如果未完全在视口中,将margin-left属性更改为-175px - (the number of pixels it crossed the boundary by)我刚刚意识到,如果它穿过视口,只需设置margin-left或margin-right(如果适用,由getBoundingClientRect找到)为0。

是的,就是这样!我希望这应该有效,我还没试过。结果是什么?

答案 4 :(得分:-3)

更改

li {
    display: inline-block;
    background-color: red;
    width: 100px;
    height: 25px;
    margin-right: 10px;
    position: relative;
}

惠特

li {
    display: inline-block;
    background-color: red;
    width: 100px;
    height: 25px;
    margin-right: 10px;
    position: static;
}