如何在jQuery中获取屏幕上的可见元素对象?

47 html javascript css jquery dom

我在DOM中有一个对象列表,它比屏幕高度区域长.

我需要检测屏幕上的可见对象,只是为了制作类似时间轴树视图的东西.(如下图所示):

在此输入图像描述

我的DOM看起来像这样:

<!-- elements visibility on screen to be DETECTED -->
<div id="elements">
    <div id="elem-1">Lorem ipsum</div>
    <div id="elem-2">Lorem ipsum</div>
    <div id="elem-3">Lorem ipsum</div>
    <div id="elem-4">Lorem ipsum</div>
    <div id="elem-5">Lorem ipsum</div>
    <div id="elem-6">Lorem ipsum</div>
    <div id="elem-7">Lorem ipsum</div>
    <div id="elem-8">Lorem ipsum</div>
</div>


<!--elements visibility on screen to be AFFECTED  -->
<ul id="timeline">
    <li view-id="elem-1">Elem-1</li>
    <li view-id="elem-2">Elem-2</li>
    <li view-id="elem-3" class="active">Elem-3</li>
    <li view-id="elem-4" class="active">Elem-4</li>
    <li view-id="elem-5" class="active">Elem-5</li>
    <li view-id="elem-6" class="active">Elem-6</li>
    <li view-id="elem-7">Elem-7</li>
    <li view-id="elem-8">Elem-8</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

我的目标是从#elements容器中检测屏幕上可见元素的ID,并将active类分配给容器中的相应元素#timeline.

我需要在Scroll事件上执行此过程.

任何想法如何实现这一目标?

zur*_*4ik 41

首先on-screen visible area被称为Viewport.

图像取自OP并在Photoshop中清理

(图像取自OP.在Photoshop中清除和编辑)


所以你需要的只是检测你的所有元素Viewport.

这可以使用jQuery的许多插件来实现,但我会在一个例子中解释你,这被称为 jQuery withinviewport

链接到源代码和文档:[withInViewport - Github]


步骤1:

下载插件并在脚本中包含jQuery框架和withinviewport插件:

<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
<script src="withinViewport.js"></script>
<script src="jquery.withinviewport.js"></script>
Run Code Online (Sandbox Code Playgroud)

.

第2步:

scroll事件初始化函数:

$(window).bind("scroll", function() {
    //your code placeholder
});
Run Code Online (Sandbox Code Playgroud)

.

第3步:

使用withinviewport选择器获取Viewport中的所有元素,并通过每个元素将类添加到#timeline容器中的相应列表项:

$("#elements > div").withinviewport().each(function() {
   $('#timeline > li[view-id="'+$(this)[0].id+'"]').addClass('active');
});
Run Code Online (Sandbox Code Playgroud)

第4步:

全部放在一起:

$(window).bind("scroll", function() {

    //clear all active class
    $('#timeline > li').removeClass('active');

    //add active class to timeline
    $("#elements > div").withinviewport().each(function() {
         $('#timeline > li[view-id="'+$(this)[0].id+'"]').addClass('active');
    });
});
Run Code Online (Sandbox Code Playgroud)

.


.

此插件还为您提供了为视口设置顶部,底部,左侧和右侧偏移的机会.

请参阅此处的演示:http://patik.com/code/within-viewport/

  • @ zur4ik,非常清楚:到目前为止,Punto只问了两个问题,你回答了两个问题(你的答案被接受了).他提供的唯一答案是你的一个问题,你接受了.巧合发生了,但这看起来有点太多了. (4认同)
  • 请解释'做它'和使用插件之间的区别?我很想知道.另请告诉我OP在哪里说我不想使用插件 (3认同)
  • 我不明白什么是错的.我有相同的内容,这只是复制/粘贴的问题.我只是在Photoshop中修改了图片.我不认为在3分钟内回答大内容是不可能的. (3认同)
  • @musefan我在不同的论坛上有相同的答案,只是复制了大部分内容.只有我拍了Punto的照片,很快就在photoshop中清理干净了. (2认同)
  • @ zur4ik:看,老实说,你和OP(假设你不是两个账户)都决定聚在一起做这篇文章.我个人对回答你自己的"问题"没有任何问题,将此作为参考点也不是问题,因为它可能对其他访问者有所帮助.我正在辩论的事情是它是重复的,我不认为这个问题应该存在因为这个原因(它也没有显示任何努力在提出之前解决问题) (2认同)