摘要:注意的本質(zhì)是的解析整體上看,是一個(gè)語句由于的元素,是相對(duì)于瀏覽器窗口進(jìn)行定位的,所以它的偏移就是,即獲取某個(gè)元素相對(duì)于視窗的位置。注意的本質(zhì)是的完
position()
作用:
返回被選元素相對(duì)于父元素(parent)的偏移坐標(biāo)
使用:
直接調(diào)用$().position()即可,該方法沒有 arguments(參數(shù)對(duì)象)
這是divTwo
源碼:
// 返回被選元素相對(duì)于父元素(parent)的偏移坐標(biāo) // 可以理解成被選元素設(shè)置為absolute, // 然后設(shè)置left、top的值就是相對(duì)于父元素的偏移坐標(biāo) // 源碼10571行 // position() relates an element"s margin box to its offset parent"s padding box // This corresponds to the behavior of CSS absolute positioning position: function() { // 如果DOM元素不存在,直接返回 if ( !this[ 0 ] ) { return; } var offsetParent, offset, doc, elem = this[ 0 ], parentOffset = { top: 0, left: 0 }; // position:fixed elements are offset from the viewport, which itself always has zero offset // position:fixed的元素,是相對(duì)于瀏覽器窗口進(jìn)行定位的, // 所以它的偏移就是getBoundingClientRect(),即獲取某個(gè)元素相對(duì)于視窗的位置 if ( jQuery.css( elem, "position" ) === "fixed" ) { // Assume position:fixed implies availability of getBoundingClientRect offset = elem.getBoundingClientRect(); } // 除去position是fixed的情況 else { // 獲取被選元素相對(duì)于文檔(document)的偏移坐標(biāo) offset = this.offset(); // Account for the *real* offset parent, which can be the document or its root element // when a statically positioned element is identified doc = elem.ownerDocument; //定位目標(biāo)元素的父元素(position不為static的元素) offsetParent = elem.offsetParent || doc.documentElement; // 如果父元素是/的話,將父元素重新定位為它們的父元素 // body的父元素是html,html的父元素是document while ( offsetParent && ( offsetParent === doc.body || offsetParent === doc.documentElement ) && jQuery.css( offsetParent, "position" ) === "static" ) { offsetParent = offsetParent.parentNode; } // 如果定位父元素存在,并且不等于目標(biāo)元素,并且定位元素類型是 "元素類型" if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { // Incorporate borders into its offset, since they are outside its content origin parentOffset = jQuery( offsetParent ).offset(); // 這兩行代碼的意思是父元素的offset()要從padding算起,不包括border // 所以需要去掉border // jQuery.css( element, "borderTopWidth", true )的 true 表示返回?cái)?shù)字,而不帶單位 px parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); } } // Subtract parent offsets and element margins // 可以看出,$().position()的本質(zhì)是目標(biāo)元素的offset()減去父元素的offset(),同時(shí)還要算上目標(biāo)元素的margin,因?yàn)楹凶幽P停P(guān)鍵)。 //(注意:offset()的本質(zhì)是getBoundingClientRect()的top、left + pageYOffset、pageXOffset) return { top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) }; },
解析:
整體上看,是一個(gè) if(...fixed) { } esle { } 語句
(1)if ( jQuery.css( elem, "position" ) === "fixed" )
if ( jQuery.css( elem, "position" ) === "fixed" ) { // Assume position:fixed implies availability of getBoundingClientRect offset = elem.getBoundingClientRect(); } return { top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) };
由于position:fixed的元素,是相對(duì)于瀏覽器窗口進(jìn)行定位的,所以它的偏移就是getBoundingClientRect(),即獲取某個(gè)元素相對(duì)于視窗的位置。
注意:
① getBoundingClientRect() 計(jì)算的是目標(biāo)元素的border的位置(左上角),是不包括margin的
② 如果不加上margin的話(代碼是通過減去,來算上margin的),是不準(zhǔn)確的,看下圖
所以源碼最后會(huì):
- jQuery.css( elem, "marginTop", true ) - jQuery.css( elem, "marginLeft", true )
(2)jQuery.css( elem, "width", true )
true的作用是返回該屬性的數(shù)字,而不帶單位 px
(3)定位父元素存在,并且不等于目標(biāo)元素,并且定位元素類型是 "元素類型"的話
if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 )
是要減去border屬性的值的
parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
為啥?舉個(gè)例子:
let p=document.querySelector("#pTwo") console.log(p.getBoundingClientRect(),"pTwo11"); //x:8,y:16
設(shè)置 borderLeftWidth 為 8 像素
let p=document.querySelector("#pTwo") p.style.borderLeftWidth="8px" console.log(p.getBoundingClientRect(),"pTwo11"); //x:8,y:16
可以看到getBoundingClientRect()指定坐標(biāo)是到border上的,這是不準(zhǔn)確的,因?yàn)樵诶锩娴淖釉氐奈恢靡矔?huì)受父元素的border影響,所以父元素的坐標(biāo)需要越過border
綜上:
可以看出,$().position()的本質(zhì)是目標(biāo)元素的 offset() 減去父元素的 offset(),同時(shí)還要算上目標(biāo)元素的 margin,算上父元素的border。
(注意:offset()的本質(zhì)是getBoundingClientRect()的top、left + pageYOffset、pageXOffset)
Github:
https://github.com/AttackXiao...
(完)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104106.html
摘要:也就是說的本質(zhì)為參數(shù)的屬性減去對(duì)應(yīng)的默認(rèn)屬性加上上的對(duì)應(yīng)屬性。所以的本質(zhì)即相對(duì)于,對(duì)其,進(jìn)行操作,而不是像那樣相對(duì)于左上角原點(diǎn)進(jìn)行操作這樣就需要先減去中的的值了。 showImg(https://upload-images.jianshu.io/upload_images/5518628-d5ec366642ca36ab.jpg?imageMogr2/auto-orient/strip...
摘要:前言需要先看源碼解析之和一舉例的寬度先變成,再變成,最后變成這是在異步調(diào)用中,進(jìn)行同步調(diào)用動(dòng)畫是異步的就是連續(xù)調(diào)用二作用通過樣式將元素從一個(gè)狀態(tài)改變?yōu)榱硪粋€(gè)狀態(tài)源碼之前有說過是的方法源碼行是否是空對(duì)象,方法執(zhí)行單個(gè)動(dòng)畫的封裝的本質(zhì)是執(zhí)行 showImg(https://segmentfault.com/img/remote/1460000019594521); 前言:需要先看 jQue...
摘要:五作用的關(guān)鍵方法,用來從目標(biāo)節(jié)點(diǎn)克隆數(shù)據(jù)添加事件給克隆的元素注意采用數(shù)據(jù)分離的方法來保存上的事件和數(shù)據(jù),利用標(biāo)記每個(gè)元素,然后在內(nèi)存上,將每個(gè)元素相關(guān)的數(shù)據(jù)放到內(nèi)存中,然后在和內(nèi)存的數(shù)據(jù)之間建立映射。 showImg(https://segmentfault.com/img/remote/1460000018991125); 前言:這篇講完后,jQuery的文檔處理就告一段落了,有空我...
摘要:一起源方法最終是用綁定事件的而方法正是等于二作用觸發(fā)綁定的事件的處理程序源碼源碼行即原生觸發(fā)事件的處理程序修正對(duì)象獲取事件的處理程序集合,結(jié)構(gòu)如下從數(shù)據(jù)緩存中獲取事件處理集合即目標(biāo)元素委托目標(biāo)這段代碼壓根不會(huì)執(zhí)行,因?yàn)槿炙阉鳑]找到結(jié)構(gòu) showImg(https://segmentfault.com/img/remote/1460000019464031); 一、起源jQuery.e...
閱讀 3225·2021-11-10 11:35
閱讀 1321·2019-08-30 13:20
閱讀 1145·2019-08-29 16:18
閱讀 2160·2019-08-26 13:54
閱讀 2184·2019-08-26 13:50
閱讀 982·2019-08-26 13:39
閱讀 2509·2019-08-26 12:08
閱讀 1974·2019-08-26 10:37