Check position of two elements - javascript

Is there a way to check positioning of two elements?
For example:
.bigBox {
width: 100%;
height: 200px;
}
.btn {
position: fixed
display: none;
top: 10px;
right: 0;
}
There is a big box over the whole website. And i have a button with positioning fixed and display none. The button should fadeIn() if it is 100px under the .bigBox.

First thing, the the position of .bigBox's dimensions:
var bottomBigBox = $(".bigBox").offset().top + $(".bigBox").height();
var topOfBtn = $(".btn").offset().top;
// Check the condition and fade it.
if (bottomBigBox + 100 == topOfBtn)
$(".btn").fadeIn();

You can use position() or offset() methods to know the position of the element relative to the parent or relative to the document respectively.
$('.element').position().top; // returns the top value relative to parent
$('.element').position().left; // returns the left value relative to parent
$('.element').offset().top; // returns the top value relative to document
$('.element').offset().left; // returns the left value relative to document
See more:
http://api.jquery.com/offset/
https://api.jquery.com/position/

You can get an element position with offset(). Then you can sum its computed .height() and the desired margin by 100:
var bb = $(".bigBox");
var o = bb.offset();
var h = bb.height();
$(".btn").css("top", o.top + h + 100).fadeIn();
Working demo
Why use height() ? It will get the element computed height, so if you change on CSS or even if you use an relative value, it will work.
With plain Javascript
var bb = document.querySelector(".bigBox");
var t = bb.offsetTop;
var h = bb.offsetHeight;
document.querySelector(".btn").style.top = t + h + 100 + "px";
$(".btn").fadeIn(); // jQuery only for fadeIn effect
Working demo

Related

positioning new element based on position of existing element?

I am using the following code (Javascript within a webpage) to create a 'new' element in the DOM dynamically. I wish to position this say 200px 'below' an existing element. However my output has the positioning of the new element(s) all wrong...as if the position (top, left) I am specifying is ignored.
var _reference = document.getElementById("outputs");
for (_count = 0; _count < _limits; _count++) {
var _structure = document.createElement("div");
_structure.setAttribute("class", "container-fluid");
_structure.setAttribute("id", "struct_" + _tally);
if (_count === 0){
_rect = _reference.getBoundingClientRect();
//get the bounding box of the "outputs" id element...
document.getElementById("outputs").appendChild(_structure);
_structure.style.top = _rect.top + "200px"; //NOT positioned 200px below 'outputs'
_structure.style.left = _rect.left; //NOT positioned same position as 'outputs'
} //_count is "0"
} //for loop
I would have thought this should be fairly straightforward...however it is driving me crazy...any help appreciated.
You'll need to set _structure.style.position to 'relative', 'absolute', 'fixed', or 'sticky' in order to use top, left, right, bottom.
You need to set your position to realtive or absolute in order for this to work, also note that position: absolute sets the position according to the nearest relative positioned parent while position: relative positions according to the current position of the element

Get amount of pixels scrolled from a div's height + its distance from the top

I'm looking for a way in jQuery or pure JS to get the amount of pixels scrolled, not from the top of the page, but from the bottom of a div.
In other words I need to turn the amount scrolled beyond a div's height + its pixel distance from the top of the page into a variable.
I want to append this parallax code below so instead of calculating from the top of the page, calculates from a target div's distance from the top + its height.
/* Parallax Once Threshold is Reached */
var triggerOne = $('#trigger-01').offset().top;
$(window).scroll(function(e){
if ($(window).scrollTop() >= triggerOne) {
function parallaxTriggerOne(){
var scrolled = $(window).scrollTop();
$('#test').css('top',+(scrolled*0.2)+'px');
}
parallaxTriggerOne();
} else {
$('#test').css('top','initial');
}
});
I realize I didn't phrase this quite clear enough, I'm looking to only get the value of the amount of pixels scrolled since passing a div, so for example if I had a 200px tall div at the very top of the page and I scrolled 20 pixels beyond it, that variable I need would equal 20, not 220.
You can get a div's position by using div.offsetTop,
adding div.offsetHeight into div's distance from top of page will give you bottom of div, then you can subtract from window's scroll to get your desired value.
Feel free to ask if you have any doubts.
var div = document.getElementById('foo');
let div_bottom = div.offsetTop + div.offsetHeight;
var doc = document.documentElement;
var left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
var scroll_top, scroll_after_div;
setInterval(function(){
scroll_top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
scroll_after_div = scroll_top - div_bottom;
console.log(scroll_after_div);
}, 1000);
body { margin: 0; }
<div id="foo" style="position:relative; top: 100px; height: 30px; width: 100%; background-color: #000;"></div>
<div id="bar" style="position:relative; top: 700px; height: 30px; width: 100%; background-color: #000;"></div>
In this snippet setInterval method is printing the scroll value each second, you can scroll and see the change in value.
To work out the distance from the top of the page to the bottom of an element, you can add an elements outerHeight() with its offset().top.
Example: https://jsfiddle.net/dw2jwLpw/
console.log(
$('.target').outerHeight() + $('.target').offset().top
);
In pure JS you can get the bottom of the div directly with document.getElementById("my-element").getBoundingClientRect().bottom.
In jQuery you can use $('#my-element').offset().top + $('#my-element').height()

Highlighting line of text in div while scrolling

I'm trying to highlight some text in a div, with the highlight being a fixed line in said text. So far I've got a very simple solution that uses two divs, one that houses the text, and the other acting as the highlight, and as you scroll the text, it will pass through the highlight div.
HTML is as follows:
<div id="test">
text...
</div>
<div id="highlight"></div>
CSS is:
#highlight {
position: fixed;
top: 50%;
width: 100%;
background-color: #ccff00;
height: 30px;
opacity: 0.6;
}
#test{
position: absolute;
font-size: 30px;
top: 50%;
}
A demo of it can be found here
I was wondering if anyone knows how to make it so that scrolling the text can be done in a way where as a user scrolls, the next line becomes highlighted. Currently it scrolls normally, so the highlight may miss a line, or not highlight a complete line. Additionally, I was wondering how it would be best to make the text scroll all the way to the bottom. Would adding a margin of the same size as the offset at the top work? Alternative solutions for any of this would be appreciated as well.
Try adding an event listener to the window on scroll. Then calculate the offset by taking the scrollY % line-height and set the highlight top margin to the negative of that value.
JavaScript below:
var highlight = document.querySelector("#highlight");
window.addEventListener('scroll', function(e){
var y = window.scrollY;
var offset = y % 30;
highlight.style.marginTop = - y % 30 + "px";
});
See Working Fiddle
Not sure if this
https://jsfiddle.net/ok0x3apo/6/ is what you're looking for
You can see that I'm remodifying the entered text, to get line by line highlight as page scrolls.
var el = document.getElementById("text"),
content = el.innerHTML.replace(/ |^\s+|\s+$/g,""),
lines = content.split(/\./);
var html = "";
for(var i in lines){
html+="<p class='clear_display' id='id_"+i+"'>"+lines[i]+".</p>";
};
document.getElementById("text").innerHTML=html;
You can make changes to the "clear_display" class on how you prefer to have the text block.
function calledEveryScroll() {
var scrollPosition = $(window).scrollTop();
for(var i in lines){
var currentSection = document.querySelector("#id_"+i+"");
var sectionTop = currentSection.offsetTop;
if (scrollPosition<=0){
$(".clear_display").removeClass('active');
document.querySelector("#id_0").className += " active";
}
if (scrollPosition >= sectionTop-50) {
$(".clear_display").removeClass('active');
if (!$(currentSection).hasClass('active')) {
$(currentSection).addClass('active');
if(previous){
if(currentSection.offsetTop==previous.offsetTop){
$(previous).addClass('active');
}
}
var previous = currentSection;
}
//return false;
}
}
}
function resizing(){
var offset =100;
var bottom = $(window).height()-offset;
$('#text').css('margin-bottom',bottom);
}
This function checks each line when page scrolls.For the scroll to reach the bottom I'm calculating the margin-bottom.Hope it helps.

Detecting background image top margin with javascript

This is how I detect the top margin of a div and increase/decrease it:
var oldm = $("#bdi").css("margin-top").replace("px", "");
var addm = 1;
$("#bdi").css({
'margin-top': '-='+addm+'px'
})
But I need to do the same with background position.
detect the actual top position of a background image
increase/decrease the top margin of a background image
For example:
background-position: center 5px;
How do I detect "5px" and increase/decrease it?
Thanks
You can get it using background-position-y like this :
var bgPositionY = ($("#bdi").css('background-position-y'))
var addPos = 5;
$("#bdi").css({
'background-position-y': '-='+addPos+'px'
})
https://jsfiddle.net/IA7medd/aLkok1n4/
You don't need jQuery for this...
var el = document.getElementById('bdi'),
currentYPosition = getComputedStyle(el)['backgroundPositionY'],
increment = 1,
newYPosition = 'calc(' + currentYPosition + ' + ' + increment + 'px)';
// Set new backgroundPositionY
el.style.backgroundPositionY = newYPosition;
The use of calc() above ensures the value is properly incremented, even if a percentage position value is used.
As of jQuery 1.6, .css() accepts relative values similar to .animate(). Relative values are a string starting with += or -= to increment or decrement the current value. Link
For example like this
$("div").css("background-position-x", "+=10px");
$("div").css("background-position-Y", "-=10px");
If you want to do other operation on css value use this
$("div").css("background-position-x", function(index) {
return index * 10;
});
You can see demo at bottom
$("#increaseX").click(function(){
$("#image").css("background-position-x", "+=10px");
});
$("#decreaseX").click(function(){
$("#image").css("background-position-x", "-=10px");
});
$("#increaseY").click(function(){
$("#image").css("background-position-y", "+=10px");
});
$("#decreaseY").click(function(){
$("#image").css("background-position-y", "-=10px");
});
#image {
width: 100px;
height: 100px;
background-image: url("https://assets.servedby-buysellads.com/p/manage/asset/id/28536");
background-position: 0px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="image"></div>
<button id="increaseX">increaseX</button>
<button id="decreaseX">decreaseX</button>
<br />
<button id="increaseY">increaseY</button>
<button id="decreaseY">decreaseY</button>
Firefox doesn't support background-position-x and background-position-y. If you want to do your target work in firefox, see jsfiddle
You can
If you're using jQuery, the simplest option is to use incremental notation inline:
$("#bdi").css('background-position-y', '+=5px');

How to reposition a relative DIV using left/top?

I have a div with the attribute position: relative;. Now, there are three of these divs. They all get a unique ID etc.
Now if I click a div, I want it to animate to a certain position in the document. Although I cannot determine the left/top values since if I use "top" and "left", it will relatively set the left to its parents position.
Maybe a bit unclear, but here is what I got.
The CSS of the clickable DIV that will move.
div#left_hldr .switch_project {
z-index: 1001;
position: relative;
margin: 10px 0px 0px 0px;
cursor: pointer;
}
// Open project.
$(".switch_project").live('click', function() {
// Get the ID value.
var More_Id = $(this).attr("id");
// Explode the Id.
var Id_Split = More_Id.split("_");
// Get the project ID.
var Project_Id = Id_Split[2];
/*
Replacement of the switch project div.
1 ) Define the current position.
2 ) Define the new position.
3 ) Replace the DIV to the new position.
4 ) Fade the new page in.
5 ) Put the DIV back to its original position.
*/
// Current Position.
var Ori_Left = $(this).offset().left;
var Ori_Top = $(this).offset().top;
// New Position. [ Based on the content_hldr container ]
var New_Top = $("div#content_hldr").offset().top;
var New_Left = $("div#content_hldr").offset().left;
// Define the current div.
var Div_Rep = $(this);
// Hide the More Info tab.
$(Div_Rep).children(".more_info").fadeOut("fast");
// Fade content out.
$("div#content_hldr").fadeOut("fast");
// Replace the div.
$(Div_Rep).animate({
top: New_Top,
left: New_Left
}, "slow", function() {
// Load Home page in.
$("div#content_hldr").load("content/content.projects.php?id=" + Project_Id, function() {
// Re-define Cufon.
Cufon.replace('h2');
});
// Fade in the content.
$("div#content_hldr").fadeIn("fast", function() {
// Hide the replaced div.
$(Div_Rep).hide();
// Replace it back to its position.
$(Div_Rep).css({
top: Ori_Top,
left: Ori_Left
});
// Show the More Info tab again.
$(Div_Rep).children(".more_info").show();
// Fade back in.
$(Div_Rep).fadeIn("medium");
});
});
});
...it will relatively set the left to its parents position.
Actually, no. If you use left and top with a position: relative element, they'll offset it from where it otherwise would be if it weren't positioned (e.g., in the static flow), while continuing to reserve its space in the static flow. A subtle but important distinction (and hugely useful for drag-and-drop).
If you want to animate it to the top left of the document, you can figure out its offset (via offset), and then provide those as negative numbers for left and top, since of course if it's at (say) [100,50], then positioning it at [-100,-50] compared to its default position will...put it at [0,0].
Like this:
$("selector_for_your_divs").click(function() {
var pos, $this;
$this = $(this);
pos = $this.offset();
$this.animate({
left: "-" + pos.left + "px",
top: "-" + pos.top + "px"
});
});
Live example
Similarly, if you want to move it to be where another element is, simply subtract its position from the other element's position — that gives you the delta to apply:
$("selector_for_your_divs").click(function() {
var mypos, otherpos, $this;
// Move to the target element
$this = $(this);
pos = $this.offset();
otherpos = $('selector_for_other_element').offset();
pos.left = otherpos.left - pos.left;
pos.top = otherpos.top - pos.top;
$this.animate({
left: pos.left + "px",
top: pos.top + "px"
});
});
Live example

Categories