Detecting the position of a div - javascript

I have created a small game, in which some blocks are move around a main div. The mouse which also holding a div (I had assigned the position of cursor to that div).
I just want to trace out, whether the cursor div is moving over the blocks(those are also div). If it comes like that then the game will be over.
How can I detect whether the block or cursor div moves over each other?

If you're using jQuery, you can find the left, top, width and height of a div by using these:
$(myDiv).offset().left
$(myDiv).offset().top
myDiv.offsetWidth
myDiv.offsetHeight
Use those to work out the left, right, top and bottom of each div. Then two divs overlap each other if:
left1 < right2 && left2 < right1 && top1 < bottom2 && top2 < bottom1

This is not a straightforward task using plain javascript, because you have to trace the div's ancestry and sum the relative positions until you find an absolutely positioned div.
On the other hand, this task is quite trivial with a javascript library such as jQuery or Prototype. In jQuery, for example, $(myDiv).offset() returns the div's position relative to the document.
If you also include jQuery UI, and make your main div a "Draggable", and all other divs "Droppable", all you need is hook up on the Droppable's over event to get notified when the main div is dragged over the other one.

The concept you're talking about is called collision detection.
Very simply, you need to get the bounds of your div and then loop through all the blocks to see if they overlap.

getBoundingClientRect()
John Resig has a great article here: getBoundingClientRect is Awesome

If you don't want to use jQuery you can copy/paste from here (LGPL code); http://code.google.com/p/ra-ajax/source/browse/trunk/Ra/Js/Ra.js
The place to look for is the "absolutize" function at line no. 220 which recursively calculates the size of "ancestor nodes" in the while loop.
Pasted in here for references;
var valueT = this.offsetTop || 0;
var valueL = this.offsetLeft || 0;
var el = this.offsetParent;
while (el) {
Ra.extend(el, Ra.Element.prototype);
if( el.tagName == 'BODY' ) {
break;
}
var pos = el.getStyle('position');
if( pos == 'relative' || pos == 'absolute') {
break;
}
valueT += el.offsetTop || 0;
valueL += el.offsetLeft || 0;
el = el.offsetParent;
}
"this" here is a DOM element...
However I suspect that what you have is absolutely positioned divs inside another div with position:relative in which case you can just use;
var y = parseInt(myElement.style.top, 10);
var x = parseInt(myElement.style.left, 10);
which will be orders of magnitudes faster then doing the "offset loops"...

Related

How to get Co-ordinates on onmouseup?

I have built a javascript application for dragging and dropping divs from one place to another in the same page. I have made the dragging part. I have the co-ordinates of the div(s) where I must drop the div but I am stuck at the part where I should introduce conditions for matching the divs at target zone. Basically the divs can be dropped above any of the divs but they must drop exactly above the target div if on onmouseup event I am anywhere close to that target div. I am thinking of assigning the top and left attribute of my dragged(onmousdown) div to the target div but I may be wrong.. Please guide my through this part.
Here is the part where I need help:
function mouseUp(e)
{
e = e || window.event;
var mousePos = mouseCoords(e);
var itemPosition = getPosition(id);
//console.log("This is at: "+itemPosition);
//console.log(mousePos);
console.log(getPosition(id));
for(var i=0;i<destination.length;i++)
{
var curTarget = destination[i];
var targPos = getPosition(curTarget);
var targWidth = parseInt(curTarget.offsetWidth);
var targHeight = parseInt(curTarget.offsetHeight);
var temp = document.elementFromPoint(event.clientX, event.clientY);
}
id = null;
}
Here is the link to my code: jsfiddle The javascript part must be written inside of html to make it work properly
The question title is misleading, what you really seem to be having trouble with is finding the coordinates of the target divs. You're grabbing mouse coordinates just fine using clientX and clientY though you likely want to be using the pageX and pageY coordinates as they are relative to the rendered page and not the viewport (ie. window the user is looking at). 0,0 using the client coordinates will change as the user scrolls whereas the page coordinates will reference a particular spot on the webpage.
As for finding your drop divs you can use the method getClientBoundingRect on the element and use the top, right, bottom, and left properties on the returned object to determine if the pageX and pageY coordinates of the mouse are inside (or close to inside) the element.
Maybe there's a better way, but this is how I would do it.
function mouseUp(e){
var targets = document.getElementsByClassName("drop_here");
for(var i=0;i<targets.length;i++){
var bounds = targets[i].getClientBoundingRect();
var lenience = 5;
if(e.pageX < bounds.right + lenience &&
e.pageX > bounds.left - lenience &&
e.pageY < bounds.top - lenience &&
e.pageY > bounds.bottom + lenience){
//do my work here
}
}
}

Vanilla JS Sticky Divs?

I'm trying to create a script that will keep divs fixed in their position no matter where they are on the screen when the page is scrolled... Basically, if a div is 50 px from the top, it will stay 50 px from the top of the current window. If a div is 0 px from the top, it will stay 0 px from the top.
I don't want a fixed div because of the cut-off problems they have... So please don't recommended changing the position to 'position: fixed;'...
A script I was working with was essentially doing the following:
window.onscroll = function() {
var elements = document.getElementsByClassName('sticky_div');
var doc = document.documentElement;
for (i = 0; i < elements.length; i++) {
rect = elements[i].getBoundingClientRect();
if (doc.scrollTop > rect.top) {
elements.style.top = doc.scrollTop + rect.top;
} else {
elements.style.top - doc.scrollTop - rect.top;
}
}
}
I'm sorry if that actually comes out wrong. I accidentally deleted my original code... Either way, the above method caused to be too laggy and it would jump the headers and divs. Are there any other ways of doing this using less over-the-top processing to do?
elements.style.top = doc.scrollTop; works very well but it won't allow for divs that are positioned elsewhere on the page...
Here's a JSFiddle for the reason why I don't want to use fixed divs (try scrolling horizontally):
https://jsfiddle.net/o27L3uss/

Check if whole div is visible in browser window

I have a product listing on my website and when hovering over the product an info div shows up. The only problem is that in some cases parts of the div fall outside of the browser window.
I need to check with Javascript if thats the case, and if so I need to assign a class to that particular div. I know how to do the last part, but I have no idea how to check if the whole div is visible.
Can anybody give me a suggestion how to handle this?
Your goal is to determine if your HTML element is in the viewport. If you're using jQuery - there are a few plugins tha handle this.
Jquery check if element is visible in viewport
http://opensource.teamdf.com/visible/examples/demo-basic.html
With the example above, you'd want to use detectPartial set to true -- so that you would know whether or not the thing is inside the viewport entirely.
//added by JG 3/10/2011, to extend selectors.
// Example:
//if ($('#whatever').is(':inView') ) {...}
jQuery.extend(jQuery.expr[':'], {
inView: function(a) {
var st = (document.documentElement.scrollTop || document.body.scrollTop),
ot = jQuery(a).offset().top,
wh = (window.innerHeight && window.innerHeight < jQuery(window).height()) ? window.innerHeight : jQuery(window).height();
return ot > st && (jQuery(a).height() + ot) < (st + wh);
}
});
I did that a number of years ago, based off of Remy Sharp's inview plugin (https://remysharp.com/2009/01/26/element-in-view-event-plugin) -- but these only check for vertical in-view, not horizontal (scrolling sideways/off the left or right).

Constraining the position on a resizable div

This effort is in response to my previously un-answered question: Resizable div doesn't stay within containment parameter
Since my resizable div, which is referred to as a pocket, is not the direct child of the container that I want it contained in, I supplied a callback in the resize method that should contain it within the container.
Fiddle here: http://jsfiddle.net/dKuER/12/
My Problem
When you re-size the resizable div to the left (which affects its left position) past the grid boundary, it does not always respect my logic in the callback function. As you drag to the left, you'll notice a blinking action, where the div will switch between its hard-coded left position to the left position determined by the mouse.
Depending on when you discontinue dragging, the left position of the div may either be at the hard-coded position or wherever the mouse stopped dragging.
How do I make sure the callback function's logic is ALWAYS respected?
// Relevant Code
// No blinking action when dealing with the width
//Re-sizing to the right works
if ( (pocketLeft + currentWidth) > (gridLeft + gridWidth) ) {
var deltaWidth = (gridLeft + gridWidth) - (pocketLeft + originalWidth);
ui.size.width = originalWidth -deltaWidth;
}
// This should force the position if the div is re-sized
// past the grid's left boundary
if (pocketLeft < gridLeft) {
ui.position.left = -120;
}
Using the mouse coordinates, and the width attained through the resizable div's object methods ( so obvious! ), rather than deriving it from some obscure calculations, I was able to achieve the correct effect
http://jsfiddle.net/dKuER/16/
var x = event.pageX - $('#grid').offset().left;
var y = event.pageY - $('#grid').offset().top;
if (x < 0)
{
ui.size.width = $(this).width();
ui.position.left = $(this).position().left;
}
I achieved this solution trying to understand the core of the jquery.ui.resizable code. However, I maintain there is more acceptable answer than mine.

javascript: finding the absolute size of an anchored link

I need to calculate the position, height and width of every anchored link in my page. I know how to find the x,y coords, but I have a problem with the height and width. The problem appears when the link has children inside (images, divs etc), so heightOffset and widthOffset won't work. Is there a way to do this without going on all the children and calculating their sizes?
EDIT:
Here is some code to demonstrate what I mean (the press function is called whenever the mouse is being pressed):
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
}
return [curleft,curtop];
}
function getHeight(elem) {
if (elem.style.pixelHeight) {
return elem.style.pixelHeight;
} else {
return elem.offsetHeight;
}
}
function getWidth(elem) {
if (elem.style.pixelWidth) {
return elem.style.pixelWidth;
} else {
return elem.offsetWidth;
}
}
function press(e)
{
x= e.pageX;
y= e.pageY;
window.alert(x+","+y);
var links = document.getElementsByTagName('a');
for (i = 0; i < links.length; i++){
var pos = findPos(links[i]);
window.alert(x+","+y+" "+pos[0]+" " + pos[1] + " "+links[i].offsetWidth+ " "+links[i].offsetHeight);
if (x >= pos[0] && x <= pos[0] + getWidth(links[i]) && y >= pos[1] && y <= pos[1] + getHeight(links[i])){
window.alert(links[i].href);
i = links.length;
}
}
}
When I encounter a link with an image for instance it doesn't return me the right size.
Thanks
offsetWidth/Height do very much work on links that contain images, as long as you haven't done anything weird like overflowing or positioning the images or other child content so that they fall out of the content area of their parent.
Your code isn't using offsetHeight on IE, it's using pixelHeight, which doesn't do what perhaps you think it does. Stick with offsetHeight.
Conversely, you are using event.pageX/Y, which is a non-standard extension IE doesn't have. Sadly the only reliable way to get page-relative co-ordinates from an event is to use clientX/Y and adjust for viewport scrolling.
I don't really know why you are going to the effort of enumerating link positions when for a mouse click/down event you can quite reliably get the element that was clicked on using event.target/srcElement. In fact this is the only reliable way to do it. Consider a link that has split over two text lines. Now what you've got is a non-rectangular region; you can't test whether a particular mouse position lies within that area using a simple x and y range test.
The correct properties are offsetHeight (not heightOffset) and offsetWidth (not widthOffset).
Those properties should correctly return the sizes you're after, because the children would expand the elements to fit, assuming overflow is set to visible. There's no need to calculate the sizes of the children in any situation.
offsetHeight and offsetWidth aren't part of any standard but most browsers seem to have them implemented anyway.
Since you're having problems with Safari and offsetHeight, maybe you could try the getClientRects() method:
http://www.quirksmode.org/dom/tests/rectangles.html
var dims = links[i].getClientRects()[0];
var width = dims.right - dims.left;
var height = dims.bottom - dims.top;
Can't say I've ever used getClientRects(), however. It sounds like the results may be closer to clientWidth and clientHeight.
FURTHER EDIT
I figured out a workaround. The following does not work:
<a href="#">
<img onclick="press(event);" src="http://sstatic.net/so/img/logo.png" alt="" />
<!-- onclick handler alerts with size 250x15 -->
</a>
But wrapping a <span> tag around the <img> tag, like so:
<a href="#"><span>
<img onclick="press(event);" src="http://sstatic.net/so/img/logo.png" />
<!-- onclick handler alerts with size 250x61 -->
</span></a>
Fixes the problem. At least, it does in Chrome but like I said before Chrome and Safari share the WebKit rendering engine, so it should work for Safari too.
You should not use the values in elem.style.* to determine the size of an element. These values are CSS styles and aren't reliable. Use only offsetWidth and offsetHeight.
To get the position of an element, use the answers to this question: Retrieve the position (X,Y) of an HTML element

Categories

Resources