先看看這兩個方法的定義。
offset():
擷取匹配元素在當前視口的相對位移。
返回的對象包含兩個整形屬性:top 和 left。此方法只對可見元素有效。
position():
擷取匹配元素相對父元素的位移。
返回的對象包含兩個整形屬性:top 和 left。為精確計算結果,請在補白、邊框和填充屬性上使用像素單位。此方法只對可見元素有效。
真的就這麼簡單嗎?實踐出真知。
先來看看在jquery架構源碼裡面,是怎麼獲得position()的:
複製代碼 代碼如下:
// Get *real* offsetParent
var offsetParent = this.offsetParent(),
// Get correct offsets
offset = this.offset(),
parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
// Subtract element margins
// note: when an element has margin: auto the offsetLeft and marginLeft
// are the same in Safari causing offset.left to incorrectly be 0
offset.top -= num( this, 'marginTop' );
offset.left -= num( this, 'marginLeft' );
// Add offsetParent borders
parentOffset.top += num( offsetParent, 'borderTopWidth' );
parentOffset.left += num( offsetParent, 'borderLeftWidth' );
// Subtract the two offsets
results = {
top: offset.top - parentOffset.top,
left: offset.left - parentOffset.left
};
點擊下面的頁面可以測試一下兩個的區別:
<!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" > 父容器的position是預設值,也就是static,子容器的position為預設值,也是static,這個時候,offset和position值相同<br><br><br> <div class="child"></div> </div> <div ></div> <br> <div class="parent" > 父容器的position是相對定位,也就是ralative,子容器的position為預設值,也是static,這個時候,offset和position值不同 <div class="child"></div> </div> <br> <div > <div class="parent"> 父容器的position是絕對位置,也就是absolute,子容器的position為預設值,也是static,這個時候,offset和position值不同 <div class="child"></div> </div> </div> <div class="copyright">©playgoogle.com</div> </body> </html>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
通過test1頁面測試的結果可以得出這個結論:
使用position()方法時事實上是把該元素當絕對位置來處理,擷取的是該元素相當於最近的一個擁有絕對或者相對定位的父元素的位移位置。
使用position()方法時如果其所有的父元素都為預設定位(static)方式,則其處理方式和offset()一樣,是當前視窗的相對位移
使用offset()方法不管該元素如何定位,也不管其父元素如何定位,都是擷取的該元素相對於當前視口的位移
知道了這些特點,我們應該如何來合理的使用position()和offset()呢?
就我個人的經驗,通常擷取一個元素(A)的位置是為了讓另外的一個元素(B)正好出現在A元素的附近。通常有2種情況:
1.要顯示的元素B存放在DOM的最頂端或者最底端(即其父元素就是body).這個時候用offset()是最好的。樣本驗證:
<!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; } input{ height:25px; float:right; } .copyright{ position:absolute; right:0; } .tip{ border:3px dotted #669900; background:#eee; width:200px; height:40px; position:absolute; display:none; } </style> <script type="text/javascript"> $(document).ready(function(){ $("input").bind("click",function(){ $(".tip").css({ left:$(this).offset().left+"px", top:$(this).offset().top+25+"px" }); $(".tip").toggle(); }); }); </script> </head> <body> 用offset, 該例中元素B在DOM的最下面,也就是,其父容器為body <div class="parent" > 父元素是絕對位置的 <input type="button" value="點擊我,正好在我的下面顯示元素B,且左邊和我對齊"> </div> <br><br><br><br><br><br><br><br> <div class="tip"> 我是元素B<br> 現在用的是offset </div> </body> </html>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
用position無法正常顯示的例子
<!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; } input{ height:25px; float:right; } .copyright{ position:absolute; right:0; } .tip{ border:3px dotted #669900; background:#eee; width:200px; position:absolute; display:none; } </style> <script type="text/javascript"> $(document).ready(function(){ $("input").bind("click",function(){ $(".tip").css({ left:$(this).position().left+"px", top:$(this).position().top+25+"px" }); $(".tip").toggle(); }); }); </script> </head> <body> 用position的例子, 該例中元素B的在DOM的最下面,也就是,其父容器為body <div class="parent" > 父元素是絕對位置的 <input type="button" value="點擊我,正好在我的下面顯示元素B,且左邊和我對齊"> </div> <br><br><br><br><br><br><br><br> <div class="tip"> 我是元素B<br> 現在用的是position<br> 你會發現我現在的位置不正確 </div> </body> </html>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
在以上兩個例子中,元素B都存放在Dom 結構的最下面,由於其父元素就是BODY,所以,不管元素A如何定位,只要找的A相當與整個視窗的位移位置,就可以解決問題。
2.若要顯示的元素B存放在元素A的同一父元素下(即B為A的兄弟節點),這個時候使用position() 是最合適的。
用offset 正常顯示的例子
<!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; } input{ height:25px; float:right; } .copyright{ position:absolute; right:0; } .tip{ border:3px dotted #669900; background:#eee; width:200px; position:absolute; display:none; } </style> <script type="text/javascript"> $(document).ready(function(){ $("input").bind("click",function(){ $(".tip").css({ left:$(this).position().left+"px", top:$(this).position().top+25+"px" }); $(".tip").toggle(); }); }); </script> </head> <body> 用position, 該例中元素B在button按鈕的附近,也就是,元素B和button按鈕有共同的父容器 <div class="parent" > 父元素是絕對位置的 <input type="button" value="點擊我,正好在我的下面顯示元素B,且左邊和我對齊"> <div class="tip"> 我是元素B<br> 現在用的是position, 我和按鈕的父親元素相同<br> 我能按要求正常顯示 </div> </div> <br><br><br><br><br><br><br><br> </body> </html>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
用offset五法正常顯示的例子
<!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; } input{ height:25px; float:right; } .copyright{ position:absolute; right:0; } .tip{ border:3px dotted #669900; background:#eee; width:200px; position:absolute; display:none; } </style> <script type="text/javascript"> $(document).ready(function(){ $("input").bind("click",function(){ $(".tip").css({ left:$(this).offset().left+"px", top:$(this).offset().top+25+"px" }); $(".tip").toggle(); }); }); </script> </head> <body> 用offset, 該例中元素B在button按鈕的附近,也就是,元素B和button按鈕有共同的父容器 <div class="parent" > 父元素是絕對位置的 <input type="button" value="點擊我,正好在我的下面顯示元素B,且左邊和我對齊"> <div class="tip"> 我是元素B<br> 現在用的是offset, 我和按鈕的父親元素相同 我無法按要求正常顯示 </div> </div> <br><br><br><br><br><br><br><br> </body> </html>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
綜上所述,應該使用position()還是offset()取決於你被控制的元素B DOM所在的位置。