How to check scroll position in front of div - javascript

I created one parent div that has scroll. It has children divs which have text content, I want to check if scroll is in front of one of the child divs.
I tried it by comparing top scroll position with
div.offset().top
but as I am scrolling down div will calculate only visible height from parent with offset top position and scroll will calculate it's top from starting of parent. I am checking scroll's position like so:
if(scrollPosition>div.offset().top && scrollPostion (div.offset.top+div.height) ) {//scroll present }
What is correct way of getting div's top position?
Blockquote
Thanks in advance.

You need to add the offsetTop of the parents elements.
var t = div.offsetTop;
var p = div;
while (p=p.offsetParent)
t += p.offsetTop;

suppose that two boxes and one has scroll named container and another is child named target:
<div id="container">
<div id="target"></div>
</div>
<script type="text/javascript">
var container = document.getElementById('container'),
target = document.getElementById('target');
if((container.scrollTop - target.offsetTop) > 0 && (container.scrollTop - target.offsetTop) < target.offsetHeight) {
console.log('in range');
}
</script>
target.offsetHeight is not contains margin.

Related

Add/remove class to div if section is in viewport (vanilla JS)

I have a onepager with 5 sections, each with a min-height of 100vh and an id.
Then there is a fixed background div that changes its state when a new section comes into the viewport.
<div class="background"></div>
<section id="s1">...</section>
<section id="s2">...</section>
<section id="s3">...</section>
<section id="s4">...</section>
<section id="s5">...</section>
I wanted to update the background div with a class with the name of the current section id when the section enters the viewport and remove it when the section leaves the viewport.
This is what I made:
const sections = document.querySelectorAll('section')
const bg = document.querySelector('div.background')
document.addEventListener('scroll', updateBg)
function updateBg() {
sections.forEach((section) => {
const pixels = window.pageYOffset
const sectionId = section.getAttribute('id')
const offsetBottom = section.offsetTop + section.offsetHeight
if (section.offsetTop <= pixels) {
bg.classList.add(sectionId)
}
else if (offsetBottom >= pixels) {
bg.classList.remove(sectionId)
}
else {
bg.classList.remove(sectionId)
}
})
}
Adding the current class when the section enters the viewport works fine. But it's not removing the classes when the sections have left the viewport like I declared in my else if (offsetBottom >= pixels) statement. When I fully scrolled down the page I have something like this:
<div class="background s1 s2 s3 s4 s5"></div>
but what I want at the end is this:
<div class="background s5"></div>
any help?
Your conditions seem to be out of order. You are setting the class for all sections that are below the scroll threshold. Instead, you should add the class if part of the section is visible and remove it otherwise, like this:
if (section.offsetTop <= pixels && offsetBottom > pixels) {
bg.classList.add(sectionId);
} else {
bg.classList.remove(sectionId)
}
Also, please read the answer to this question: How can I tell if a DOM element is visible in the current viewport?
It is recommended to use getBoundingClientRect API instead.

How would I change the height of a parent div based on the height of a child div?

http://jsfiddle.net/nWb5j/68/
Hi there! As you can see in the jsfiddle above, I have a parent div that has a position of relative with child divs with position of absolute.
<div class="d1">
<div class="d2">W<br>o<br>r<br>l<br>d
</div>
<div class="d3">Hello</div>
</div>
d1 has a position of relative, while d2 and d3 have positions of absolute.
I have tried the following jQuery to no success:
$('.d1').css(height,($( "d3" ).height());
(As you can probably tell, I have no clue what I'm doing.)
I would like for the parent div to have the height of whatever the tallest child is, if possible. If that doesnt work, then to have the parent the same height as one of the children would work too.
I am very new to jQuery and javascript and have tried a few things, but none of them seem to work.
Thanks in advance!
Possible duplicate of Auto height on parent container with Absolute/Fixed Children
So your answer would be:
The parent div can not use "height:auto" when its children are positioned absolute / fixed.
You would need to use JavaScript to achieve this.
In jquery something like.
var biggestHeight = "0";
// Loop through elements children to find & set the biggest height
$("#d1 *").each(function(){
// If this elements height is bigger than the biggestHeight
if ($(this).height() > biggestHeight ) {
// Set the biggestHeight to this Height
biggestHeight = $(this).height();
}
});
// Set the container height
$("#d1").height(biggestHeight);
Working example
http://jsfiddle.net/blowsie/dPCky/1/
Customized example for you
http://jsfiddle.net/nWb5j/68/
Just use Math.max here is the demo
var d2Height = $("#d2").height(),
d3Height = $("#d3").height(),
largest = Math.max(d2Height, d3Height);
$('#d1').css({"height":largest});
In your case these two lines of javascript resolves the problem:
var height = Math.max($( "#d2" ).height(),$( "#d3" ).height());
$('#d1').height(height);
See updated fiddle:
http://jsfiddle.net/nWb5j/69/
You can try this...
var maxHeight =0;
//get the max height of child div
$(".d1 > div").height(function(i, h){
if (h > maxHeight ) {
maxHeight = h;
}
});
$(".d1").height(maxHeight);

JQUERY- refer to specific div with class as other divs inside the html page

In the fiddle you will see at the center of the page a DIV that contains text next to an img.
When I scroll down/up I need to effect with jquery/javascript only the div who's the closest to the navbar-below. all the divs as the same class so I effect them all-not what I need
For example:
what I am trying to achieve : when I scroll down,the closest div to the navbar(yellow bar) will be painted(the div) green,so if I scroll down and the navbar "collapse" with the div with will paint in green, and when he passes him and "disapper" it will go back to original color and the next div will paint in green. is it possible?
Here's the JS FIDDLE
When I referred to div I meant this section :
<div class="x" id="inside_center">
<div class="left_side" id="left_inside_center">sddsadasasdsadLorem </div>
<div class="right_side" id="right_inside_center"><img src="http://img-9gag-lol.9cache.com/photo/a7KwPAr_460s.jpg"></div>
</div>
EDIT:
UPDATED JSFIDDLE :
http://jsfiddle.net/nnkekjsy/3/
I added my jquery,as you can see it works only for the first one,and then stuck.. i need to "pass" it along the others div below him when the are getting to the same point. any ideas? :
$(document).ready(function() {
$(window).scroll(function() {
var scrollVal = $(this).scrollTop();
var navHeight = $("#div_menu").outerHeight();
if ( scrollVal > 55) {
$('#left_inside_center').css({'position':'fixed','top' :navHeight+'px'});
} else {
$('#left_inside_center').css({'position':'static','top':'auto'});
}
});
});
Have you tried use the first-of-type to select the top div, if i understand what your trying to do.
CSS3 selector :first-of-type with class name?
An other solution would be to check the position of the div and the nav bar and pick the closest one.
$(".left_side").each(function () {
//compare scroll with div
if(window.scrollTop() = $(this).position.top())
{
//do something
}
});
I know the position and the scroll won't be the same value but you can play with the condition to put some range.
Edit :
I think this is what you want. The navHeight and the height variable should be outside the window.scroll function as they never change :
$(window).scroll(function() {
var scrollVal = $(this).scrollTop();
var navHeight = $("#div_menu").outerHeight();
var height = parseInt($(".right_side").css("height").split("px")[0]);
$(".left_side").css({'position':'static','top':'auto'});
$(".left_side").filter(function( ) {
return $(this).position().top - 10 < scrollVal && $(this).position().top + height > scrollVal;
}).css({'position':'fixed','top' :navHeight+'px'});
});
Working fiddle :
http://jsfiddle.net/nnkekjsy/6/

How to calculate position of nested element to it parent element on click event

I have set up an example where i want to calculate position of nested element to it parent element.
For example http://jsfiddle.net/45cJZ/ in this example on click event i need to calculate position of nested div element to it parent element i.e .wrapper class.
can this be done using .offsetParent()
Add position:relative to the .wrapper (to make it the parent for the position calculations) and use .position() to get the position of the clicked element relative to the .wrapper
HTML
<div class="wrapper">
<div class="div1"></div>
<!-- ... -->
</div>
CSS
.wrapper {
/*...*/
position: relative;
}
Javascript
$(".wrapper").children().on("click", function() {
console.log($(this).position());
});
Demo: http://jsfiddle.net/8d62J/
#Andreas' answer is the best and correct but since you mentioned offset you can see how that works like this.
$('.wrapper div').on('click', function (event) {
var myOffset = $(this).offset();
var myParentOffset = $(this).parent().offset();
console.log(myOffset, myParentOffset);
var topDiff = myOffset.top - myParentOffset.top;
var leftDiff = myOffset.left - myParentOffset.left;
console.log(topDiff, leftDiff);
});
Demo: http://jsfiddle.net/robschmuecker/45cJZ/1/
You can use jQuery .position() to get the coordinates of element relative to its parent. Here is your fiddle edited to show the functionality of .position(). Just change the class to see the alerts change. All you have to do is:
var p = $(".div2").position();
alert("Left: " + p.left);
alert("Top: " + p.top);

find the height of a div and change the current div height to match

I'm trying to make a div the same height as the parent (if the parent is larger) or make the parent the same height as the current div (if the current div is larger)
Here's what i've got so far
$(this).parents().find('.address').slideToggle(function() {
$(this).parent().height($(this).parent().find('.address').height())
})
It makes the parent the height of the current div (but in my current case the parent is larger than the current div
Any ideas?
Thanks
Jamie
Check the solution here
Sample Html:
<div id="parent" style="height:500px;border:1px solid #000000">
<div id="child" style="height:300px;border:1px solid #000000">child</div>
</div>
Javascript:
jQuery(document).ready(function() {
var $parentDiv = $('#parent');
var $childDiv = $('#child');
if($childDiv.height() > $parentDiv.height())
$childDiv.css('height', $parentDiv.height());
else
$parentDiv.css('height', $childDiv.height());
});
your script is not really readable (and is not really performing)
but you could just read the height of the two elements and then set the height to the shorter one
var child = $(...),
parent = child.closest(...),
h = Math.max(child.height(), parent.height()),
e = (child.height() > parent.height())? parent : child;
e.css('height', h + 'px');

Categories