Detecting clicked horizontal position in a div - javascript

When i click on streaming bar, position will be detected from left edge of the browser window but it has to be detected from left edge of the #progressBar div in this demo. So, because of positioning #progressBar div with left: 200px; 200px is added on horizontal position that is clicked.
My simple detecting function:
function point_it(e){
var x=e.clientX;
var seekSecond = Math.floor((x/1100) * ytplayer.getDuration()); //1100 is width of the progress bar
seekTo(seekSecond);
document.getElementById("xPos").innerHTML=x;
}
style:
#progressBar{
position: relative;
top: 400px;
left: 200px;
width: 1100px;
height: 4px;
border: 2px solid gray;
margin: 10px;
z-index: 8;
}
#elapsedBar{
position: relative;
top: -1px;
width:0px;
height:3px;
border:1px solid;
border-color: #660033;
background-color: #660033;
margin:0px;
z-index: 10;
}
#loadedBar{
position: relative;
top: 0px;
width: 0px;
height:4px;
border:1px solid;
border-color: gray;
background-color: gray;
margin:0px;
z-index: 9;
}

You can subtract the left position from the clicked position, I only know the jQuery way of doing this:
// Get the "left" value
var leftPos = $("#progressBar").css("left");
// Remove "px"
var leftPos = leftPos.replace("px", "");
Then subtract leftPos from the value you are getting

Just use e.offsetX in your function instead of e.clientX.
e.client... is related to the browsers window, e.offsett... is related to the clicked target element.

You have to subtract 10 from x because of margin: 10px;. This causes var x=e.clientX; to be 10 when clicking on the left side of the bar.

Related

Center Child to Parent When Child is Absolute Positioned [duplicate]

This question already has answers here:
How to center a "position: absolute" element
(31 answers)
How can I center an absolutely positioned element in a div?
(37 answers)
How to center absolute div horizontally using CSS?
(9 answers)
Closed 1 year ago.
Is there a way to position an absolute positioned element centered to its' parent who is relative positioned?
I was thinking if somehow I can calculate the width of the parent, and based on that, center the child? But not sure where to start whether with JavaScript or css.
Here's the codepen for reference
.tooltip {
/*
position the top-left corner of the element
in the center of the parent
*/
position: absolute;
top: 50%;
left: 50%;
/*
move the (positioned) element up and left
by half its own width/height
*/
transform: translate(-50%, -50%);
}
.container,
.tooltip{
border: 2px solid black;
padding: 10px;
}
.container {
position: relative;
width: 80vw;
height: 50vh;
}
<div class="container">
<div class="tooltip">Tooltip</div>
</div>
top and left percentages are percentages of that dimension on the of the parentElement.
Whereas the percentages in translate are relative to the element itself.
This should center your tooltip
const tooltip = document.getElementById('tooltip');
const parentWidth = tooltip.parentElement.offsetWidth;
tooltip.style.left = (parentWidth - tooltip.offsetWidth) / 2 + 'px';
You can use left/right positioning with transform:translateX in order to put element in the center of it's parent. I've made below snippet by using your codepen example:
#container {
border: 1px solid gray;
}
#wrapper {
display: inline-block;
position: relative;
height: fit-content;
border: 1px solid red;
padding: 8px;
}
#tooltip {
border:1px solid green;
position:absolute;
bottom: -24px;
left: 50%;
transform: translateX(-50%);
white-space: nowrap; /* to prevent break the text*/
}
<div id="wrapper">
Trigger Content, Trigger Content, Trigger Content,Trigger Content,
<div id="tooltip">I want to be a centered to my parent</div>
</div>
Edit: I think Thomas Answer contains the better way
Well it depends on your code if you want to do this css only, Here are several cases I came up with after doing my research:
1. If your div has a set size (width & height), According to this page you can take this steps:
Add left: 50% to the element that you want to center. You will notice
that this aligns the left edge of the child element with the 50% line
of the parent.
Add a negative left margin that is equal to half the width of the
element. This moves us back onto the halfway mark.
Next, we’ll do a similar process for the vertical axis. Add top: 50%
to the child
And then add a negative top margin equal to half its height.
In your case it looks like this:
#container {
border: 1px solid gray;
}
#wrapper {
display: inline-block;
position: relative;
height: fit-content;
border: 1px solid red;
padding: 8px;
}
#tooltip {
width: 100px; /* could be set by % aswell */
height: 10px;
border:1px solid green;
position:absolute;
left:50%;
top:50%;
margin-left: -50px;
margin-top: -5px;
bottom: -24px;
}
<div id="wrapper">
Trigger Content, Trigger Content, Trigger Content,Trigger Content,
<div id="tooltip">Center</div>
</div>
2. If it doesn't contain a set value but you want it to be centered anyway:
Not sure if it's a good way but you can use an absolute element inside wrapper before any other content, covering its parent and having its display value as flex and containing justify-content: center as well as align-items: center;
e.g. on your code:
#container {
border: 1px solid gray;
}
.full-flex{
width: 100%;
display: flex;
position: absolute;
justify-content: center;
align-items: center;
}
#wrapper {
display: inline-block;
position: relative;
height: fit-content;
border: 1px solid red;
/* padding: 8px; */ /* I removed the padding so you can get a better understanding of this */
}
#tooltip {
border:1px solid green;
}
<div id="wrapper">
<div class="full-flex">
<div id="tooltip">Wanna be centered</div>
</div>
Trigger Content, Trigger Content, Trigger Content,Trigger Content,
</div>

can't get the click position of a div element

I want to create a minimap. So I have an accurate representation of div elements inside my minimap. I want the user to use the minimap to navigate around the site.
I get the correct position when I click inside my minimap (the gray box), but when I click on a "ghostly" or the green box, I get incorrect dimensions, which leads to an incorrect position setting.
here is a showcase:
function getClickPosition(e) {
// I need the click position of the gray box
// but when I click on the green or red box I get their values
console.log(e.layerX)
}
.minimap {
height: 100px;
width: 140px;
background-color: #999;
position: absolute;
z-index: 100;
}
.viewport-layer {
height: 20px;
width: 35px;
left: 20px;
top: 15px;
box-sizing: border-box;
position: absolute;
border: 2px solid green;
z-index: 101;
max-width: 100px;
}
.ghosty-box {
position: absolute;
top: 60px;
left: 90px;
height: 30px;
width: 40px;
background-color: red;
z-index: 0; // should be in the background
}
<div class="minimap" onclick="getClickPosition(event)">
<!-- user screen: green border -->
<div class="viewport-layer">
</div>
<!-- dynamic size of the minimap -->
<div class="relativeLayer">
<!-- representation of the visible elements -->
<div class="ghosty-box"></div>
</div>
</div>
my console of e says something like:
click { target: div.ghosty-box, ... layerX: 10, layerY: 11 }
or
click { target: div.viewportLayer, ... layerX: 33, layerY: 16 }
I was expecting that a z-index would help.
Do you have any suggestions to get the click position of the .minimap or .relativeLayer with elements behind it?
So the target is always the gray box?
I think you want relative values of clicked elements inside of minimap. This will give you the relative X and Y of the clicked item - as well as the relative mouseX and mouseY (along with the relative percentage position)
function getClickPosition(e) {
// I need the click position of the gray box
// but when I click on the green or red box I get their values
if (e.target.classList.contains('minimap')) {
console.log('clicked on minimap background');
return;
}
let ref = e.target.closest('.minimap').getBoundingClientRect()
let pos = e.target.getBoundingClientRect();
let posY = pos.top - ref.top
let posX = pos.left - ref.left
let mouseY = e.clientY - ref.top
let mouseYPerc = ((mouseY / ref.height) * 100).toFixed(2);
let mouseX = e.clientX - ref.top
let mouseXPerc = ((mouseX / ref.width) * 100).toFixed(2)
console.log('my relative position X:' + posX + ' Y:' + posY);
console.log("relative mouseX:" + mouseX + " (" + mouseXPerc + "%) horiz");
console.log("relative mouseY:" + mouseY + " (" + mouseYPerc + "%) vert");
}
.minimap {
height: 100px;
width: 140px;
background-color: #999;
position: absolute;
z-index: 100;
margin: 50px;
opacity: .2;
}
.viewport-layer {
height: 20px;
width: 35px;
left: 20px;
top: 15px;
box-sizing: border-box;
position: absolute;
border: 2px solid green;
z-index: 101;
max-width: 100px;
}
.ghosty-box {
position: absolute;
top: 60px;
left: 90px;
height: 30px;
width: 40px;
background-color: red;
z-index: 0; // should be in the background
}
<div class="minimap" onclick="getClickPosition(event)">
<!-- user screen: green border -->
<div class="viewport-layer">
</div>
<!-- dynamic size of the minimap -->
<div class="relativeLayer">
<!-- representation of the visible elements -->
<div class="ghosty-box"></div>
</div>
</div>
I'm not absolutely sure what readings you want out of the various layers, but a couple of comments:
According to MDN:
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
If you want the position relative to the gray box, as in your example, you may want to look at event.pageX or event.clientX. As in this snippet:
function getClickPosition(e) {
// I need the click position of the gray box
// but when I click on the green or red box I get their values
console.log('pageX = ' + e.pageX);
console.log('clientX = ' + e.clientX);
}
.minimap {
height: 100px;
width: 140px;
background-color: #999;
position: absolute;
z-index: 100;
}
.viewport-layer {
height: 20px;
width: 35px;
left: 20px;
top: 15px;
box-sizing: border-box;
position: absolute;
border: 2px solid green;
z-index: 101;
max-width: 100px;
}
.ghosty-box {
position: absolute;
top: 60px;
left: 90px;
height: 30px;
width: 40px;
background-color: red;
z-index: 0; // should be in the background
}
<div class="minimap" onclick="getClickPosition(event)">
<!-- user screen: green border -->
<div class="viewport-layer">
</div>
<!-- dynamic size of the minimap -->
<div class="relativeLayer">
<!-- representation of the visible elements -->
<div class="ghosty-box"></div>
</div>
</div>
Alternatively, when you process the click event you may want to check which actual element has been clicked when you have nested elements and/or you may or may not want to stop propagation. It's worth looking at an event object console.log(e) for example to see what the target is and the other settings you are given to get the right ones.
if you don't really need to click the elements inside a good solution could be placing an absolute postioned empty layer covering the whole minimap just to capture the clicks. I added it to your snippet with the class .position-layer
function getClickPosition(e) {
// I need the click position of the gray box
// but when I click on the green or red box I get their values
console.log(e.layerX);
console.log(e.layerY);
}
.minimap {
height: 100px;
width: 140px;
background-color: #999;
position: absolute;
z-index: 100;
}
.viewport-layer {
height: 20px;
width: 35px;
left: 20px;
top: 15px;
box-sizing: border-box;
position: absolute;
border: 2px solid green;
z-index: 101;
max-width: 100px;
}
.ghosty-box {
position: absolute;
top: 60px;
left: 90px;
height: 30px;
width: 40px;
background-color: red;
z-index: 0; // should be in the background
}
.position-layer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index:1000;
}
<div class="minimap">
<!-- user screen: green border -->
<div class="viewport-layer">
</div>
<!-- dynamic size of the minimap -->
<div class="relativeLayer">
<!-- representation of the visible elements -->
<div class="ghosty-box"></div>
</div>
<div class="position-layer" onclick="getClickPosition(event)"></div>
</div>
MDN says (I'm paraphrasing) that layerX is position of the mouse cursor relative to the clicked element or one of it's parents that is absolutely positioned element
Your ghosty-box is position: absolute, which means that is it's clicked, the layerX is relative to it.
If you could position it relatively or using margins, that would solve the issue.
Other option is using pageX or screenX and computing the offset yourself, or positioning an overlay element over the minimap and catching the click on that.

Align Button At Bottom of Floating Div - BootStrap Responsive

I am trying to align a button at the bottom of a div that shows when the user scrolls down 600px.
I cannot get the button to align where I want it, as when i use margin-top, when the screensize changes, the button position changes, as I am using % because I want it to be responsive.
Here is the button code and the div code.
Button and div
<div class="topMenu"><button type="button" class="btn btn-sky btn-lg btn-float">Get Started</button></div>
.topMenu {
display: none;
position: fixed;
top: 0;
width: 100%;
height: 14%;
border-top: 1px solid #000;
background: #337AB7;
z-index: 1;
}
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 600) {
$('.topMenu').fadeIn();
} else {
$('.topMenu').fadeOut();
}
});
Thanks for any help.
First, take the link out of the button element. It's not valid HTML.
Next, you need to make your parent div's position relative and your button's position absolute. Give your button a bottom and left value and you should be good.
.topMenu {
position: relative;
width: 100%;
height: 1000px;
border-top: 1px solid #000;
background: #337AB7;
z-index: 1;
}
button {
position: absolute;
bottom: 0;
left: 50%;
display: none;
}

Jquery $(window).height() gives wrong value when setting height for document element

So my problem is when i get $(window).height() of an empty document it gives the correct value, but when i set a height for the div (.main-header) the $(window).height() gives it's value plus value close to the div height ,
this picture when i set a height 0 for the .main-header div
and this when i set 700px height for .main-header
i have tried $(window).load() and $(document).ready() and both gave same value https://jsfiddle.net/nev5onff/
$(window).load(function () {
var header = $('.main-header'),
windowH = $(window).height();
$('.test').text( windowH);
});
.main-header {
width: 100%;
height: 700px;
box-shadow: 0 1px 4px #888;
position: relative;
overflow: hidden;
}
.test {
position: fixed;
top: 0;
left: 0;
width: 100px;
float: left;
height: 100px;
background-color: #eee;
color: #000;
padding: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class="test"></div>
<header class="main-header"></header>
I'm not sure if I understand your question, but I'll try and answer the best I can.
Weave: Pure JS
http://kodeweave.sourceforge.net/editor/#f722c9d64b3e290ec7cc9b4c1a6d19b8
So if you're trying to grab the height of your window/document you can use... (I'm using vanilla/plain js)
var test = document.querySelector('.test');
test.textContent = window.innerHeight;
However if you were grabbing the height of an element, if it has padding that sometimes can add to the elements height depending on how it's styled regardless if it's height is 0 or auto.
In some cases you may want to use clientHeight over innerHeight source
var test = document.querySelector('.test'),
mainHeader = document.querySelector('.main-header');
test.innerHTML = test.clientHeight
Here's a simple fiddle demonstrating this process.
var test = document.querySelector('.test'),
mainHeader = document.querySelector('.main-header');
test.innerHTML = test.clientHeight
.main-header {
width: 100%;
height: 700px;
box-shadow: 0 1px 4px #888;
position: relative;
overflow: hidden;
}
.test {
position: fixed;
top: 0;
left: 0;
width: 100px;
float: left;
height: 100px;
background-color: #eee;
color: #000;
padding: 20px;
}
<div class="test"></div>
<header class="main-header"></header>

How can I prevent this jquery text panel from sliding top to bottom the first time it's hovered?

When the page is first loaded, and the image is hovered over for the first time, the sliding panel slides down from the top to the bottom. But ever time you hover over it after that, it slides up from the bottom - which is what I want. I don't want it to slide down from the top the first time it's hovered over. Is there any way to make it just slide up every time it's hovered over? I'm sure there's some simple solution but I'm not very familiar with javascript.
<div class="boxgrid captionfull">
<img src="http://s17.postimage.org/arxuilf9r/jareck.jpg"/>
<div class="cover boxcaption">
<h3>Jarek Kubicki</h3>
<p>Artist<br/>http://www.nonsensesociety.com/2009/03/art-by-jarek-kubicki/" target="_BLANK">More Work</a></p>
</div>
.boxgrid{
width: 325px;
height: 260px;
margin:10px;
float:left;
background:#161613;
border: solid 2px #8399AF;
overflow: hidden;
position: relative;
}
.boxgrid img{
position: absolute;
top: 0;
left: 0;
border: 0;
}
.boxcaption{
float: left;
position: absolute;
background: #000;
height: 100px;
width: 100%;
opacity: .8;
/* For IE 5-7 */
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
/* For IE 8 */
-MS-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
}
.captionfull .boxcaption {
top: 260;
left: 0;
}
$(document).ready(function(){
$('.cover').hide();
$('.boxgrid.captionfull').hover(function(){
$(".cover", this).stop().animate({top:'160px'},{queue:false,duration:160}).show();
}, function() {
$(".cover", this).stop().animate({top:'260px'},{queue:false,duration:160});
});
});
http://jsfiddle.net/scottm29/NUpfz/1/
Define a startup css to your element:
Here is jsFiddle.
.boxcaption{
...
top:260px;
}

Categories