I have a div that I want to listen to the mousemove event to see the offset between the mouse and the top of the div (so I use event.layerY). Inside this div I have another div.
The problem is when I move my mouse over this inner div, my mousemove event listens to the inner div and not the outer div where I set the listener to. Meaning event.layerY will give me the offset to the inner div and not the outer div.
This is my code:
this.draglistener = this.renderer.listen(this.container.nativeElement, 'mousemove', e => {
e.stopPropagation();
});
As you can see I tired stopPropagation()but that doesn't work.
I also tried this:
if (e.target !== this.container.nativeElement) {
return;
}
But this way it just stops listening to the event when moving over the inner div. So thats not working too.
Also I can't do pointer-events: none; for the inner div because I need to listen to some other events on this div.
Any Ideas?
To get the mouse position relative to the outer div, subtract the client position of the outer div from the client position of the mouse. A template reference variable outerDiv can be used to pass the outer element to the event handler.
<div #outerDiv (mousemove)="onMouseMove($event, outerDiv)">
<div class="innerDiv">
</div>
</div>
In the event handler, the client mouse position is obtained with event.clientX and event.clientY, and the outer div client position is obtained with outerDiv.getBoundingClientRect().
onMouseMove(event: MouseEvent, outerDiv: HTMLElement) {
const bounds = outerDiv.getBoundingClientRect();
const posX = event.clientX - bounds.left;
const posY = event.clientY - bounds.top;
console.log(posX, posY);
}
See this stackblitz for a demo.
Related
I have recently tried to drag option box content in select element. It seems that ca not be done - drag doesn't fire at all.
I consider redesign this element totally that it will act & look as Select. Other option with jQuery is described here:
https://stackoverflow.com/questions/ask
In my case it must be done with Vanilla.JS.
I can of course back-engineer the above code, however maybe someone knows other working solution?
Make the element you wish to drag absolute and place it above the rest of the content using z-index. Then get the x and y coordinates of the element. Move the element directly into the body, center the element on pointer. Add an event listener for mousemove using a function to center the element at the page x/y coords. Function to drop element when you release the mouse button .onmouseup, this would remove all event listeners relevant to the moving of the element.
NOTE: This is very basic, more code would have to be used to determine page constraints in case user drags element out of the page bounding.
let drag = document.getElementById('draggableSpan');
drag.onmousedown = function(event) {
// make element absolute and place it on top with z-index
drag.style.position = 'absolute';
drag.style.zIndex = 1000;
let shiftX = event.clientX - drag.getBoundingClientRect().left;
let shiftY = event.clientY - drag.getBoundingClientRect().top;
// move it out of any current parents directly into body
// to make it positioned relative to the body
document.body.append(drag);
// function that centers the element at (pageX, pageY) coordinates
function moveTo(pageX, pageY) {
drag.style.left = pageX - shiftX + 'px';
drag.style.top = pageY - shiftY + 'px';
}
// move the absolutely positioned element under the pointer
moveTo(event.pageX, event.pageY);
function onMouseMove(event) {
moveTo(event.pageX, event.pageY);
}
// move the element on mousemove with event listener
document.addEventListener('mousemove', onMouseMove);
// drop the element on the page by removing eventlisteners that
// are relavent to the moving of the element
drag.onmouseup = function() {
document.removeEventListener('mousemove', onMouseMove);
drag.onmouseup = null;
};
};
<div class='parent'>
<span id='draggableSpan'>
draggable
</span>
</div>
I'm having a hard time figuring this out.
I have a bunch of divs (with some content inside them), and I want to be able to drag and drop them, horizontally. However, I want to move them by 100px increments (the left position needs to be 0, 100, 200 etc). Imagine having a table in the background with 100px wide cells and you can only move the element to another cell. Except there's no table.
jQuery is out of the question I think (I'm using Vue).
I won't write your code for you, but I'll help you figure it out by telling you where to start.
First, listen to the mousedown and mouseup events on the element:
<div v-on="{ mousedown, mouseup }">Some content</div>
Next register a mousemove listener on mousedown, and deregister it on mouseup:
methods: {
mousemove(e) {
const moved = e.offsetX - this.startX;
// The mouse has moved "moved" pixels.
// Now calculate whatever you want
},
mousedown(e) {
this.startX = e.offsetX;
e.currentTarget.addEventListener(this.mousemove);
},
mouseup(e) {
e.currentTarget.removeEventListener(this.mousemove);
},
}
I'm wondering how to do an effect like this:
http://www.gazprom.com/
(please note, the moving blue background, in top blue menu), and its relativity to cursor position)
Is there any script that follows cursor and changes background position style?
This effect can be achieved using small piece of JavaScript:
JavaScript
document.addEventListener('mousemove', function (event) {
if (window.event) { // IE fix
event = window.event;
}
// Grab the mouse's X-position.
var mousex = event.clientX;
var header = document.getElementById('header');
header.style.backgroundPosition = mousex/3 + 'px 0';
}, false);
Working Demo
How it works :
It binds a function on the mousemove event on document.
It grabs the current mouse position using event.clientX.
It changes the background-position of element #header with 1/3rd of the speed (mousex/3). Reference
I have a parent div with two inner divs, part of a Google Maps OverlayView:
<div id="container">
<div id="inner1">inner 1</div>
<div id="inner2">inner2</div>
</div>
I want to fire a mouseout event only when the user moves their mouse outside the boundaries of #container. At the moment I have this code:
google.maps.event.addDomListener(this.$content.get(0), "mouseout", function (e) {
console.log('InfoWindow mouseleave', $(e.fromElement));
});
But it's firing whenever the user moves their mouse into #inner1 too. In fact, looking at e.fromElement, it seems to fire whenever the user moves their mouse into the container! What can I do?
The correct answer in jQuery seems to be to use the mouseleave event, but I don't appear to have access to that in Google Maps - at least, if I change mouseout to mouseleave, the event no longer fires at all.
This jsFiddle demonstrates the basic problem: http://jsfiddle.net/pvB4u/1/
If its not working, you can try alternative. get pageX and pageY for mouse pointer(need to initialize it in document.ready(). Then check if it is inside the boundries of the outermost container. Something like this
$(document).mousemove(function (e) {
if ($("#container").offset().left > e.pageX || (parseInt($("#container").offset().left) + $("#container").width()) < e.pageX
|| $("#container").offset().top > e.pageY || (parseInt($("#container").offset().top) + $("#container).height()) < e.pageY) {
// This will be your required mouseout event
}
});
I have a layout similar to
<div id="outer">
<div id="inner"></div>
</div>
with a mouse event for the 'outer' element.
I am accessing the mouse coords of the event using jQuery's mouseup event with the layerX and layerY values.
When a click is received on the 'inner' element, it gives the coords of the click relative to the 'inner' element. Is it possible that when a click is given to the element, it can give the mouse coords relative to the outer element
Basic overview of what I have:
$('#outer').mouseup(function(e){
// do stuff with
//e.layerX
//e.layerY
}
jQuery doesn't have a built in way to do this, however you could calculate what you are looking for in the way you are describing. However a simpler way would be to always get the mouse position relative to the document, and then subtract the #outer elements position relative to the document:
var $outer = $('#outer');
$outer.mouseup(function(e) {
var offset = $outer.offset();
var x = e.pageX - offset.left;
var y = e.pageY - offset.top;
});