Solved

jQuery .position() behaving weird.

Posted on 2013-06-03
5
322 Views
Last Modified: 2013-06-03
I want to put a translucent screen over a div so I can show an image on top of the screen without the div contents being a distraction. The main div could move around so I read its current width, height, and offset with jQuery and then apply those to the screen. But the screen appears in a different place each time!

There's a jsfiddle here: http://jsfiddle.net/bdWW3/1/

When you click Screen On the screen is applied. When you click Screen Off the screen is removed. When you click Screen On again the screen is applied, but it appears in a different place, no longer exactly over the canvas div. But console.log shows exactly the same parameters being put into the jQuery offset() call!?  The new position seems to depend on where the element was before. The offset given to position() is added to something, but http://api.jquery.com/offset says that the coordinates passed to the offset() method are "integers indicating the new top and left coordinates for the elements."

Does anyone see what's going on?

Thanks
0
Comment
Question by:steva
  • 3
  • 2
5 Comments
 
LVL 82

Expert Comment

by:leakim971
ID: 39216396
Check the first example, line 13 : http://api.jquery.com/offset
code updated : http://jsfiddle.net/bdWW3/3/
0
 

Author Comment

by:steva
ID: 39216609
Hi leakim,

Thanks for the solution, but I don't understand it.  

For some reason

canvasOffset = $('#canvas').offset();
$('#canvasScreen').css(left:canvasOffset.left, top:canvasOffset.top});

Open in new window

works but

canvasOffset = $('#canvas').offset();
$('#canvasScreen').offset(canvasOffset);

Open in new window

doesn't.  

Do you see why?
0
 

Author Comment

by:steva
ID: 39216689
Ah!  I got it!

 I was applying .offset() to an element that had no width and no height, which gave unreliable results. I have to "display:block" the element before applying an offset to it.  Just changing the order of the methods in the chain works, so that offset happens after display:block:

$('#canvasScreen').width(canvasWidth).height(canvasHeight).css({'opacity':'0.7', 'display' : 'block'}).offset(canvasOffset);
0
 
LVL 82

Accepted Solution

by:
leakim971 earned 500 total points
ID: 39216695
if you check carefully, it add the offset (top and left values) each time. first time is good because top and left are null or zero
This is the way it work, if you check the code you will see :
		if ( options.top != null ) {
			props.top = ( options.top - curOffset.top ) + curTop;
		}
		if ( options.left != null ) {
			props.left = ( options.left - curOffset.left ) + curLeft;
		}
                curElem.css( props );

Open in new window

0
 

Author Comment

by:steva
ID: 39216839
Yes, I can see what the actual jQuery offset() code does internally, but the offset reference doesn't say anything about adding the offset you provide to the element's existing offset.  The reference says offset() makes the offset you give it the document offset of the element, regardless of what the element's offset was before. Not said there is that applying offset() to a "display:none" element behaves differently.  When I have more time maybe I'll break down the internal jQuery offset() code to understand exactly what was happening, but for now just making sure that  the element is displayed before applying offset() to it works for me, so I'm moving on.    

Thanks for your help, Leakim.  I gave you the points.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now