How Detect Which Child Element Is Visible After Scrolling the Parent Div

How detect which child element is visible after scrolling the parent div?

Since this question never tagged jQuery, here's a pure Javascript solution that simulates the behavior you're looking for to the best of my knowledge. The solution calculates the amount of pixels of each child element currently visible within the container. If the amount is bigger or equal to half the size of the container, it assumes this is the page your visitor is looking at.

function getVisibleHeight(element){ const container = document.getElementById("container"); let scrollTop = container.scrollTop; let scrollBot = scrollTop + container.clientHeight; let containerRect = container.getBoundingClientRect(); let eleRect = element.getBoundingClientRect(); let rect = {}; rect.top = eleRect.top - containerRect.top, rect.right = eleRect.right - containerRect.right, rect.bottom = eleRect.bottom - containerRect.bottom, rect.left = eleRect.left - containerRect.left; let eleTop = rect.top + scrollTop; let eleBot = eleTop + element.offsetHeight; let visibleTop = eleTop < scrollTop ? scrollTop : eleTop; let visibleBot = eleBot > scrollBot ? scrollBot : eleBot;
return visibleBot - visibleTop;}
document.addEventListener("DOMContentLoaded", function(event) { const container = document.getElementById("container"); const divs = document.querySelectorAll('.page');
container.addEventListener("scroll", () => { for(let i=0; i<divs.length; i++){ const containerHeight = container.clientHeight;
// Gets the amount of pixels currently visible within the container let visiblePageHeight = getVisibleHeight(divs[i]);
// If the amount of visible pixels is bigger or equal to half the container size, set page if(visiblePageHeight >= containerHeight / 2){ document.getElementById('page-counter').innerText = i+1; } } }, false);});
#container { width: 400px; height: 300px; overflow: auto;}
.page { width: 380px;}
.red { background-color: red; height: 300px;}
.blue { background-color: blue; height: 200px;}
Current page: <span id="page-counter">1</span><div id='container'> <div id="div-1" class="page red"></div> <div id="div-2" class="page blue"></div> <div id="div-3" class="page red"></div> <div id="div-4" class="page blue"></div></div>

How to check if element is visible after scrolling?

This should do the trick:

function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();

var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();

return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

Simple Utility Function
This will allow you to call a utility function that accepts the element you're looking for and if you want the element to be fully in view or partially.

function Utils() {

}

Utils.prototype = {
constructor: Utils,
isElementInView: function (element, fullyInView) {
var pageTop = $(window).scrollTop();
var pageBottom = pageTop + $(window).height();
var elementTop = $(element).offset().top;
var elementBottom = elementTop + $(element).height();

if (fullyInView === true) {
return ((pageTop < elementTop) && (pageBottom > elementBottom));
} else {
return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
}
}
};

var Utils = new Utils();

Usage

var isElementInView = Utils.isElementInView($('#flyout-left-container'), false);

if (isElementInView) {
console.log('in view');
} else {
console.log('out of view');
}

Why using CSS display:grid of parent element shows a scroll bar for child element?

both grid and flex will give you scroll bar for a similar reason which is the default stretch alignment. inner-container will get stretched to its parent height due to that alignment so it's like having height:100% then you have your scrollbar because of the overflow: scroll

No other display can do the same because the stretch alignment exits only with flexbox and CSS grid.

If you disable it, it won't happen:

.container {
display: grid;
grid-row: 2;
grid-column: 2;
height: 100px;
align-items:start;
}

.inner-container {
overflow-style: auto;
overflow-y: scroll;
}
<div class="container">
<div class="inner-container">
<ul>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
</ul>
</div>
</div>

Scrolling child div within a parent div

Assuming you wish to apply scrolling to enable responsive behaviour on smaller displays such a s mobile phone, overflow scroll should be applied to a parent of the table to enable scrolling like so

HTML:

<div class="parent">
<ul class="child">
...
</ul>
</div>

CSS:

.parent {
overflow: scroll;
}

For a better responsive experience we probably only want this scrolling to be left to right (y-axis) and not top to bottom (x-axis) we need to set this as well and so therefore need to adjust our CSS accordingly.

.parent {
overflow-y: scroll;
}

In your example it looks like the father and child classes are being applied to the grid build as an unordered list (<ul>) with the little car icons in. This <ul> is defining the height and with of the the parent, so therefore in a large enough window the table would not be expected to scroll. If you compress the window however the parent element only expands to the width of the window which is expected behaviour of a div. At this point the child element does scroll.

If you wish to apply this same behaviour to the .table-responsive element you need to apply the same principle. Wrap the table in a parent and apply the overflow accordingly. You do not want to put overflow-scroll on the table itself, but you may wish to give the table a min-width or apply a fixed width such as width: 300px;

HTML:

<div class="parent">
<table class="table-responsive">
...
</table>
</div>

CSS:

.parent {
overflow-y: scroll;
}
.table-responsive {
your styles
}

If you need to fix the dimensions of the parent so that the element does not define the size of the window you could do something like so with your CSS

.parent {
overflow: scroll;
width: 400px;
max-width: 100vw;
height: 400px;
max-height: 100vh;
}
.table-responsive {
your styles
}

In this case your width will ideally be 400px wide, but never exceed the viewport width and never be more that 400px high, but never exceed the viewport height.
If you want to get even cleverer with your height you could use calc for you max height so the that window never exceeds a specific height taking into consideration other elements on the page.

Detect when elements within a scrollable div are out of view

i had the same problem before, i have ended up with the following function.the first parameter is for the element to check, the second is to check if the element is partially in-view.it is for vertical check only, you can extend it to check for horizontal scroll.

function checkInView(elem,partial)
{
var container = $(".scrollable");
var contHeight = container.height();
var contTop = container.scrollTop();
var contBottom = contTop + contHeight ;

var elemTop = $(elem).offset().top - container.offset().top;
var elemBottom = elemTop + $(elem).height();

var isTotal = (elemTop >= 0 && elemBottom <=contHeight);
var isPart = ((elemTop < 0 && elemBottom > 0 ) || (elemTop > 0 && elemTop <= container.height())) && partial ;

return isTotal || isPart ;
}

check it on jsFiddle .

Is element visible in scrollable container

I found a way to tell if a child element is visible in the scrollable parent. Here is the jQuery function that I came up with.

$.fn.visible = function(partial, parent, child){
var $outer = $(parent);
var $child = $(child);

if(partial)
return ($child.position().top >= 0 && $child.position().top < $outer.height());
else
return ($child.position().top - $child.height() >= 0 && $child.position().top + $child.height() < $outer.height());
};

Allow overflow of child element while maintaining scrollability of parent

Wrap the contents of the div and the "other content" divs so that they are seperated from where the popup will be shown. Then use JavaScript to calculate the height.

const other = document.querySelector('.other');
var start = 100;
const button = document.getElementById('open');
button.addEventListener('click', () => {
const child = document.querySelector('.child');
child.insertAdjacentHTML('afterbegin', '<div class="popup"></div>');
start -= 50;
other.style.height = start + "px";
});
.container {
width: 100px;
height: 100px;
border: 1px solid black;
}

.popup {
width: 150px;
height: 50px;
background: red;
}

.other {
height: 100px;
overflow: hidden;
}
<div class="container">
<div class="child">
<div class="other">
<button id="open">Open</button>
<div>other content</div>
<div>other content</div>
<div>other content</div>
<div>other content</div>
<div>other content</div>
<div>other content</div>
</div>
</div>
</div>

How to detect whether an element that have parent `overflow: hidden;`, is hidden?

EDIT: my compulsion forced me into changing this code without jQuery and correcting a bug

Here's a jsFiddle for a quick test, I repeat the code below:

HTML:

<div id="someContainer" style="overflow:hidden; position:relative; height:26px; background-color: #ffffff;">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
</div>
<pre id="output"></pre>

JS (no jQuery):

var i, top, container, output, height;

container = document.getElementById("someContainer");
output = document.getElementById("output");
height = container.offsetHeight;

output.innerText += "Height: " + height + "px\n";

for (i = 0; i < container.children.length; i++)
{
top = container.children[i].offsetTop;
output.innerText += "Top " + i + ": " + top + "px => visible=" + (top < height) + "\n";
}

The output will be:

Height: 26px
Top 0: 0px => visible=true
Top 1: 18px => visible=true
Top 2: 36px => visible=false

The first two items are visible (at least in part, I cut the B in half on purpose), while the last item is not visible. It falls beyond the lower edge of the container.

NOTE: I had to add position: relative; to the container so that it becomes a positioning reference for child elements. Otherwise, offsetTop would compute incorrectly under specific circumstances (depending on outer HTML).



Related Topics



Leave a reply



Submit