Getting element coordinates on page scroll

I have this problem when I have a set of 6 UL having a common class x. Each of them consists of a specific section of the page. Now I have 6 menus that are associated with each section. you need to do this by highlighting the menu when its associated section is in the users view. For this, I thought there might be jQuery position (); or offset (); might help, but they give the top and left of the element. I also tried using jQuery viewport , but apparently the port view is large, it can display more than one UL at a time, so I cannot apply the specific logic of the element here. I am not familiar with this, but does something change the element when scrolling? If so, how do I access it?

Share your opinions.

Relations Himanshu Sharma.

+6
source share
3 answers

It is very easy to do this with jQuery and a fictitious fixed HTML block to help you find the current position of the viewport.

$(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; } }); }) 

See a working example: http://jsfiddle.net/6c8Az/1/


You can also do something similar with the jQuery plugin along with the : first selector:

 $(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') }); }) 
+5
source
  • You can get the width and height of the viewport using $(document).width() and $(document).height()
  • You can get how many pixels the user scrolls through $(document).scrollTop() and $(document).scrollLeft
  • Combining 1 and 2 , you can calculate where the rectangle of the viewport
  • You can get the rectangle of an element using $(element).offset() , $(element).width() and $(element).height()
  • So, you just have to determine whether the rectangle of the viewport (or interacts) with the rectangle of elements

So the whole code might look like this:

 /** * 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); 
0
source

Let's see if I understand well. You have a page long enough to scroll, and there is an element that, when it appears in the viewport, you want to do something with it. Thus, the only event that is triggered for sure at the moment when the element falls into the viewport is "scrolling". Therefore, if the item is on the page and the scroll is in the viewport, then you need to associate the action with the scroll event to check if the item is in the view every time the event is fired. Mostly like this:

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

Now, to find out if an item is in the viewport, you need 3 things. The offset of the top of this item, the size of the viewport, and the top of the scroll window. It 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 position of the element if there was no scrolling. Thus, you just need to check if the top of the element’s offset is above the window viewer to see if it has a view or not. Finally, you can be more accurate in your calculations by adding the height of the element (the variable is already there), because just the code that I just made will fire an event, even if the element is visible only by 1 pixel.

Note. I did it in five minutes, so you may have to fix some of this, but it gives you a good idea of ​​what is going on;)

Feel free to comment and ask questions.

0
source

Source: https://habr.com/ru/post/911472/


All Articles