Updating the mouse position while scrolling - javascript

I am trying to find the latest updated current mouse position relative to the whole document. I have set up a scroll event.
Since this event doesn't contain mouse location I have nested another event listener of mousemove inside this scroll event.
Even though, it works the problem I am facing is that if the user keeps the pointer in the same position and simply scrolls with the wheel, the latest position is not being updated unless I move the mouse.
What should I do? What can I use to detect the mouse position? I want simplest answer because I am learning css and js.
Here is my code:
document.addEventListener('scroll', (e) => {
document.addEventListener('mousemove', (e1) => {
total_scroll = window.scrollY + e1.clientY;
console.log("Current Pos: " + total_scroll);
})
})
body {
height: 2000px;
}

I think the best solution would be to separate these listeners, and keep updating some variable with current mouse position, and then, on scroll - just use the variable.
My previous answer was not proper, so I'll give another one:
<html lang="en">
<head>
<title>Document</title>
<style>
body {
height: 2000px;
}
</style>
</head>
<body>
<script>
let clientScrollY = 0;
document.addEventListener('mousemove', (e1) => {
clientScrollY = e1.clientY;
})
document.addEventListener('scroll', (e) => {
total_scroll = window.scrollY + clientScrollY;
console.log("Current Pos: " + total_scroll);
})
</script>
</body>
</html>
Also here is solution if you want to update onscroll and onmousemove.
<html lang="en">
<head>
<title>Document</title>
<style>
body {
height: 2000px;
}
</style>
</head>
<body>
<script>
let clientScrollY = 0;
let totalScrollY = 0;
function updateTotalScrollY(){
totalScrollY = window.scrollY + clientScrollY;
console.log(totalScrollY);
}
document.addEventListener('mousemove', (e1) => {
clientScrollY = e1.clientY;
updateTotalScrollY();
})
document.addEventListener('scroll', (e) => {
updateTotalScrollY();
})
</script>
</body>
</html>

Related

Why I failed removing 'resize' event on window?

There is a div element in my page. Here are the functionalities I would like it to have:
Fill out the browser window, that is, maximized, after it's clicked
After it's maximized, the div element remains maximized when the browser window size changes.
When it's maximized, clicking on it restores the div to its original size before it was maximized.
To implement the second point, I registered a resize event on the window to maintain the maximized state. The resize event is removed when it comes to the third point. However, it seems that the resize event failed to be removed because when I adjust the browser window, the div element is maximized again.
Can anybody tell me what happens underneath the hood?
http://jsbin.com/pokirokahe/edit?html,output
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
border: 2px solid blue;
background: gray;
}
body {
margin: 0;
}
</style>
</head>
<body>
<div></div>
<script>
var domDiv = document.getElementsByTagName("div")[0];
var maximized = false;
var originSize = {};
originSize.w = parseFloat(getComputedStyle(domDiv, null).width);
originSize.h = parseFloat(getComputedStyle(domDiv, null).height);
domDiv.addEventListener("click", function() {
if (!maximized) {
fullfill();
maximized = true;
console.log("maximized true, adding event listener");
window.addEventListener("resize", fullfill);
} else {
this.style.width = originSize.w + "px";
this.style.height = originSize.h + "px";
console.log("maximized false, removing event listener");
window.removeEventListener("resize", fullfill);
maximized = false;
}
function fullfill() {
var screensize = getViewportSize();
console.log(screensize.w + " " + screensize.h);
var divBorder = {
top: parseFloat(getComputedStyle(domDiv, null).borderTopWidth),
bottom: parseFloat(getComputedStyle(domDiv, null).borderBottomWidth),
left: parseFloat(getComputedStyle(domDiv, null).borderLeftWidth),
right: parseFloat(getComputedStyle(domDiv, null).borderRightWidth)
};
domDiv.style.width = screensize.w - divBorder.left - divBorder.right + "px";
domDiv.style.height = screensize.h - divBorder.top - divBorder.bottom + "px";
}
});
function getViewportSize(w) {
w = w || window;
if (w.innerWidth != null) return {
w: w.innerWidth,
h: w.innerHeight
};
var d = w.document;
if (document.compatMode == "CSS1Compat")
return {
w: d.documentElement.clientWidth,
h: d.documentElement.clientHeight
};
return {
w: d.body.clientWidth,
h: d.body.clientHeight
};
}
</script>
</body>
</html>
Everytime you trigger click event, you defined a function named fullfill, so the function fullfill your addEventListener is not equal to the one you remove.
If you want your web run correctly, you should define the function named fullfill out of your click eventListner.
well i think it is best to use css in this case, since you need the div to be maximized and get the browser's size, use the position absolute or fixed to the div and give it height:100% , width:100% it will re-size automatically with the browser and it will save you the hassle of JS events.

JavaScript "animation" not working as I expect

I've been trying to move a red box 20px on mouseover. But instead of adding 20px to the current position it just goes to position "20px".
I got the idea for this here: Move an image with the arrow keys using JavaScript
But it's not working for me :/
Thanks!
<html>
<head>
<meta charset="UTF-8">
<style>
#element {
position: absolute;
left:100px;
top:100px;
height: 140px;
width: 60px;
background-color: red;
}
</style>
</head>
<body>
<div id="element"></div>
<script>
window.addEventListener('load', function () {
boxElement = document.getElementById('element');
if (boxElement) {
boxElement.addEventListener('mouseover', function () {
boxElement.style.left += 20 + 'px';
});
}
});
</script>
</body>
</html>
boxElement.style.left returns a string which looks like "123px".
The first time you execute
boxElement.style.left += 20 + 'px';
it will be fine, since boxElement.style.left will be an empty string. But the second time, you are trying to set style.left to 20px20px (string concatenation!), so the browser simply ignores the new value, and keep the old one, 20px.
You have to parse the position out of the value first, using parseInt and then add to it:
var left = boxElement.style.left;
boxElement.style.left = (parseInt(left, 10) + 20) + 'px';
The other problem is that boxElement.style.left won't return the initial value which was inherited from the CSS class. For that you can use getComputedStyle and set it once before you bind the event handler:
var boxElement.style.left =
window.getComputedStyle(boxElement,null).getPropertyValue("left");
If you read the code of the linked question properly, you can see that that's exactly what was done there:
element.style.left = parseInt(element.style.left) - 5 + 'px';
You're adding a string "20px" to an empty string, which is effectively setting the style property of the boxElement to "left: 20px", overriding the stylesheet.
You could get the current computed style of the element each time and add to it, or you could keep a closure-scoped variable with the position, like this:
window.addEventListener('load', function () {
var x=window.getComputedStyle(boxElement,null).getPropertyValue("left");
boxElement = document.getElementById('element');
if (boxElement) {
boxElement.addEventListener('mouseover', function () {
x+=20;
boxElement.style.left = x + 'px';
});
}
});

Javascript division positioning

Here's my simple code.It contains division, which moves on dragging with mouse (on x axis) anywhere on screen.Everything works perfect on first drag, but on second division comes back to it's original position, which is centre of screen.I know why does this happen, but can't figure out how to fix it.My point is to continue moving division from coords where previous drags moved it.
<!DOCTYPE html>
<html>
<head>
</head>
<body style="overflow:hidden">
<style>
#screen
{
width:200px;
height:300px;
position:absolute;
top:0;bottom:0;left:0;right:0;
margin:auto;
border-style:solid;
}
</style>
<script>
var exit=0;
document.onmousedown=function(e)
{
exit=1;
x=e.pageX;
document.onmousemove= function(e)
{
if(exit==1)
{
y=e.pageX;
final=x-y;
document.getElementById("screen").innerHTML=final;
document.getElementById("screen").style.left=final+"px";
}
};
};
document.onmouseup=function(e)
{
exit=0;
}
</script>
<div id="screen">
</body>
</html>
You want to store the "final" value so that you can use it as an offset on the next click. What's happening is that you are using the mouse down and mousemove X difference to move the object, but on second click you are not taking into consideration that the object was offseted by the previous "final" value and it has to be moved with that offset in mind!
Here's the code snippet working, and the jsfiddle link below:
var exit=0;
var final = 0;
document.onmousedown=function(e)
{
exit=1;
x=e.pageX + final;
document.onmousemove= function(e)
{
if(exit==1)
{
y=e.pageX;
final=x-y;
document.getElementById("screen").innerHTML=final;
document.getElementById("screen").style.left=final+"px";
}
};
};
document.onmouseup=function(e)
{
exit=0;
}
jsfiddle:
http://jsfiddle.net/dcasadevall/NELWW/

Overlay showing mouse cursor coordinates relative to an image when mouse cursor is over that image

I'm trying to create a little overlay next to the mouse cursor that shows the coordinates of the cursor vs. the upper left corner of the image the mouse is on. I'm almost there: it kind of works, but there are still some problems.
When I scroll (either with the mouse wheel or with the scroll bars on the side) the overlay and the cursor get far apart from each other: the overlay moves with the page and the cursor stays still relative to the monitor. I already tried "onscroll" but it does not work
I used "onmouseover" and "onmouseout" function for the images in the page, but for some reason they are only executed ONCE, when the page is loaded.
When I put the mouse on the upper left corner of the image, I'd like to see 0,0 as the coordinates. The X is actually 0, but the Y is actually -15. For some reason the coordinates of the image are 15 pixel below the upper edge. No idea why.
OK, now that I mentioned the problems, here is my code:
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link href="main2008.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="Ext/mcs2.js"></script></head>
</head>
<body>
<div id="content">
<h1>JS test</h1>
<img src = "pic.jpg">
</div>
</body>
</html>
CSS
#xy {
font-size:10px;
position: absolute;
top: 0px;
right:0px;
width:60px;
visibility: visible;
color:#006699;
background-color:#ffffff;
border: 1px solid #66ccff;
z-index: 10;
padding:7px;
}
JS
var myX, myY, xyOn, myMouseX, myMouseY, ImgX, ImgY, Active;
//For each image, set onmouseover and onmouseout to the functions that activate and deactivate
$(document).ready(function() {
$("img").each(function(i) {
this.onmouseover = getcoordinates(this);
this.onmouseout = deactivate(this);
});
});
//Creation of new div is inside window.onload because it needs to be done when body already exists
window.onload = function(){
var divg = document.createElement("div");
divg.setAttribute('id',"xy");
divg.appendChild(document.createTextNode("New DIV"));
document.body.appendChild(divg);
};
function getcoordinates(object) {
ImgX=object.offsetLeft;
ImgY=object.offsetTop;
//document.getElementById('xy').style.visibility='visible';
Active=1;
alert("Acti"); //This pop-up is just for debugging
}
function deactivate(object) {
//document.getElementById('xy').style.visibility='hidden';
alert("Deacti"); //This pop-up is just for debugging
Active=0;
}
document.onmousemove=getXYPosition; //THIS IS THE KEY FUNCTION!!! And it works
window.onscroll=getXYPosition; //I tried this to fix the scrolling problem, but it does not work
// Cursor coordinate function
xyOn = true;
function getXYPosition(e){
if (1==1) { //Instead of "1==1" I had written "Active==1", but it does not work at all
myMouseX=(e||event).clientX-ImgX;
myMouseY=(e||event).clientY-ImgY;
if (myMouseX + 100 > document.documentElement.clientWidth) {
myX = myMouseX - (myMouseX + 80 - (document.documentElement.clientWidth));
} else {
myX = myMouseX + 20;
}
if (myMouseY + 64 > document.documentElement.clientHeight) {
myY = myMouseY - (myMouseY + 44 - (document.documentElement.clientHeight));
} else {
myY = myMouseY + 20;
}
if (document.documentElement.scrollTop > 0) {
myY = myY + document.documentElement.scrollTop;
myMouseY = myMouseY + document.documentElement.scrollTop;
}
document.getElementById('xy').style.top = myY + "px";
document.getElementById('xy').style.left = myX + "px";
document.getElementById('xy').innerHTML = "X is " + myMouseX + "<br />Y is " + myMouseY;
document.getElementById('xy').innerHTML = document.getElementById('xy').innerHTML;
if (xyOn) {
document.getElementById('xy').style.visibility = "visible";
} else {
document.getElementById('xy').style.visibility = "hidden";
}
}
}
PS: In case you're wondering why I add the overlay div and set the properties with JS rather than HTML, the reason is that when I manage to make the JS code at some point this will become a Chrome extension, which means I can inject JS and CSS into the page, but no HTML.

Custom HTML/Javascript context menu won't work

I'm trying to make a custom context menu. I'll eventually put in all the options.
I tried it in both Firefox and Chrome, and it doesn't even appear. It just shows the default context menu.
Here is my code:
sandbox.html:
<!DOCTYPE html>
<!-- Christian's Sandbox -->
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta name="Author" content="Christian Arnold" />
<title>Sandbox</title>
<link rel="stylesheet" type="text/css" href="sandbox.css" />
<script type="text/javascript" src="sandbox.js"></script>
</head>
<body>
<div id="contextmenu">
This is the context menu div.<br />
Put all your context menu-y things in here.
</div>
</body>
</html>
sandbox.css:
/* CSS for Christian's Sandbox */
#contextmenu {
display: none;
position: absolute;
left: 0px;
top: 0px;
border: 1px solid #aaa;
border-radius: 2px;
background-color: #ccc;
color: #000;
}
sandbox.js:
/* JavaScript for Christian's Sandbox */
document.onload = function() { // Make sure this all works
// Context menu script
var contextmenudiv = document.getElementById("contextmenu"),
contextmenu = {
hide: function(event) {
// Hide the context menu div
contextmenudiv.style.display = "none";
// Remove the event listener
document.removeEventListener("click", contextmenu.hide, true);
},
};
document.addEventListener("contextmenu", function(event) {
// Prevent the browser from opening the default context menu
event.preventDefault();
// Move the context menu to where the mouse is with respect to the page
contextmenudiv.style.left = (event.pageX + scrollX) + "px";
contextmenudiv.style.top = (event.pageY + scrollY) + "px";
// Display it
contextmenudiv.style.display = "block ";
// When you click somewhere else, hide it
document.addEventListener("click", contextmenu.hide, true);
}, true);
}
I got it fixed.
What I did was:
I put the contextmenudiv = document.getElementById("contextmenu") into the event listener instead of putting the whole thing into document.onload.
Here is my new code:
/* JavaScript for Christian's Sandbox */
// Context menu script
var contextmenudiv,
contextmenu = {
hide: function(event) {
if (event.button == 0) {
event.preventDefault();
// Hide the context menu div
contextmenudiv.style.display = "none";
// Remove the event listener
document.removeEventListener("click", contextmenu.hide, true);
}
},
};
document.addEventListener("contextmenu", function(event) {
contextmenudiv = document.getElementById("contextmenu");
// Prevent the browser from opening the default context menu
event.preventDefault();
// Move the context menu to where the mouse is with respect to the page
contextmenudiv.style.left = (event.pageX + scrollX) + "px";
contextmenudiv.style.top = (event.pageY + scrollY) + "px";
// Display it
contextmenudiv.style.display = "block";
// When you click somewhere else, hide it
document.addEventListener("click", contextmenu.hide, true);
}, true);
Now, I have effects and a notifications system to go along with it.

Categories