@@ -169,7 +169,7 @@ const get_parents = (el) => {
169169/**
170170 * Return the value of the first attribute found in the list of parents.
171171 *
172- * @param {DOM element } el - The DOM element to start the acquisition search for the given attribute.
172+ * @param {Node } el - The DOM element to start the acquisition search for the given attribute.
173173 * @param {string } attribute - Name of the attribute to search for.
174174 * @param {Boolean } include_empty - Also return empty values.
175175 * @param {Boolean } include_all - Return a list of attribute values found in all parents.
@@ -245,7 +245,7 @@ function get_css_value(el, property, as_pixels = false, as_float = false) {
245245 * @param {String } [direction=] - Not given: Search for any scrollable element up in the DOM tree.
246246 * ``x``: Search for a horizontally scrollable element.
247247 * ``y``: Search for a vertically scrollable element.
248- * @param {(DOM Node|null) } [fallback=document.body] - Fallback, if no scroll container can be found.
248+ * @param {(Node|null) } [fallback=document.body] - Fallback, if no scroll container can be found.
249249 * The default is to use document.body.
250250 *
251251 * @returns {Node } - Return the first scrollable element.
@@ -270,6 +270,38 @@ const find_scroll_container = (el, direction, fallback = document.body) => {
270270 return fallback ;
271271} ;
272272
273+ /**
274+ * Get the horizontal scroll position.
275+ *
276+ * @param {Node } scroll_reference - The element to get the scroll position from.
277+ *
278+ * @returns {number } The horizontal scroll position.
279+ */
280+ const get_scroll_x = ( scroll_reference ) => {
281+ // scroll_listener == window: window.scrollX
282+ // scroll_listener == html: html.scrollLeft == window.scrollX
283+ // scroll_listener == DOM node: node.scrollLeft
284+ return typeof scroll_reference . scrollLeft !== "undefined"
285+ ? scroll_reference . scrollLeft
286+ : scroll_reference . scrollX ;
287+ } ;
288+
289+ /**
290+ * Get the vertical scroll position.
291+ *
292+ * @param {Node } scroll_reference - The element to get the scroll position from.
293+ *
294+ * @returns {number } The vertical scroll position.
295+ */
296+ const get_scroll_y = ( scroll_reference ) => {
297+ // scroll_listener == window: window.scrollY
298+ // scroll_listener == html: html.scrollTop == window.scrollY
299+ // scroll_listener == DOM node: node.scrollTop
300+ return typeof scroll_reference . scrollTop !== "undefined"
301+ ? scroll_reference . scrollTop
302+ : scroll_reference . scrollY ;
303+ } ;
304+
273305/**
274306 * Get data stored directly on the node instance.
275307 * We are using a prefix to make sure the data doesn't collide with other attributes.
@@ -336,6 +368,44 @@ const template = (template_string, template_variables = {}) => {
336368 return new Function ( "return `" + template_string + "`;" ) . call ( template_variables ) ;
337369} ;
338370
371+ /**
372+ * Get the visible ratio of an element compared to container.
373+ * If no container is given, the viewport is used.
374+ *
375+ * Note: currently only vertical ratio is supported.
376+ *
377+ * @param {Node } el - The element to get the visible ratio from.
378+ * @param {Node } [container] - The container to compare the element to.
379+ * @returns {number } - The visible ratio of the element.
380+ * 0 means the element is not visible.
381+ * 1 means the element is fully visible.
382+ */
383+ const get_visible_ratio = ( el , container ) => {
384+ if ( ! el ) {
385+ return 0 ;
386+ }
387+
388+ const rect = el . getBoundingClientRect ( ) ;
389+ const container_rect =
390+ container !== window
391+ ? container . getBoundingClientRect ( )
392+ : {
393+ top : 0 ,
394+ bottom : window . innerHeight ,
395+ } ;
396+
397+ let visible_ratio = 0 ;
398+ if ( rect . top < container_rect . bottom && rect . bottom > container_rect . top ) {
399+ const rect_height = rect . bottom - rect . top ;
400+ const visible_height =
401+ Math . min ( rect . bottom , container_rect . bottom ) -
402+ Math . max ( rect . top , container_rect . top ) ;
403+ visible_ratio = visible_height / rect_height ;
404+ }
405+
406+ return visible_ratio ;
407+ } ;
408+
339409const dom = {
340410 toNodeArray : toNodeArray ,
341411 querySelectorAllAndMe : querySelectorAllAndMe ,
@@ -351,10 +421,13 @@ const dom = {
351421 create_from_string : create_from_string ,
352422 get_css_value : get_css_value ,
353423 find_scroll_container : find_scroll_container ,
424+ get_scroll_x : get_scroll_x ,
425+ get_scroll_y : get_scroll_y ,
354426 get_data : get_data ,
355427 set_data : set_data ,
356428 delete_data : delete_data ,
357429 template : template ,
430+ get_visible_ratio : get_visible_ratio ,
358431 add_event_listener : events . add_event_listener , // BBB export. TODO: Remove in an upcoming version.
359432 remove_event_listener : events . remove_event_listener , // BBB export. TODO: Remove in an upcoming version.
360433} ;
0 commit comments