什么元素在中心?

What element is on the center?

有一个由 ng-repeat 制作的列表,其中有很多行。

 <ul ng-repeat="element in elements |  filter:filterQuery">
    <a class="row" >
        <div class="col-lg-8">
            <div class="caption">
                <h4>{{element.artists[0].name}}</h4>
            </div>
        </div>
    </a>
</ul>

我想找出哪个元素(垂直)在屏幕中央。

你能帮我吗?我是 Angular 的新人。 我相信这个问题类似于无限滚动。但不是找到最后一个元素,而是需要在中心找到元素

我不知道怎么工作Angular 但是要获得中间元素,您应该尝试类似的方法。

计算元素长度。 将结果一分为二。

你得到了位于中心的元素。 如果你有类似 2.5 的东西,请随意将目标定为之前或之后的一个。

嘿,我创造了 fiddle http://jsfiddle.net/uwk46bky/1/ 可能有帮助:-)

<div ng-init="elements=['1','2','3','4','5']">
  <ul ng-repeat="element in  elements">
    <a class="row" >
        <div class="col-lg-8">
            <div class="caption">
                <h4 ng-class="{'check':($index+0.5)==(elements.length/2)}">{{element}}</h4>
            </div>
        </div>
    </a>
</ul>
</div>

CSS:-

.check{
 background-color:red;   
}

这是一种可能的解决方案,也是我自己可能会采用的解决方案:

  1. 创建指令,将所有代码放入post link函数中。
  2. 存储window垂直中心坐标。
  3. 在任何列表父元素上添加 scroll 事件侦听器。
  4. 使用Document.elementFromPoint()找到当前最中心的元素。
  5. 为其分配活动 class,从之前的活动中移除。

你也不应该忘记维护正确的指令生命周期。这意味着删除事件侦听器并取消引用 DOM 节点以防止内存泄漏。

指令:

.directive("highlightCentermost", function ($window, $document, $timeout) {
  return function postLink (scope, el) {
    // References are kept here
    var center, centermost

    // Find and update centermost element
    function probe () {
      var newCentermost = $document[0].elementFromPoint(0, center)
      // No centermost assigned yet
      if (!centermost) {
        centermost = newCentermost
        centermost.classList.toggle("active", true)
        return
      }
      // Found another element
      if (centermost !== newCentermost) {
        // Remove class from old element
        centermost.classList.toggle("active", false)
        // Add class to new element
        newCentermost.classList.toggle("active", true)
        // Update the reference
        centermost = newCentermost
      } else if (!newCentermost && centermost) {
        // Cleanup if nothing was found
        centermost.classList.toggle("active", false)
        centermost = null
      }
    }

    function resize () {
      center = $window.innerHeight / 2
    }

    resize()
    // $timeout is required to wait until all element directives are applied
    $timeout(probe)
    $window.addEventListener("scroll", probe)
    $window.addEventListener("resize", resize)

    scope.$on("$destroy", function cleanup () {
      $window.removeEventListener("scroll", probe)
      $window.removeEventListener("resize", resize)
      centermost = null
    })
  }
})

Full example at JSBin.

优点:

  1. 您不需要知道集合大小。
  2. 无需检查每个 DOM 节点的位置。
  3. 每个卷轴只有一个 DOM 操作。

缺点:

  1. 您必须对列表项进行微观管理。弹出窗口叠加可能会带来更多的复杂性,具体取决于滚动的内容。

请注意,这是非常基本的版本,您可能想要改进计算垂直中心和元素探测的功能(比如探测两个点而不是一个点)。我在我的一个应用程序中使用了类似的方法来实现 display:sticky 模拟,因此它非常灵活。

我可以想出更多的解决方案:

  1. 检查 scroll/animationFrame 上每个列表项的垂直位置,如果满足某些条件则更新 class。速度慢,但可以处理动态高度。
  2. 如果列表项的高度是常数,你可以编写函数来计算当前符合条件的元素 scrollTop 值。这是虚拟滚动背后的机制(仅在视口中显示项目,允许在不影响性能的情况下拥有大量项目)。