Solved

jQuery .position() behaving weird.

Posted on 2013-06-03
5
328 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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 …
How to build a simple, quick and effective accordion menu using just 15 lines of jQuery and 2 css classes
The viewer will learn how to dynamically set the form action using jQuery.
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)

717 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