Absolute position after zooming - javascript

I have divs with class="myDiv". I need to do this logic: on mouse over, I want to show a popup in the middle of the div.
For that I have the following:
$(".myDiv").mouseover(function () {
positionDiv($(this).position().left + $(this).width() / 2, $(this).position().top + $(this).height() / 2);
});
function positionDiv(xPosition ,yPosition ) {
$("#popupWindow").css("left", xPosition + "px");
$("#popupWindow").css("top", yPosition + "px");
$("#popupWindow").show();
}
The CSS:
.popupWindow{
position:absolute;
width:313px;
height:383px;
display:none;
}
This will position the popup window in the middle of the div on mouse over. Everything works great at this point.
However, if the website is zoomed in (using the browser zoom functionality), tHe position will get messed up. The popup window no longer appears in the middle of myDiv.
Any idea what might be the problem?
Edit:
For more info, if it is created and I zoom it, it is fine. But when I move my mouse to another myDiv and the new popup appears in a weird position. The left and top attribute of the Div are messing up.

You don't need JS for this:
http://jsfiddle.net/coma/6VUpS/1/
The key is to play with CSS and avoid JS calculations. The container div (myDiv) should be position: relative, the popup must be inside and position: absolute, top and left to 50% and using negative margins to center it (http://www.css-101.org/negative-margin/06.php).
Try avoiding JS for visual fanciness, only CSS ensures the correct position even on zoom since it's rendered by the browser.
HTML
<div class="myDiv">
Hi!
<div class="popupWindow">you are welcome!</div>
</div>
CSS
div.myDiv {
padding: 10px;
background-color: #eee;
margin: 50px 0;
position: relative;
}
div.popupWindow {
position: absolute;
top: 50%;
left: 50%;
margin: -50px 0 0 -100px;
width: 200px;
line-height: 100px;
background-color: #111;
color: #fff;
text-align: center;
display: none;
pointer-events: none;
}
div.myDiv:hover > div.popupWindow {
display: block;
}
Bonus track using a checkbox to click/tap/toggle popup and some fade in:
http://jsfiddle.net/coma/6VUpS/3/
More hacky:
http://jsfiddle.net/coma/6VUpS/
More complex example:
http://jsfiddle.net/coma/dHTHG/

I understand your problem and my solution is to put every object containing a pop up in pos relative and then set your pop up with those CSS :
.myPopUp{
position:absolute;
display : none;
width:400px;
height : 100px;
margin-top : -50px;
margin-left:-200px;
background-color: red;
top : 50%;
left: 50%;
}
It will alway be centered.
Now i understand you have only 1 pop up for all your hoverable div. My trick is to save the pop up in a var and remove it from its parent container to append it in the hovered div like this :
var popUp = $('.myPopUp');
$('.myDiv').mouseover(appendPopUp);
$('.myDiv').mouseout(function(){popUp.css('display', 'none')});
function appendPopUp(){
console.log(popUp.parent(), $(this))
if(popUp.parent()[0] != $(this)[0]){
popUp.remove();
$(this).append(popUp);
}
popUp.css('display', 'block')
}
That should work, here's my fiddle : http://jsfiddle.net/7EEZT/

$(window).on('resize', function(){
var $md = $('.myDiv');
positionDiv($md.position().left + $md.width() / 2, $md.position().top + $(this).height() / 2);
});

I have a simple css solution if you have a div with known height and width you can do same task with help of css only
.popupWindow {
position:absolute;
width:313px;
height:383px;
left:50%;
top:50%;
margin-left:-156px;/*half of width*/
margin-top:-191px;/*half of height*/
display:none;
}

Go with position:relative and try this. It will solved your problem relate to position.
$(".myDiv").mouseover(function () {
positionDiv( $(this).width() / 2, $(this).height() / 2);
});
function positionDiv(xPosition ,yPosition ) {
$("#popupWindow").css("left","-" + xPosition + "px");
$("#popupWindow").css("top", "-" + yPosition + "px");
$("#popupWindow").show();
}
The CSS:
.popupWindow{
position:relative;
width:313px;
height:383px;
display:none;
}
http://jsfiddle.net/kishan6446/PdNkg/13/

Related

Javascript mousemove function to show element not working as expected

I am trying to to get a mousemove function to display a custom cursor element i created when the mouse is moved inside the specific div. The custom cursor is an absolute positioned div within the div i want it to appear in. The wierd thing i am seeing is i can see from the developer tools that it is infact working but the custom cursor doesnt actually show. If i however move the custom cursor div outside of the div i want it in and into the main body it displays fine.
I know this must be a simple error on my part but i cant see it! Appreciate any advice.
let customCursor = document.querySelector('.custom-cursor');
const section2 = document.querySelector('.section2');
section2.addEventListener('mousemove', function(e) {
customCursor.classList.add('active');
customCursor.setAttribute("style", "top:" + (e.pageY) + "px; left: " + e.pageX + "px;");
});
section2.addEventListener('mouseleave', function() {
customCursor.classList.remove('active');
});
.section {
position: relative;
}
.section1 {
height: 500px;
}
.section2 {
height: 500px;
}
.custom-cursor {
width: 50px;
height: 50px;
background: black;
border-radius: 50%;
display: none;
position: absolute;
}
.custom-cursor.active {
display: block;
}
<body>
<section class="section1 section">Section 1</section>
<section class="section2 section">Section 2
<div class="custom-cursor"></div>
</section>
</body>
Like #Titus comment, you can use CSS with cursor.
But if you implemeting it with JS that need to track position of your mouse relative to section2, you will need to subtract the section2 element offset left and top, then subtract half of the cursor width and height to center the cursor:
let customCursor = document.querySelector('.custom-cursor');
const section2 = document.querySelector('.section2');
section2.addEventListener('mousemove', function(e) {
customCursor.classList.add('active');
customCursor.setAttribute("style", "top:" + (e.pageY - section2.offsetTop - (customCursor.offsetWidth/2) ) + "px; left: " + (e.pageX - section2.offsetLeft - (customCursor.offsetHeight/2)) + "px;");
});
section2.addEventListener('mouseleave', function() {
customCursor.classList.remove('active');
});
.section {
position: relative;
}
.section1 {
height: 500px;
}
.section2 {
height: 500px;
}
.custom-cursor {
width: 50px;
height: 50px;
background: black;
border-radius: 50%;
display: none;
position: absolute;
}
.custom-cursor.active {
display: block;
}
<body>
<section class="section1 section">Section 1</section>
<section class="section2 section">Section 2
<div class="custom-cursor"></div>
</section>
</body>
position: absolute
is relative to the parent if the parent has
position:relative
so in order to have the correct position within your section2, you need to use e.layerY and e.layerX instead of e.pageY and e.pageX since those are based on the top left corner of your screen. e.layerY and e.layerX is relative to the container that the mouseevent is attached to.
Try this: https://jsfiddle.net/42kq1w8m/9/

keep the background image fixed position and centered

In my project, I need to show a small image in center of the visible part of the container, with respect to the window i.e .loader. Even when the user scrolls the page, the image should be visible in center of .loader.
I successfully implemented this but now I am facing a edgecase which is when user scrolls the page "up to the header" or "down to the footer", the small image is hiding. demo.
This is actually normal behaviour but in these edgecases, I want the image to stick to top/bottom end of the .loader container.
What I want:
Keep the small image always at center of .loader container. (I already implemented this)
when scrolled to any end of .loader container, the image should stick to that end instead of hiding behind the container.
Fiddle
A solution using just css is preferred. I am looking for browser support in IE9+, chrome and firefox.
.header {
height: 600px;
width: 650px;
background-color: grey;
}
.left-side {
height: 300px;
width: 150px;
float: left;
background-color: red;
}
.loader {
background-image: url('http://i.imgur.com/U2njI.jpg');
margin-left: 150px;
height: 1500px;
width: 500px;
background-position: 345px center;
background-repeat: no-repeat;
background-attachment: fixed;
background-color: cornflowerblue;
}
.footer {
height: 600px;
width: 650px;
background-color: silver;
}
<div class="header"></div>
<div class="left-side"></div>
<div class="loader"></div>
<div class="footer"></div>
Here is a working solution with javascript, I hope its behaviour is how you expect it to be. I'm unfortunately not able to test it on IE9 right now but it should work (DEMO):
document.addEventListener('DOMContentLoaded',function() {
var loader = document.querySelector('.loader'),
loaderRect = loader.getBoundingClientRect(),
loaderTop = loaderRect.top + document.body.scrollTop,
loaderBottom = loaderTop + loader.offsetHeight,
initialBgPos = loader.style.backgroundPosition,
imageHeight = 141;
function onScroll() {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if(loaderTop >= (scrollTop + (window.innerHeight - imageHeight)/2)) {
loader.style.backgroundPosition='345px ' + (loaderTop - scrollTop) + 'px';
} else if(loaderBottom <= (scrollTop + (window.innerHeight + imageHeight)/2)) {
loader.style.backgroundPosition='345px ' + (loaderBottom - scrollTop - imageHeight) + 'px';
} else {
loader.style.backgroundPosition = initialBgPos;
}
}
window.addEventListener('scroll', onScroll);
onScroll();
});
To achieve what I think you want. We have to set the position of the .loader div to fixed, then it'll always stay where it's placed, regardless of whether the user scrolls the page, the div will scroll too. In here's how to set the position of loader to fixed in CSS (you may also have to get the position of your fixed div):
.loader{
position: fixed;
left: 100px;
top: 300px;
}
Here's your upadted JSFiddle: http://jsfiddle.net/Ezhb4/4/

Float a div at the bottom right corner, but not inside footer

I'm trying to implement a "go to top" button that floats at the bottom right corner of a page. I can do this with the following code, but I don't want this button to enter the footer of my page. How can I stop it from entering the footer and stay at the top of it when user scrolls the page down to the bottom of the page?
CSS
#to-top {
position: fixed;
bottom: 10px;
right: 10px;
width: 100px;
padding: 5px;
border: 1px solid #ccc;
background: #f7f7f7;
color: #333;
text-align: center;
cursor: pointer;
display: none;
}
JavaScript
$(window).scroll(function() {
if($(this).scrollTop() != 0) {
$('#to-top').fadeIn();
} else {
$('#to-top').fadeOut();
}
});
$('#to-top').click(function() {
$('body,html').animate({scrollTop:0},"fast");
});
HTML
<div id="to-top">Back to Top</div>
EDIT
Here is a drawing of how it should look like. The black vertical rectangle is a scroll bar. The "back to top" button should never enter the footer region.
Here is a jsfiddle.
The solution turned out to be more complicated than I thought. Here is my solution.
It uses this function to check if footer is visible on the screen. If it is, it positions the button with position: absolute within a div. Otherwise, it uses position: fixed.
function isVisible(elment) {
var vpH = $(window).height(), // Viewport Height
st = $(window).scrollTop(), // Scroll Top
y = $(elment).offset().top;
return y <= (vpH + st);
}
$(window).scroll(function() {
if($(this).scrollTop() == 0) {
$('#to-top').fadeOut();
} else if (isVisible($('footer'))) {
$('#to-top').css('position','absolute');
} else {
$('#to-top').css('position','fixed');
$('#to-top').fadeIn();
}
});
jsfiddle
Increase the value of bottom: 10px; than the height of footer.
I saw your screenshot now,just add some padding-bottom to it.
Solution
$(document).ready(function(){
$(window).scroll(function(){
btnBottom = $(".btt").offset().top + $(".btt").outerHeight();
ftrTop = $(".footer").offset().top;
if (btnBottom > ftrTop)
$(".btt").css("bottom", btnBottom - ftrTop + $(".btt").outerHeight());
});
});
Fiddle: http://jsfiddle.net/praveenscience/BhvMg/
You forgot to give the z-index, that prevents it from being on top!
z-index: 999;
Or if it is overlapping with the footer of your page, you can increase the co-ordinates.
bottom: 50px;
Your question is still not clear, "stop it from entering the footer". Does it overlap?

Multiple line jquery tooltip

How to make custom jquery tooltip appear as multiple line that adjusts to fixed width? So it not go in one long line (if 'title' attribute is very long). Because Now if I write long 'title' attribute, tooltip is displayed on one long line and it does not matter what width is set to tooltip element.
My code to get better understanding of what I'm asking:
http://jsfiddle.net/8XttH/
jquery code:
$(document).ready(function() {
$("body").append("<div class='tip'></div>");
$("p[title]").each(function() {
$(this).hover(function(e) {
$().mousemove(function(e) {
var tipY = e.pageY + 16;
var tipX = e.pageX + 16;
$(".tip").css({'top': tipY, 'left': tipX});
});
$(".tip")
.html($(this).attr('title'))
.stop(true,true)
.fadeIn("fast");
$(this).removeAttr('title');
}, function() {
$(".tip")
.stop(true,true)
.fadeOut("fast");
$(this).attr('title', $(".tip").html());
});
});
});
Set a max-width on the tool tip box?
max-width: 100px;
Also set the height to auto so it increases as needed
height: auto;
The text will then wrap to the next line.
See this fiddle
Use this css
div.tip{
position: absolute;
top: 100px;
left: 100px;
width:100px;
border: 2px solid #FF0000;
background-color: #FF9999;
display: none;
padding: 3px;
}
Fiddle: http://jsfiddle.net/8XttH/2/

How to keep a floating div centered on window resize (jQuery/CSS)

Is there a way (without binding to the window.resize event) to force a floating DIV to re-center itself when the browser window is resized?
To help explain, I imagine the pseudocode would look something like:
div.left = 50% - (div.width / 2)
div.top = 50% - (div.height / 2)
UPDATE
My query having been answered below, I wanted to post the final outcome of my quest - a jQuery extension method allowing you to center any block element - hope it helps someone else too.
jQuery.fn.center = function() {
var container = $(window);
var top = -this.height() / 2;
var left = -this.width() / 2;
return this.css('position', 'absolute').css({ 'margin-left': left + 'px', 'margin-top': top + 'px', 'left': '50%', 'top': '50%' });
}
Usage:
$('#mydiv').center();
This is easy to do with CSS if you have a fixed-size div:
.keepcentered {
position: absolute;
left: 50%; /* Start with top left in the center */
top: 50%;
width: 200px; /* The fixed width... */
height: 100px; /* ...and height */
margin-left: -100px; /* Shift over half the width */
margin-top: -50px; /* Shift up half the height */
border: 1px solid black; /* Just for demo */
}
The problem, of course, is that fixed-size elements aren't ideal.
The simplest way would be with the following CSS code:
#floating-div {
width: 50%;
border: 1px solid gray;
margin: 0 auto;
}
The key line of CSS code above is the "margin: 0 auto;" which tells the browser to automatically set the left/right margins to keep the div centered on the page, even when you resize the browser window.
Try this little article about Horizontal and Vertical centering. It is a little old and has a few hacks but you should be able to work out some test code from it.

Categories