Jquery中的offset()和position()深刻剖析(元素定位)

先看看這兩個方法的定義。
offset():
獲取匹配元素在當前視口的相對偏移。
返回的對象包含兩個整形屬性:top 和 left。此方法只對可見元素有效。
position():
獲取匹配元素相對父元素的偏移。
返回的對象包含兩個整形屬性:top 和 left。爲精確計算結果,請在補白、邊框和填充屬性上使用像素單位。此方法只對可見元素有效。
真的就這麼簡單嗎?實踐出真知。
先來看看在jquery框架源碼裏面,是怎麼得到position()的: javascript

 1 // Get *real* offsetParent 
 2 var offsetParent = this.offsetParent(), 
 3 // Get correct offsets 
 4 offset = this.offset(), 
 5 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset(); 
 6 // Subtract element margins 
 7 // note: when an element has margin: auto the offsetLeft and marginLeft 
 8 // are the same in Safari causing offset.left to incorrectly be 0 
 9 offset.top -= num( this, 'marginTop' ); 
10 offset.left -= num( this, 'marginLeft' ); 
11 // Add offsetParent borders 
12 parentOffset.top += num( offsetParent, 'borderTopWidth' ); 
13 parentOffset.left += num( offsetParent, 'borderLeftWidth' ); 
14 // Subtract the two offsets 
15 results = { 
16 top: offset.top - parentOffset.top, 
17 left: offset.left - parentOffset.left 
18 };

 



 

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
<title>offset和position測試1</title> 
<script type="text/javascript" src="http://img.jb51.net/jslib/jquery/jquery-1.3.2.js"></script> 
<style type="text/css"> 
body{margin:15px;width:960px;} 
.parent{ 
border:3px solid #ccc; 
width:600px; 
height:300px; 
margin-left:55px; 
padding:25px; 
} 
.child{ 
background:#666; 
width:200px; 
height:200px; 

color:#fff; 
} 
.copyright{ 
position:absolute; 
right:0; 
} 
</style> 
<script type="text/javascript"> 
$(document).ready(function(){ 
$(".child").each(function(){ 
var text = "position().left="+$(this).position().left; 
text +="<br>position().top="+$(this).position().top; 
text +="<br>offset().left="+$(this).offset().left; 
text +="<br>offset().top="+$(this).offset().top; 
text +="<br>其parent的offset().top="+$(this).parents(".parent").offset().top; 
text +="<br>其parent的offset().left="+$(this).parents(".parent").offset().left; 
$(this).html(text); 
}); 

}); 
</script> 
</head> 
<body> 

<div class="parent" style="float:right"> 
父容器的position是默認值,也就是static,子容器的position爲默認值,也是static,這個時候,offset和position值相同<br><br><br> 
<div class="child"></div> 
</div> 
<div style="clear:both"></div> 
<br> 
<div class="parent" style="position:relative"> 
父容器的position是相對定位,也就是ralative,子容器的position爲默認值,也是static,這個時候,offset和position值不一樣 
<div class="child"></div> 
</div> 
<br> 
<div style="position:absolute;padding:15px;border:3px solid #ff0000;"> 
<div class="parent"> 
父容器的position是絕對定位,也就是absolute,子容器的position爲默認值,也是static,這個時候,offset和position值不一樣 
<div class="child"></div> 
</div> 
</div> 

<div class="copyright"><a href="http://www.playgoogle.com">©playgoogle.com</a></div> 
</body> 
</html> 

 


經過test1頁面測試的結果能夠得出這個結論:
使用position()方法時事實上是把該元素當絕對定位來處理,獲取的是該元素至關於最近的一個擁有絕對或者相對定位的父元素的偏移位置。
使用position()方法時若是其全部的父元素都爲默認定位(static)方式,則其處理方式和offset()同樣,是當前窗口的相對偏移
使用offset()方法無論該元素如何定位,也無論其父元素如何定位,都是獲取的該元素相對於當前視口的偏移
知道了這些特色,咱們應該如何來合理的使用position()和offset()呢?
就我我的的經驗,一般獲取一個元素(A)的位置是爲了讓另外的一個元素(B)正好出如今A元素的附近。一般有2種狀況:
1.要顯示的元素B存放在DOM的最頂端或者最底端(即其父元素就是body).這個時候用offset()是最好的。示例驗證: css

 1  
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 3 <html xmlns="http://www.w3.org/1999/xhtml"> 
 4 <head> 
 5 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
 6 <title>offset和position測試1</title> 
 7 <script type="text/javascript" src="http://img.jb51.net/jslib/jquery/jquery-1.3.2.js"></script> 
 8 <style type="text/css"> 
 9 body{margin:15px;width:960px;} 
10 .parent{ 
11 border:3px solid #ccc; 
12 width:600px; 
13 height:300px; 
14 margin-left:55px; 
15 padding:25px; 
16 } 
17 input{ 
18 height:25px; 
19 float:right; 
20 } 
21 .copyright{ 
22 position:absolute; 
23 right:0; 
24 } 
25 .tip{ 
26 border:3px dotted #669900; 
27 background:#eee; 
28 width:200px; 
29 height:40px; 
30 position:absolute; 
31 display:none; 
32 } 
33 </style> 
34 <script type="text/javascript"> 
35 $(document).ready(function(){ 
36 $("input").bind("click",function(){ 
37 $(".tip").css({ 
38 left:$(this).offset().left+"px", 
39 top:$(this).offset().top+25+"px" 
40 }); 
41 $(".tip").toggle(); 
42 }); 
43 }); 
44 </script> 
45 </head> 
46 <body> 
47 用offset, 該例中元素B在DOM的最下面,也就是,其父容器爲body 
48 <div class="parent" style="position:absolute;left:150px"> 
49 父元素是絕對定位的 
50 <input type="button" value="點擊我,正好在個人下面顯示元素B,且左邊和我對齊"> 
51 </div> 
52 <br><br><br><br><br><br><br><br> 
53 <div class="tip"> 
54 我是元素B<br> 
55 如今用的是offset 
56 </div> 
57 </body> 
58 </html> 

 


用position沒法正常顯示的例子 html

 1  
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 3 <html xmlns="http://www.w3.org/1999/xhtml"> 
 4 <head> 
 5 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
 6 <title>offset和position測試1</title> 
 7 <script type="text/javascript" src="http://img.jb51.net/jslib/jquery/jquery-1.3.2.js"></script> 
 8 <style type="text/css"> 
 9 body{margin:15px;width:960px;} 
10 .parent{ 
11 border:3px solid #ccc; 
12 width:600px; 
13 height:300px; 
14 margin-left:55px; 
15 padding:25px; 
16 } 
17 input{ 
18 height:25px; 
19 float:right; 
20 } 
21 .copyright{ 
22 position:absolute; 
23 right:0; 
24 } 
25 .tip{ 
26 border:3px dotted #669900; 
27 background:#eee; 
28 width:200px; 
29 position:absolute; 
30 display:none; 
31 } 
32 </style> 
33 <script type="text/javascript"> 
34 $(document).ready(function(){ 
35 $("input").bind("click",function(){ 
36 $(".tip").css({ 
37 left:$(this).position().left+"px", 
38 top:$(this).position().top+25+"px" 
39 }); 
40 $(".tip").toggle(); 
41 }); 
42 }); 
43 </script> 
44 </head> 
45 <body> 
46 用position的例子, 該例中元素B的在DOM的最下面,也就是,其父容器爲body 
47 <div class="parent" style="position:absolute;left:150px"> 
48 父元素是絕對定位的 
49 <input type="button" value="點擊我,正好在個人下面顯示元素B,且左邊和我對齊"> 
50 </div> 
51 <br><br><br><br><br><br><br><br> 
52 <div class="tip"> 
53 我是元素B<br> 
54 如今用的是position<br> 
55 你會發現我如今的位置不正確 
56 </div> 
57 </body> 
58 </html> 

 


在以上兩個例子中,元素B都存放在Dom 結構的最下面,因爲其父元素就是BODY,因此,無論元素A如何定位,只要找的A至關與整個窗口的偏移位置,就能夠解決問題。

2.若要顯示的元素B存放在元素A的同一父元素下(即B爲A的兄弟節點),這個時候使用position() 是最合適的。
用offset 正常顯示的例子 java

 1  
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 3 <html xmlns="http://www.w3.org/1999/xhtml"> 
 4 <head> 
 5 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
 6 <title>offset和position測試1</title> 
 7 <script type="text/javascript" src="http://img.jb51.net/jslib/jquery/jquery-1.3.2.js"></script> 
 8 <style type="text/css"> 
 9 body{margin:15px;width:960px;} 
10 .parent{ 
11 border:3px solid #ccc; 
12 width:600px; 
13 height:300px; 
14 margin-left:55px; 
15 padding:25px; 
16 } 
17 input{ 
18 height:25px; 
19 float:right; 
20 } 
21 .copyright{ 
22 position:absolute; 
23 right:0; 
24 } 
25 .tip{ 
26 border:3px dotted #669900; 
27 background:#eee; 
28 width:200px; 
29 position:absolute; 
30 display:none; 
31 } 
32 </style> 
33 <script type="text/javascript"> 
34 $(document).ready(function(){ 
35 $("input").bind("click",function(){ 
36 $(".tip").css({ 
37 left:$(this).position().left+"px", 
38 top:$(this).position().top+25+"px" 
39 }); 
40 $(".tip").toggle(); 
41 }); 
42 }); 
43 </script> 
44 </head> 
45 <body> 
46 用position, 該例中元素B在button按鈕的附近,也就是,元素B和button按鈕有共同的父容器 
47 <div class="parent" style="position:absolute;left:150px"> 
48 父元素是絕對定位的 
49 <input type="button" value="點擊我,正好在個人下面顯示元素B,且左邊和我對齊"> 
50 <div class="tip"> 
51 我是元素B<br> 
52 如今用的是position, 
53 我和按鈕的父親元素相同<br> 
54 我能按要求正常顯示 
55 </div> 
56 </div> 
57 <br><br><br><br><br><br><br><br> 
58 </body> 
59 </html> 
View Code

 


用offset五法正常顯示的例子 jquery

 1  
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 3 <html xmlns="http://www.w3.org/1999/xhtml"> 
 4 <head> 
 5 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
 6 <title>offset和position測試1</title> 
 7 <script type="text/javascript" src="http://img.jb51.net/jslib/jquery/jquery-1.3.2.js"></script> 
 8 <style type="text/css"> 
 9 body{margin:15px;width:960px;} 
10 .parent{ 
11 border:3px solid #ccc; 
12 width:600px; 
13 height:300px; 
14 margin-left:55px; 
15 padding:25px; 
16 } 
17 input{ 
18 height:25px; 
19 float:right; 
20 } 
21 .copyright{ 
22 position:absolute; 
23 right:0; 
24 } 
25 .tip{ 
26 border:3px dotted #669900; 
27 background:#eee; 
28 width:200px; 
29 position:absolute; 
30 display:none; 
31 } 
32 </style> 
33 <script type="text/javascript"> 
34 $(document).ready(function(){ 
35 $("input").bind("click",function(){ 
36 $(".tip").css({ 
37 left:$(this).offset().left+"px", 
38 top:$(this).offset().top+25+"px" 
39 }); 
40 $(".tip").toggle(); 
41 }); 
42 }); 
43 </script> 
44 </head> 
45 <body> 
46 用offset, 該例中元素B在button按鈕的附近,也就是,元素B和button按鈕有共同的父容器 
47 <div class="parent" style="position:absolute;left:150px"> 
48 父元素是絕對定位的 
49 <input type="button" value="點擊我,正好在個人下面顯示元素B,且左邊和我對齊"> 
50 
51 <div class="tip"> 
52 我是元素B<br> 
53 如今用的是offset, 
54 我和按鈕的父親元素相同 
55 我沒法按要求正常顯示 
56 </div> 
57 </div> 
58 <br><br><br><br><br><br><br><br> 
59 </body> 
60 </html> 
View Code

 


綜上所述,應該使用position()仍是offset()取決於你被控制的元素B DOM所在的位置。框架

相關文章