I am using a drag script to move an object along the x axis.
Along that same axis there is another object.
I want to use onmouseover so when the cursor is over that object and I'm dragging my object, something happens.
Now, this won't work because while dragging, the dragged object is always over other objects.
How can I make JavaScript ignore the dragged object?
Edit : I use http://www.webtoolkit.info/javascript-drag-and-drop.html for dragging.
I recently encountered this issue and ended up using this jQuery plugin:
http://www.48design.de/news/2009/11/20/kollisionsabfrage-per-jquery-plugin-update-v11-8/
This is great for detecting object collision. However, to determine when the mouse cursor is over the object, the trick I used was to create a 1x1 absolute inline-block div and always have that be positioned where the mouse cursor is.
So, when the user is dragging, to check and see if objects are colliding, use:
if ($('.cursorBlock').collidesWith('.staticBlock')) {
// objects are colliding
} else {
// objects are not colliding
}
So if you keep the 1x1 .cursorBlock with the mouse cursor as you drag, when the cursor is over the .staticBlock element, the .cursorBlock element will be too, and the collision will be detected, even though the real object you're "dragging" will be between the two.
I know you didn't tag your question with jQuery, but I thought I'd answer anyhow in case this helps you.
Have a look at the ondragenter event:
https://developer.mozilla.org/en/DragDrop/Drag_and_Drop
http://msdn.microsoft.com/en-us/library/ms536925%28v=vs.85%29.aspx
Related
I'd like to replace the mouse cursor on my website with a custom one, composed of two elements:
a cursor;
a trail that follows the cursor and lags behind it.
Doing that with jquery is extremely easy.
1) You hide the default cursor in CSS:
html, body {cursor:none;}
2) You create two different divs (one for the cursor itself and one for the trail) and style them:
<div id="mouse_cursor" class="mouse_cursor"></div>
<div id="mouse_trail" class="mouse_trail"></div>
3) You create the logic for each one of them:
function moveCursor(e) {
$('#mouse_cursor').css({'left' : e.pageX,'top' : e.pageY });
}
$(window).on('mousemove', moveCursor);
function moveTrail(e) {
TweenMax.to('#mouse_trail', 0.35, {
css: {left: e.pageX,top: e.pageY},
ease:SlowMo.easeIn
}
)};
$(window).on('mousemove', moveTrail);
(In my case the trail effect is made using Greensock's GSAP).
Now... this works perfectly as long as the cursor style isn't changed. Here's a fiddle, for your reference: https://jsfiddle.net/collederfomento/jvy1zfg8/27/
I'd like to change the style of the cursor once it hovers specific elements, however, and that's where I am encountering a few issues.
The way I have attempted to do that is the following:
1) Create a function bound to the mouseenter \ mouseover events that adds a class to the cursor if it's hovering the element:
$(".hover").bind( "mouseenter mouseover", function() {
$("#mouse_cursor").addClass("mouse_cursor_hover");
});
2) ... and then a second function that removes the class once the cursor is not hovering the element anymore:
$(".hover").mouseleave(function() {
$("#mouse_cursor").removeClass("mouse_cursor_hover");
});
3) Lastly, of course, I added the style for the "hover" cursor:
.mouse_cursor_hover {width:300px;height:300px;}
As you can see in this fiddle ( https://jsfiddle.net/collederfomento/z4e1qjbc/13/ ) the hover event is not firing properly, and the mouse cursor flickers.
I have tried several other approaches (using Javascript event listener rather than the above mentioned functions, using the css property rather than toggling a class, etc.) but they all behave in the same way.
What's curious is that if I remove the functions that make the cursors move, then the hover event is handled flawlessly. I believe the combination of the two functions is causing the issue, but I have no clue why (or how to solve it).
I think the cursor and the trail elements are interfering with the hover events. Even though they are at a high z-index, the browser still has to take them into account to figure out which element is actually getting hovered. The mouse cursor is still going over them after all, since they are not a “real” cursor, but actual elements positioned in that place.
Adding pointer-events none to both of them seems to fix the issue for the most part (checked in Chrome and Firefox, in both it seemed to significantly improve), so please give that a try:
.mouse_cursor,
.mouse_trail {
pointer-events:none;
}
https://jsfiddle.net/aur39py4/1/
I am assuming that you are not going to need any sort of hover effect on the cursor and trail themselves, so setting pointer-events:none should not have any adverse effects on the rest of what you’re doing on the page.
function move(event){
box.style.left=event.clientX-25+"px";
box.style.top=event.clientY-25+"px";
}
I created a dynamically div element named box, and then added mouseup and mousedown events, In mouseup, mousemove event will be added, in mousedown , it will removed
when mousemove event will be added with the function move, and also removed with the same
I want to make sure that this element doesnot go off Screen while i am moving the mouse or dragging the box
Thank you very much
You must define the dimensions of the dragged element beforehand, and then limit the the x and y based on the window's width&height:
var element_w = 50
var element_h = 50
function move(event){
box.style.left=Math.max(0,Math.min(window.innerWidth-element_w,event.clientX-25))+"px";
box.style.top=Math.max(0,Math.min(window.innerHeight-element_h,event.clientY-25))+"px";
}
mousemove event gives the delta from the last mousemove event position.
With this information, you have two options:
Get the current position when the user first pressed the mouse button, and add it's delta to the initial values
Get the current position of the box on every mouse move and add the delta to it.
The second one is more memory consuming and will create a lag for the move because of the position calculations, so the first option is the one you should go with.
Don't want to interfere with your learning curve. But this is a common situation and wherever you search it, you'll find a correct and working answer. You just needed to search it. For example here is one: javascript use drag to move element
So I have an element behind another, but it's still visible(its covered only partially by the element itself, but is otherwise completely covered by the margin attribute of the element above). I want to trigger a mouse event when I mouse over, but it doesn't get passed to it because of the element in front. I know how to calculate if I am over it and how to point to it, but I don't know how to send it the event onmouseover or hover or onmouseout.
If it helps I would be pointing at it by using document.getElementById("<calculated id>"). I know this works because it's ID is based off of its location within a grid, so I just have to calculate the position of the mouse and relate it to the grid.
Also the event that is supposed to happen(but isn't because of the things in front of it), is a :hover that triggers a simple transition animation via CSS.
document.getElementById('elementInFront').addEventListener('mouseenter', function(){
document.getElementById('elementBehind').DoYourStuff();
});
Does this work? I'm not sure if I understand your intention.
var item = document.getElementById("CalculatedId");
item.addEventListener("mouseover", func, false);
function func()
{
console.log("Hovered");
}
You can use the css property
pointer-events: none;
On the top element. This will allow all mouse events to "fall-through" to the element in the back. Unfortunately this doesn't work in IE, the only simple alternative for that is to make the front element's background transparent
How stop draggable JcanvaScript library?
For example a picture, in cases when drag-and-drop goes beyond the canvas element and I don't want to allow pictures to go beyond it.
jc('#img1').draggable({
drag: function(){
point=jc('#img1').position();
if(point.x<0){
//here stop draggable image
//these options don't work
//this.draggable('pause');
//return;
//jc.pause();
}
}
});
Wow! This was actually a really horrible problem. What makes it really horrible is that JCanvasScript doesn't fire onRelaseOutside events.
I've posted a solution here: http://jsfiddle.net/qpuGw/
You will not be able to drag the circle closer that 100px from the left-hand side.
The gist is:
If your object moves outside of a bounding box: (a) set clone it and (b) set it to invisible.
If your object moves back inside your bounding box: (a) delete the clone and (b) set your object to visible again
If the user releases the object: do the same as (2) above.
Good luck!
The problem I'm trying to solve is "What's at this position?"
It's fairly trivial to get the x/y position (offset) of a DIV, but what about the reverse? How do I get the id of a DIV (or any element) given an x/y position?
Unfortunately, triggering a manufactured/simulated mouse event won't work, since when you dispatch it, you have to provide a target element. Since that element is the one you're trying to figure out, all you could do is dispatch it on the body, as if it had already bubbled.
You really are left to do it on your own, that is manually walk through the elements you're interested in, and compare their position/size/zIndex to your x/y point and see if they overlap. Except in IE and more recently FF3, where you can use
var el = document.elementFromPoint(x, y);
See
http://developer.mozilla.org/En/DOM:document.elementFromPoint
http://msdn.microsoft.com/en-us/library/ms536417(VS.85).aspx
function getDivByXY(x,y) {
var alldivs = document.getElementsByTagName('div');
for(var d = 0; d < alldivs.length; d++) {
if((alldivs[d].offsetLeft == x) && (alldivs[d].offsetTop == y)) {
return alldivs[d];
}
}
return false;
}
Use a JQuery selector to filter the list of all DIVs for one that matches your position criteria?
Create a mouse event listener, then trigger a mouse event at that location. This should give you the entire stack of elements at that location.
Or, look at the source of Firebug.
If all you have is the X and Y position, (and you can't track mouse movement like you mentioned) then you will have to traverse the DOM, looping through every DIV. For each DIV you will need to compare its X and Y coordinates against those you have. This is an expensive operation, but it is the only way. I suggest you might be better off rethinking your problem instead of coming up with a solution for it.
One option is to build an array of "div-dimension" objects. (Not to be confused with the divs themselves... IE7 perf is frustrating when you read dimensions off of object.)
These objects consist of a pointer to the div, their dimensions (four points... say top, left, bottom, and right), and possibly a dirty bit. (Dirty bit is only really needed if the sizes change.
You could then iterate through the array and check dimensions. It requires O(n) to do that on each mouse move. You might be able to do slightly better with a binary search style approach... maybe.
If you do a binary search style approach, one way is to store 4 arrays. Each with a single point of the dimension, and then binary search on all four. O(4logn) = O(logn).
I'm not saying I recommend any of these, but they MIGHT work.
I think what John is saying is that you can use document.createEvent() to simulate a mousemove at the location you want. If you capture that event, by adding an eventlistener to the body, you can look at the event.target and see what element was at that position. I'm unsure as to what degree IE supports this method, maybe someone else knows?
http://developer.mozilla.org/en/DOM/document.createEvent
Update:
Here's a jquery plugin that simulates events:
http://jquery-ui.googlecode.com/svn/trunk/tests/simulate/jquery.simulate.js
this might be a little too processor intensive but going over the whole list of div elements on a page, finding their positions and sizes then testing if they're under the mouse. i don't think i'd want to do that to a browser though.
You might find it's more efficient to traverse the DOM tree once when the page is loaded, get all elements' positions and sizes, and store them in an array/hash/etc. If you design the data structure well, you should be able to find an element at the given coordinates fairly quickly when you need it later.
Consider how often you will need to detect an element, and compare that to how often the elements on the page will change. You would be balancing the number of times you have to re-compute all the element locations (an expensive computation) against the number of times you'd actually use the computed information (relatively cheap, I hope).