I have a container of 200px that have a container itself with 400px height, I have a tracking mouse object that moves with it on mousemove event
when I'm moving the mouse in the not overflowed part, everything is fine, but when I move the scroll down the object do not track the mouse anymore
$(document).mousemove(function(e) {
$("#image").css({
left: e.pageX,
top: e.pageY
});
});
#image {
position: absolute;
}
.container {
height: 200px;
overflow: auto;
}
.image-container {
position: relative;
height: 400px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="image-container">
<img id="image" src="http://images.pictureshunt.com/pics/m/mouse-8557.JPG" />
</div>
</div>
There is JSFiddle link here too.
Because you're not taking account of the scrollTop property of .container when positioning the cursor element. Try this:
let container = $('.container'); //<-- get container
$(document).mousemove(e => {
$("#image").css({
left: e.pageX,
top: e.pageY + container[0].scrollTop //<-- add scroll top too
});
});
In the interests of efficiency, it would also be good to cache the reference to #image once rather than grab it afresh every time the event fires.
let
container = $('.container'),
image = $('#image')
;
$(document).mousemove(e => {
image.css({ ...
Related
How can I detect where the mouse is positioned whenever I scroll? I can do this using a combination of onmousemove and scroll, but this seems like such a waste. I don't need to know where the mouse is before I scroll, only when I scroll - or perhaps even just right after I scroll. Please refer to my snippet below to see my attempt (event.clientY produces undefined) and please no jquery. Thanks.
var clientY_display_element = document.getElementById("clientY_display");
document.addEventListener('scroll', show_position = function (event) {
clientY_display_element.textContent = "event.clientY = " + event.clientY;
})
#container {
height: 50px;
}
#content {
height: 1000px;
background-color: rgba(120,120,120,1);
}
#clientY_display {
position: fixed;
}
<div id="container">
<div id="content"></div>
</div>
<div id="clientY_display">Scroll to see event.clientY position.. </div>
Is this what you want to achieve? Scroll inside the #container to see the number of pixels scrolled.
clientY is the coordinate of the mouse pointer when a mouse event was triggered. But you are listening for "scroll" event which is triggered when the document view has been scrolled. For scroll events, you can use the scrollTop to get the number of pixels that an element's content is scrolled vertically.
I also changed a bit your css, for this example's purpose.
var clientY_display_element = document.getElementById("clientY_display");
let scroller = document.querySelector("#container")
scroller.addEventListener('scroll', show_position = function (event) {
clientY_display_element.textContent = `scroll position = ${scroller.scrollTop}`;
})
#container {
height: 50px;
overflow: scroll;
}
#content {
height: 1000px;
background-color: rgba(120,120,120,1);
}
#clientY_display {
position: fixed;
}
<div id="container">
<div id="content"></div>
</div>
<div id="clientY_display">Scroll to see scroll position.. </div>
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/
I'll start with JS Fiddle:
http://jsfiddle.net/zy2xy/4/
<div id="page" style="position: relative; background: #ccc; width: 500px; height: 600px;">
<div id="container" style="top: 50px; left: 100px; width: 200px; height: 200px; position: absolute; background: #fff;">
<img src="http://lorempixel.com/200/100/">
</div>
</div>
I've got a whole page div #page, and inside that another div #container positioned absolute against #page.
What I want to achieve, is to rotate image inside it 90deg, 180deg or 270deg but always move that image to top left corner of #container.
I tried a little bit with transform-origin but I couldn't find any solution.
Set the position:absolute to the image
Then calculate the angle.. If it's 90 or 270 then set the left and top attributes for the image.
Code
$('a').click(function(e) {
e.preventDefault();
var angle = $(this).attr("id");
console.log("angle");
var $container = $('#container');
var left = 0;
var top = 0;
if(+angle === 90 || +angle === 270){
top = 50;
left = -50;
}
$("#my_image").css({
transform: 'rotate('+angle+'deg)',
'-moz-transform': 'rotate('+angle+'deg)',
'-webkit-transform': 'rotate('+angle+'deg)',
'top' : top + 'px',
'left' : left + 'px'
});
}).click(); // Fire click on DOM ready
Check Fiddle
I am using this code:
$('.my_img').mousemove(function(e){
$('.mycls').css("left",e.pageX-20+"px");
$('.mycls').css("top",e.pageY-10+"px");
});
then...
<div class="mycls">I Move</div>
then...
<img class="my_img" src="myimg.png" />
My problem is that if I add any div's above these divs the position changes and mycls is no longer at mouse position.
So if I was to add to extra div's after the body like this:
<div>ONE</div>
<div>TWO</div>
...then the rest of the code...I will lose the position :o/
Any ideas on how to sort this?
Since e.pageX and e.pageY values are relative to the entire page, your code shouldn't be affected by adding new elements. If you set top and left to an element, it defines its distance from the top and left of the page.
The only case where it could be problematic is if you have position:relative set on any parent elements of the mycls div. Remove that position:relative, so that top and left refer to the entire page and not the parent element.
simply add a CSS position:absolute; to your movable element .mycls
var img = document.getElementById("my_img");
var cls = document.getElementById("mycls");
img.onmousemove = function(e){
cls.style.left = e.clientX-20 + "px";
cls.style.top = e.clientY-10 + "px";
};
#mycls {
background-color: rgba(255,255,255,0.8);
position: fixed;
left: 0;
top: 0;
font-family: sans-serif;
padding: 10px;
border-radius: 5px;
border: 1px solid rgba(0,0,0,0.8);
}
#my_img {
width: 420px;
height: 200px;
background-color: #333; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="my_img">
<div id="mycls">
Your message here
</div>
</div>
Here's an example of how I have done this in the past ... importantly
the div that is moving is a child of the container so that a any mousemove events it triggers are bubbled to the parent for handling
I'm trying to replace the mouse cursor with an image.
I have the following html:
<div id="content-bg">
<img src="path"/>
</div>
<div id="mouse"></div>
CSS:
#content-bg{
background:url(../img/frontend/content-bg.png) top left no-repeat;
width: 968px;
height: 552px;
position:relative;
}
#mouse {
cursor: none;
width: 75px;
height: 76px;
background: url("../img/frontend/cross.png") no-repeat center;
position: absolute;
display:none;
top: 0;
left: 0;
z-index: 10000;
}
javascript:
$(document).ready(function(){
$('#content-bg').mouseout(function(){
$('#mouse').hide();
$(this).css("cursor","none");
return false;
});
$('#content-bg').mouseenter(function(){
$('#mouse').show();
return false;
});
$('#content-bg').mousemove(function(e){
var x = e.clientX - $(document).scrollLeft() - 37.5;
var y = e.clientY + $(document).scrollTop() - 38;
$('#mouse').css('left', x).css('top',y);
});
});
The mouse image is on the right place but seems to be blinking and flashy. The transitions aren't as smooth as I wanted. Somehow it seems that the mouseout and mouseenter events are triggered every time I move the mouse inside the content-bg div.
Any idea how I can solve this?
As has been pointed out in comments, your mouseout occurs when your mouse suddenly hovers #mouse, as it appears.
You need to cancel out these events manually:
$('#content-bg').mouseout(function(e){
if($(e.relatedTarget).is('#mouse')) { return false; }
$('#mouse').hide();
$(this).css("cursor","none");
return false;
});
$('#content-bg').mouseenter(function(e){
if($(e.fromElement).is('#mouse')) { return false; }
$('#mouse').show();
return false;
});