How to determine element coordinates in scrollable div? - javascript

I have a div element with vertical scrolling. It has span elements with text in it. How can I get the coordinates of these span elements. But I don't want it relative to the scroll position.
For example, in the div, lets say its 400px width, 1000px in height (but the view height is 500px), and its scrolled half way vertically. Then in the center of the view, I see a text, and if I click on it, I want the coordinate like (200, 250)
How can I get coordinates that are absolute to the div container?

Use element.getBoundingClientRect? (Subtract the container's top if you want it relative to the container.)
function client() {
alert(document.getElementById('child').getBoundingClientRect().top);
}
function local() {
var container = document.getElementById('container');
var containerRect = container.getBoundingClientRect();
var child = document.getElementById('child');
var childRect = child.getBoundingClientRect();
localTop = childRect.top - containerRect.top;
alert(localTop);
}
#container {
height: 100px;
overflow:scroll;
border:1px solid red;
margin-top:100px;
}
#child {
background: yellow;
}
<div id="container">
<div>Test</div>
<div>Test</div><div>Test</div><div>Test</div><div>Test</div>
<div id="child">Item of interest</div>
<div>Test</div><div>Test</div><div>Test</div><div>Test</div>
</div>
<button onclick="client()">Global top</button>
<button onclick="local()">Local top</button>

Let's say the scrollable div has an id of 'myDiv' and one element inside the div has an id of 'element1'. To find its true 'top' value in javascript try this:
alert($('myDiv').css('top') + $('element1').css('top'));

Related

Always push content down when changing a div's height without changing the page position

I have a page with a div in the middle of content, whose height can change from javascript.
How can I control which way the page will scroll when the div height's changes? I want content to be always pushed down, never up.
Currently, the content is pushed down or up, depending on where the page scroll is when the button is clicked.
Here is a minimal example:
function toggle(ev) {
const div = document.querySelector("div");
if (div.style.height === "336px") {
div.style.height = "147px";
} else {
div.style.height = "336px";
}
}
body {max-width: 60em; margin: auto;}
<p style="background-color: coral; height: 400px;"></p>
<div style="background-color:grey; height: 147px;"></div>
<button href="#" onclick="toggle()">toggle div size</button>
<p style="background-color: olive; height: 3000px;"></p>
To make things clearer, I'm looking for a solution where the top paragraph never moves when the div expands, no matter where on the window the button currently is. i.e. the bottom paragraph should be move up/down as well as the button.
Try blurring the element (e.target.blur() on click handler) to make it inactive before updating the height of the content. Since the window no longer sees the button as active, it will no longer scroll the page to keep it in view.
const handleClick = e => {
e.target.blur()
updateScrollHeight()
}
function toggle(ev) {
const div = document.querySelector("div");
ev.target.blur();
if (div.style.height === "336px") {
div.style.height = "147px";
} else {
div.style.height = "336px";
}
}
document.querySelector("button").addEventListener("click", toggle);
body {max-width: 60em; margin: auto;}
<p style="background-color: coral; height: 400px;"></p>
<div style="background-color:grey; height: 147px;"></div>
<button href="#">toggle div size</button>
<p style="background-color: olive; height: 3000px;"></p>
If I understand correctly you want to scroll at the bottom every time you set the height
function toggle(ev) {
const div = document.querySelector("div");
if (div.style.height === "336px") {
div.style.height = "147px";
} else {
div.style.height = "336px";
}
div.scrollTop = div.scrollHeight
}
You can scroll to the selected element using window.scrollTo function.
<!doctype html>
<style>
body {max-width: 60em; margin: auto;}
</style>
<script>
function toggle(ev) {
const div = document.querySelector("div");
if (div.style.height === "336px") {
div.style.height = "147px";
} else {
div.style.height = "336px";
}
window.scrollTo(0, div.scrollHeight);
}
</script>
<p style="background-color: coral; height: 400px;"></p>
<div style="background-color:grey; height: 147px;"></div>
<button href="#" onclick="toggle()">toggle div size</button>
<p style="background-color: olive; height: 3000px;"></p>
The page is keeping the currently active element in view - i.e. the button that you clicked on - so the extra height will appear to move up or down depending on where the button is in relation to the screen.
What you want to do is to make the page look like it didn't scroll up after the element expanded. To do this we can just scroll the page back to the position it was before the element expanded - this makes it look as if the height expanded downwards.
1. Save the current position of the top of the page
var pagePosBeforeExpand = window.pageYOffset;
2. Scroll the page back to the position it was before we changed the height, if the div has been expanded:
// if we are increasing the height, then scroll to the previous top...
window.scrollTo({ top: pagePosBeforeExpand });
Note that this doesn't affect when you collapse the height again as you didn't ask for that in your question, however you could adapt this to suit in that scenario - e.g. you could simply move the scroll code to execute outside of the if.
Working Example:
function toggle(ev) {
// 1. Save the current position of the top of the page
var pagePosBeforeExpand = window.pageYOffset;
const div = document.querySelector("div");
if (div.style.height === "336px") {
div.style.height = "147px";
} else {
div.style.height = "336px";
// 2. scroll the page back to the position it was beforewe changed the height
window.scrollTo({ top: pagePosBeforeExpand })
}
}
body {max-width: 60em; margin: auto;}
<p style="background-color: coral; height: 400px;"></p>
<div style="background-color:grey; height: 147px;">Top of content</div>
<button href="#" onclick="toggle()">toggle div size</button>
<p style="background-color: olive; height: 3000px;"></p>

Setting div height to another div's height

I've made a timeline using a sort of following this: https://www.w3schools.com/howto/howto_css_timeline.asp and set it to position: sticky. This is in a container called, div.timeContainer. Next to it, there's some text in a separate div. The idea is that the user scrolls down, reading the text on the right, while the timeline/overview on the left is in view.
The problem right now is that if I set the height of div.timeContainer, resizing the window means that the timeline will stop being in view/sticky around half-way through since the div on the right has become longer.
This (and variations) is what I have tried so far:
const historyContainer = document.querySelector("div.history").style.height
document.querySelector("div.timeContainer").style.height = historyContainer
I have prepared for you a simple example of assigning parent height to a child. An example in vanilla js.
let parent_div = document.querySelector('.parent');
let child_div = document.querySelector('.child');
let click_button = document.querySelector('input');
click_button.onclick = function(){
child_div.style.height = parent_div.offsetHeight + 'px';
};
.parent {
width: 100%;
height: 300px;
background-color: yellow;
}
.child {
width: 50%;
background-color: green;
}
<input type="button" value="click me to get the height of the child div">
<div class="parent">
<div class="child">
</div>
</div>

jQuery UI: Container div resizes

In the following example there are two draggable divs in a container div. When the second draggable div is removed (by clicking on the button) the first div moves up and the container is resized (see jsfiddle). The first div should not move when the second div is removed, as its position is absolute. What's wrong with this code?
The HTML:
<div id="container" style="background-color:blue;width:100%;height:100%"></div>
<button onclick="removeDiv()">Remove</div>
and the javascript:
$(document).ready(function(){
var $div0 = $('<div id="div0" />').appendTo('#container');
$div0.draggable();
$div0.offset({ top: 200, left: 350});
$div0.css('background-color','white');
$div0.css('width','150px');
$div0.css('height','200px');
$div0.text(0);
var $div1 = $('<div id="div1" />').appendTo('#container');
$div1.draggable();
$div1.offset({ top: 200, left: 50});
$div1.css('background-color','white');
$div1.css('width','150px');
$div1.css('height','200px');
$div1.text(1);
});
function removeDiv () {
$('#div0').remove();
}
Both draggable divs have relative positions. You can fix them up like so:
http://jsfiddle.net/isherwood/dzSRR/13/
#container {
position: relative;
}
#container > div {
position: absolute;
}
Because they're now absolutely-positioned, you'll need to give the parent div a height. If you use 100%, you also need to apply that height to html, body.
http://jsfiddle.net/isherwood/dzSRR/14/

Checking if innerHTML exceeds width or height of parent

I have a parent div with a fixed width and a fixed height.
The contents how ever might exceed this, so I am wondering is there a way in Javascript to calculate if the content exceeds the fixed dimensions?
An example would be like this:
<div style="width:20px;height:20px;overflow-x:hidden;overflow-y:hidden;">
A sentence that exceeds the width!
</div>
In the above case it does exceed the width. How would this be achieved in Javascript?
make a parent for your content:
<div style="width:20px;height:20px;overflow-x:hidden;overflow-y:hidden;">
<div id="parent">
A sentence that exceeds the width!
</div>
</div>
now you can get width and height of the parent and compare it with your main div:
var h = document.getElementById("parent").offsetHeight;
var w = document.getElementById("parent").offsetWidth;
You can use DOM properties of the div and text nodes. If you can wrap the text in a <span> element, it seems like it will be easier to work with the dimension properties.
html
<div id="container">
<span>A sentence that exceeds the width!</span>
</div>
css
div {
width:50px;
overflow:hidden;
white-space: nowrap;
}
js
var cont = document.getElementById('container');
var spn = cont.getElementsByTagName('span')[0];
//alert(cont.clientWidth);
//alert(spn.offsetWidth);
if(spn.offsetWidth > cont.clientWidth) {
alert("content exceeds width of parent div");
}
http://jsfiddle.net/Bn2Uc/2/

jQuery animate width from centered x coordinates of the element

Is possible to animate() the width of an element making a smooth center animation?
I mean animate making the element fixed on itself centered on himself x coordinates?
if i do :
<a class="animate">hey</a>
$('.animate').animate({'width':'+=1%'},500);
it works but the element is animated on the right and not from the center of himself
Yes, you'll have to move the element also.
<a class="animate" style="display:block; width:300px; border:1px solid #000; position:fixed; top:50px; left:50px;">hey</a>
jQuery(".animate").animate({'width':'0px', 'left':'200px'});
http://jsfiddle.net/7Ysbg/
New Information
So you mean something like this: http://jsfiddle.net/7Ysbg/2/
jQuery(".animate").click( function(){
var w = jQuery(".animate").width();
var new_w = jQuery(".animate").width()*1.5;
var left = jQuery(".animate").offset().left - ((new_w - w)/2);
jQuery(".animate").animate({'width':new_w+'px', 'left':left+'px'}, 'fast');
});
Just animate not only the width but also the position of the element. For example you can animate the left property. In this case you element should have position set to relative or absolute.
var width = $('.animate').width();
$('.animate').animate({
width: width*1.01,
left: width*0.005
},500);

Categories