简体   繁体   English

在页面滚动上获取元素的坐标

[英]Getting Coordinates of an element on page scroll

I am having this problem where i have a set of 6 UL's having a common class x.Each of them consist of a specific section of the page.Now i have 6 menus that are related to each of the section.What i have to do is highlight the menu when its related section is in users view. 我有这个问题,我有一套6个UL有一个共同的类x。它们每个都包含一个页面的特定部分。现在我有6个与每个部分相关的菜单。我该怎么做当相关部分在用户视图中时突出显示菜单。 For this i thought that may be jQuery position(); 为此,我认为可能是jQuery position(); or offset(); offset(); could have helped but they give the top and left of the element.I also tried using jQuery viewport plugin but apparently view port is big it can show more than one UL at a time hence i cant apply element specific logic here.I am not familliar to this but does anything changes of an element on scrolling?If yes then how to access it? 可能有帮助,但他们给了元素的顶部和左侧。我也尝试使用jQuery 视口插件,但显然视图端口很大,它可以一次显示多个UL因此我不能在这里应用元素特定的逻辑。我不是familiar对此,但滚动时元素的变化是什么?如果是,那么如何访问它?

Please share your views. 请分享您的观点。

Regards Himanshu Sharma. 关心Himanshu Sharma。

Is very easy to do it using jQuery and a dummy fixed HTML block that helps you find the current position of the viewport. 使用jQuery和虚拟固定HTML块很容易做到这一点,它可以帮助您找到视口的当前位置。

$(window).on("scroll load",function(){  
    var once = true;
    $(".title").each(function(ele, index){
        if($(this).offset().top > $("#viewport_helper").offset().top && once){              
            var index = $(this).index(".title");
            $(".current").removeClass('current')        
            $("#menu li").eq(index).addClass('current')
            once = false;
        }
    });     
})

Check out a working example: http://jsfiddle.net/6c8Az/1/ 查看一个工作示例: http//jsfiddle.net/6c8Az/1/


You could also do something similar with the jQuery plugin, together with the :first selector: 您还可以使用jQuery插件和第一个选择器执行类似的操作:

$(window).on("scroll load",function(){  
    $(".title:in-viewport:first").each(function(){
        var index = $(this).index(".title");
        $(".current").removeClass('current')        
        $("#menu li").eq(index).addClass('current')
    }); 
})
  1. You can get the viewport's width and height via $(document).width() and $(document).height() 您可以通过$(document).width()$(document).height()获取视口的宽度和高度。
  2. You can get how many pixels user scrolls via $(document).scrollTop() and $(document).scrollLeft 您可以通过$(document).scrollTop()$(document).scrollLeft来获取用户滚动的像素数$(document).scrollLeft
  3. Combining 1 and 2 , you can calculate where the viewport rectangle is 组合12 ,可以计算视口矩形的位置
  4. You can get the rectangle of an element using $(element).offset() , $(element).width() and $(element).height() 你可以使用$(element).offset()$(element).width()$(element).height()来获取元素的矩形。
  5. So the only thing left to you is to determine whether the viewport's rectangle contains (or interacts) the elements's rectangle 因此,您唯一要做的就是确定视口的矩形是否包含(或交互)元素的矩形

So the whole code may look like: 所以整个代码可能如下所示:

/**
 * Check wether outer contains inner
 * You can change this logic to matches what you need
 */
function rectContains(outer, inner) {
    return outer.top <= inner.top &&
        outer.bottom >= inner.bottom &&
        outer.left <= inner.left &&
        outer.right >= inner.right;
}

/**
 * Use this function to find the menu related to <ul> element
 */
function findRelatedMenu(element) {
    return $('#menu-' + element.attr('id'));
}

function whenScroll() {
    var doc = $(document);
    var elem = $(element);
    var viewportRect = {
        top: doc.scrollTop(),
        left: doc.scrollLeft(),
        width: doc.width(),
        height: doc.height()
    };
    viewportRect.bottom = viewportRect.top + viewportRect.height;
    viewportRect.right = viewportRect.left + viewportRect.width;

    var elements = $('ul.your-class');
    for (var i = 0; i < elements.length; i++) {
        var elem = $(elements[i]);
        var elementRect = {
            top: elem.offset().top,
            left: elem.offset().left,
            width: elem.width(),
            height: elem.height()
        };
        elementRect.bottom = elementRect.top + elementRect.height;
        elementRect.right = elementRect.left + elementRect.width;

        if (rectContains(viewportRect, elementRect)) {
            findRelatedMenu(elem).addClass('highlight');
        }
    }
}

$(window).on('scroll', whenScroll);

Let's see if i understood well. 让我们看看我是否理解得很好。 You have a page long enough to scroll, and there is an element that when it appears in the viewport, you wanna do something with it. 你有一个足够长的页面可以滚动,并且有一个元素,当它出现在视口中时,你想用它做一些事情。 So the only event that's is triggered for sure on the time the element gets in the viewport is the 'scroll'. 因此,元素进入视口时确定触发的唯一事件是“滚动”。 So if the element is on the page and the scroll is on the viewport, what you need to do is bind an action to the scroll event to check if the element is in the view each time the event is trigger. 因此,如果元素位于页面上且滚动位于视口上,则需要执行的操作是将操作绑定到scroll事件,以在每次触发事件时检查元素是否在视图中。 Pretty much like this: 非常像这样:

$(window).scroll(function() {
   check_element_position();
});

Now, in order for you to know if the element is in the viewport, you need 3 things. 现在,为了让您知道元素是否在视口中,您需要3件事。 The offset top of that element, the size of the viewport and the scroll top of the window. 该元素的偏移顶部,视口的大小和窗口的滚动顶部。 Should pretty much look like this: 应该看起来像这样:

function check_element_position() {
   var win = $(window);
   var window_height = win.height();
   var element = $(your_element);
   var elem_offset_top = element.offset().top;
   var elem_height = element.height();
   var win_scroll = win.scrollTop();
   var pseudo_offset = (elem_offset_top - win_scroll);
   if (pseudo_offset < window_height && pseudo_offset >= 0) {
      // element in view
   }
   else {
      // elem not in view
   }
}

Here, (elem_offset_top - win_scroll) represent the element position if there was no scroll. 这里,(elem_offset_top - win_scroll)表示没有滚动的元素位置。 Like this, you just have to check if the element offset top is higher then the window viewport to see if it's in view or not. 像这样,您只需检查元素偏移顶部是否高于窗口视口,以查看它是否在视图中。 Finally, you could be more precise on you calculations by adding the element height (variable already in there) because the code i just did will fire the event even if the element is visible by only 1 pixels. 最后,通过添加元素高度(已存在的变量),您可以更准确地计算您的计算,因为我刚刚执行的代码将触发事件,即使该元素仅可见1个像素。

Note: I just did that in five minutes so you might have to fix some of this, but this gives you a pretty darn good idea of what's going on ;) 注意:我刚刚在五分钟内完成了这项工作,因此您可能需要修复其中一些内容,但这会让您对正在发生的事情有一个很好的了解;)

Feel free to comment and ask questions 随意发表评论并提出问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM