【问题标题】:How to keep <li> elements fixed top and bottom of <ul> element when scrolling滚动时如何保持 <li> 元素固定在 <ul> 元素的顶部和底部
【发布时间】:2016-03-26 22:57:59
【问题描述】:

我有一个固定高度的ul,如果滚动条出现太多,它包含动态数量的li 元素。您可以通过单击选择li元素。

我想要的是li元素,如果在其上方滚动,则活动固定在顶部,如果在其下方滚动,则固定在底部,因此始终显示活动的li元素,而另一个@987654327 @ 元素只是滚动过去的活动元素。

我做了一个plunker。我正在使用 Angular,我不知道这是否可以仅使用 CSS 来解决,或者我是否需要一个指令等。

HTML:

div class="parent">
 <div class="child1">
   <input ng-model="vm.query" type="text" placeholder="Search" />
    <ul  >
        <li ng-repeat="todo in  todos" ng-class="{'active': todo.active}" ng-click="activeTodo($index)">
            <a>{{todo.name}}</a>
        </li>

    </ul>
 </div>

CSS:

.parent{
   display: flex;
}
.child1{

  background-color: #eeeeee;
  height: 500px;
  overflow:scroll;
}
.active{
 background-color: red;
 position:fixed;
}

提前致谢!

【问题讨论】:

  • 这不能仅通过 CSS 实现。逻辑非常简单,真的:在父滚动检查活动元素的位置并确定它是否在视图中。如果不是,请将其位置更改为固定(顶部或底部)并(最终)在父级上设置顶部/底部填充。您希望我们为您编码吗?如果是,请说明理由。最好是一个好的。

标签: javascript html css angularjs angularjs-directive


【解决方案1】:

使用纯 CSS 的考虑:最好的解决方案之一就是这样,因为那些可能想要使元素在 滚动时保持固定的人上下!

body {
  margin: 10px;
}

ul {
  display: block;
  width: 210px;
  max-height: 120px;
  overflow-y: auto;
  margin: 0;
  padding: 0;
}

li {
  padding: 8px 10px;
  display: block;
  font-size: 13px;
  cursor: pointer;
  background-color: #ddd;
}

li.fixed {
  position: -webkit-sticky;
  position: sticky;
  bottom: 0;
  background-color: #111;
  color: #f2f2f2;
}
<ul>
  <li>Item1</li>
  <li>Item2</li>
  <li>Item3</li>
  <li>Item4</li>
  <li>Item5</li>
  <li>Item6</li>
  <li>Item7</li>
  <li>Item8</li>
  <li>Item9</li>
  <li>Item10</li>
  <li>Item11</li>
  <li>Item12</li>
  <li>Item13</li>
  <li>Item14</li>
  <li>Item15</li>
  <li>Item16</li>
  <li>Item17</li>
  <li>Item18</li>
  <li>Item19</li>
  <li>Item20</li>
  <li>Item21</li>
  <li>Item22</li>
  <li>Item23</li>
  <li>Item24</li>
  <li>Item25</li>
  <li>Item26</li>
  <li>Item27</li>
  <li>Item28</li>
  <li>Item29</li>
  <li>Item30</li>
  <li>Item31</li>
  <li>Item32</li>
  <li>Item33</li>
  <li>Item34</li>
  <li>Item35</li>
  <li>Item36</li>
  <li>Item37</li>
  <li>Item38</li>
  <li>Item39</li>
  <li>Item40</li>
  <li>Item41</li>
  <li>Item42</li>
  <li>Item43</li>
  <li>Item44</li>
  <li>Item45</li>
  <li>Item46</li>
  <li>Item47</li>
  <li>Item48</li>
  <li>Item49</li>
  <li>Item50</li>
  <li class="fixed">HEADER</li>
</ul>

【讨论】:

    【解决方案2】:

    我使用一些 CSS 并制定了指令来管理它。

    做了一个傻瓜here

    我做了一个指令,每个li 元素都得到了。然后在指令中使用 jquery,我得到了必要的元素,例如具有滚动条的 div、当前的 li 元素等。

    两个布尔值用于检查li 是固定在顶部还是底部。然后只需检查当前的 scrollPosition(scrollTop) 是高于还是低于当前的 li 元素。它还会检查li 元素是否也附加了活动布尔值。

    return {
            restrict: 'A',
    
            link: function($scope, element, attributes){
    
                var scrollDiv = $('#scrollDiv'),
                    liElement = element,
                    liElementTop = parseInt(liElement.offset().top),
                    scrollDivTop = parseInt(scrollDiv.offset().top),
                    isFixedTop = false,
                    isFixedBottom = false;
    
                liElement.width(scrollDiv.width());
    
    
                scrollDiv.on('scroll', function(){
                    var scrollTop = scrollDiv.scrollTop();
    
                    if (!isFixedBottom && !isFixedTop && scrollTop <= liElementTop - (scrollDivTop+(scrollDiv.height()-liElement.height())) && liElement.hasClass("active")) {
                        isFixedBottom = true;
                        liElement.css({'position': 'fixed', 'top': scrollDivTop+(scrollDiv.height()-liElement.height()+1),'list-style-type':'none','z-index':'10'});
                    } else if (isFixedBottom && !isFixedTop && scrollTop >= liElementTop - (scrollDivTop+(scrollDiv.height()-liElement.height()))) {
                        isFixedBottom = false;
                        liElement.css({'position': 'static', 'top': 0});
                    }
                    else if (!isFixedTop && !isFixedBottom && scrollTop >= liElementTop - scrollDivTop && liElement.hasClass("active")) {
                        isFixedTop = true;
                        liElement.css({'position': 'fixed', 'top': scrollDivTop,'list-style-type':'none','z-index':'10'});
                    }
                    else if (isFixedTop && !isFixedBottom && scrollTop <= liElementTop - scrollDivTop) {
                        isFixedTop = false;
                        liElement.css({'position': 'static', 'top': 0});
                    }
    
                })
    
    
    
            }
        };
    

    【讨论】:

      【解决方案3】:

      如果我理解正确,您喜欢顶部的活动 div。

      用css解决这个问题

      在父元素上使用position:relative,在子元素上使用position:absolutetop:0

      【讨论】:

      • 这样做会使活动的 li 始终出现在顶部。 Gustav Olsson 只希望它在溢出时位于顶部/底部
      猜你喜欢
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      • 1970-01-01
      • 2011-08-13
      相关资源
      最近更新 更多