Created
June 19, 2019 10:57
-
-
Save dewdad/8e7f9a1db79cee4b9b3b6e882eb97ba5 to your computer and use it in GitHub Desktop.
Finding element intersection and position in DOM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This function is useful for getting first and last elements inside a container given a y offset such as top and bottom of visible area. | |
* One way to mark the top and bottom of a container is to add 2 markers divs like so | |
* <section class="container"> | |
* <div class="fixed-top-marker" style="position: fixed; top: 0" /> | |
* ... | |
* <div class="fixed-bottom-marker" style="position: fixed; bottom: 0" /> | |
* </section> | |
* | |
* then to query bottom use: | |
* document.querySelector('#meeting-scroll-container .fixed-bottom-marker').getBoundingClientRect().bottom | |
* | |
* @param {number} yCoord - The y coord you want search proximity to, e.g: top/bottom of scroll container of elements collection | |
* @param {string | NodeList} elements - The elements you want to search for proximity to yCoord | |
* @param {('top'|'bottom')} yEdgeCompare - Compare yCoord to top or bottom of element collection | |
* @param {('top'|'bottom'|'')} [searchFrom=''] - Start the search from bottom or top of element collection | |
* @param {boolean} [stopSearchAfterDistanceGrows] - If the collection is sorted and direction is set the function will execute faster given | |
*/ | |
function getElEdgeNearestToY (yCoord, elements, yEdgeCompare, searchFrom='', stopSearchAfterDistanceGrows = searchFrom? true : false) { | |
let items = typeof(elements) === 'string'? document.querySelector(elements) : elements; | |
if(!items) return null; | |
let isSearchFromBottom = searchFrom === 'bottom'; | |
// search from top or bottom by given searchDirection | |
if(isSearchFromBottom) items = Array.from(items).reverse(); | |
let nearestToYItem = null; | |
let nearestToYCoord = Infinity; | |
for (let len = items.length, i = 0; i < len; i++) { | |
const itemOffsetFromY = Math.abs( | |
items[i].getBoundingClientRect()[yEdgeCompare] - yCoord | |
); | |
if (itemOffsetFromY < nearestToYCoord) { | |
nearestToYCoord = itemOffsetFromY; | |
nearestToYItem = items[i]; | |
} else if(stopSearchAfterDistanceGrows){ | |
break; | |
} | |
} | |
return nearestToYItem | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This function is useful for getting first and last elements inside a container given a y offset such as top and bottom of visible area. | |
* One way to mark the top and bottom of a container is to add 2 markers divs like so | |
* <section class="container"> | |
* <div class="fixed-top-marker" style="position: fixed; top: 0" /> | |
* ... | |
* <div class="fixed-bottom-marker" style="position: fixed; bottom: 0" /> | |
* </section> | |
* | |
* then to query bottom use: | |
* document.querySelector('#meeting-scroll-container .fixed-bottom-marker').getBoundingClientRect().bottom | |
* | |
* @param {number} yCoord - The y coord you want search intesection with, e.g: top/bottom of scroll container of elements collection | |
* @param {string | NodeList} elements - The elements you want to search for which intersects yCoord | |
* @param {('top'|'bottom')} [searchFrom='top'] - Start the search from bottom or top of element collection | |
* @return {HTMLElement} The Element on yCoord | |
*/ | |
window.getElOnY = function getElOnY(yCoord, elements, searchFrom = 'top', yCoordOffset = 0, margin = 0) { | |
let items = typeof (elements) === 'string' ? document.querySelectorAll(elements) : elements; | |
if (!items) return null; | |
let isSearchFromBottom = searchFrom === 'bottom'; | |
// search from top or bottom by given searchDirection | |
if (isSearchFromBottom) items = Array.from(items).reverse(); | |
yCoord += isSearchFromBottom ? -yCoordOffset : yCoordOffset; | |
let onYItem = null; | |
for (let len = items.length, i = 0; i < len; i++) { | |
const elRect = items[i].getBoundingClientRect(); | |
if (elRect.top - margin <= yCoord && yCoord <= elRect.bottom + margin) { | |
onYItem = items[i]; | |
break; | |
} | |
} | |
return onYItem | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment