摘要:也就是說的本質為參數的屬性減去對應的默認屬性加上上的對應屬性。所以的本質即相對于,對其,進行操作,而不是像那樣相對于左上角原點進行操作這樣就需要先減去中的的值了。
一、offset()
作用:
返回被選元素相對于文檔(document)的偏移坐標
二、三種情況使用:
1、$().offset()
這是divTwo
源碼:
//返回目標元素相對于doucument的偏移坐標, //即距離瀏覽器左上角的距離 // 返回偏移坐標:$(selector).offset() // 設置偏移坐標:$(selector).offset({top:value,left:value}) // 使用函數設置偏移坐標:$(selector).offset(function(index,currentoffset)) // offset() relates an element"s border box to the document origin //源碼10500行 //options即參數 //arguments是參數對象 offset: function( options ) { // Preserve chaining for setter //如果是有參數的,參數是undefined則返回目標元素本身, //否則為每個目標元素設置options console.log(options,arguments,"arguments10476") //$().offset()不走這里 if ( arguments.length ) { console.log("aaa","vvv10507") return options === undefined ? this : this.each( function( i ) { //為每個目標元素設置options jQuery.offset.setOffset( this, options, i ); } ); } var rect, win, //獲取DOM節點 elem = this[ 0 ]; if ( !elem ) { return; } // jQuery不支持獲取隱藏元素的偏移坐標。 // 同理,也無法取得隱藏元素的 border, margin, 或 padding 信息 //所以如果元素是隱藏的,默認返回0值 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) // Support: IE <=11 only // Running getBoundingClientRect on a // disconnected node in IE throws an error //對IE的特殊處理 if ( !elem.getClientRects().length ) { return { top: 0, left: 0 }; } // Get document-relative position by adding viewport scroll to viewport-relative gBCR //返回元素的大小及其相對于視口的位置 //https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect rect = elem.getBoundingClientRect(); //返回所屬文檔的默認窗口對象(只讀) //原點坐標 win = elem.ownerDocument.defaultView; //pageXOffset,pageYOffset 相當于 scrollX 和 scrollY //返回文檔在窗口左上角水平 x 和垂直 y 方向滾動的像素 return { //16 0 // top: rect.top + win.pageYOffset, //8 0 left: rect.left + win.pageXOffset }; },
解析:
由于$().offset()沒有參數,所以源碼里的兩個 if 可以忽略,所以offset()的本質即:
let p = document.getElementById("pTwo"); let rect=p.getBoundingClientRect() //返回所屬文檔的默認窗口對象(只讀) //原點坐標 let win = p.ownerDocument.defaultView; let offsetObj={ top: rect.top + win.pageYOffset, left: rect.left + win.pageXOffset } console.log(offsetObj,"win18")
(1)getBoundingClientRect()
該方法用于獲取某個元素相對于視窗的位置集合,并返回一個對象,該對象中有top, right, bottom, left等屬性,簡單點就是相對于原坐標(默認是左上角)的偏移量
(2)window.pageXOffset、window.pageYOffset
返回文檔在窗口左上角水平 x 和垂直 y 方向滾動的像素,相當于 scrollX 和 scrollY,簡單點就是滾動的偏移量
所以offset()的本質即:
相對于原坐標的偏移量+滾動的偏移量的總和。
2、$().offset({top:15,left:15})
$("#pTwo").offset({top:15,left:15})
源碼:
當有參數的時候,就會走 if 中,通過jQuery.offset.setOffset( )來處理:
if ( arguments.length ) { return options === undefined ? this : this.each( function( i ) { //為每個目標元素設置options jQuery.offset.setOffset( this, options, i ); } ); }
jQuery.offset.setOffset( )
//offset()的關鍵方法 //源碼10403行 jQuery.offset = { setOffset: function( elem, options, i ) { var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, //獲取元素的position屬性的值 //static position = jQuery.css( elem, "position" ), //過濾成標準jQuery對象 curElem = jQuery( elem ), props = {}; // Set position first, in-case top/left are set even on static elem //指定相對定位relative if ( position === "static" ) { elem.style.position = "relative"; } //{left:8,top:16} curOffset = curElem.offset(); //0px curCSSTop = jQuery.css( elem, "top" ); //0px curCSSLeft = jQuery.css( elem, "left" ); // 如果定位position是(絕對定位absolute或固定定位fixed), // 并且top,left屬性包含auto的話 //false calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; // Need to be able to calculate position if either // top or left is auto and position is either absolute or fixed if ( calculatePosition ) { curPosition = curElem.position(); curTop = curPosition.top; curLeft = curPosition.left; } else { //0 0 curTop = parseFloat( curCSSTop ) || 0; curLeft = parseFloat( curCSSLeft ) || 0; } //如果傳的參數是function{}的話 if ( isFunction( options ) ) { // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); } //如果傳的參數的有top值 if ( options.top != null ) { //參數 top - offset().top + element.top props.top = ( options.top - curOffset.top ) + curTop; } //如果傳的參數的有left值 if ( options.left != null ) { //參數 left - offset().left + element.left props.left = ( options.left - curOffset.left ) + curLeft; } //自己沒見過使用 using 的情況。。 if ( "using" in options ) { options.using.call( elem, props ); } //所以一般走這里,為當前元素設置top,left屬性 else { //position:relative //top:xxx //left:xxx curElem.css( props ); } } };
解析:
(1)先判斷當前元素的 position 的值,沒有設置 position 屬性的話,默認為 relative,并獲取元素的 top、left 屬性的值
(2)返回一個對象 obj,obj 的 top 是參數的 top - 默認偏移(offset)的 top + position 設置的 top(沒有設置,默認為0),obj 的 left 同理。
也就是說 offset({top:15,;eft:15}) 的本質為:
參數的屬性減去對應的默認offset屬性加上position上的對應屬性。
//偽代碼 offset().top = elem. getBoundingClientRect().top + document. pageYOffset top: offset({top:15}).top - offset().top + position.top 也就是: offset({top:15}).top - (elem. getBoundingClientRect().top + document. pageYOffset) + position.top
3、$().offset(function(){})
$("#pTwo").offset(function(index,currentoffset){ let newPos={}; newPos.left=currentoffset.left+15; newPos.top=currentoffset.top+15; return newPos; });
源碼:
//如果傳的參數是function{}的話 if ( isFunction( options ) ) { // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); }
解析:
讓當前元素通過call 去調用參數中的 function(){} 方法,call 的參數必須一個一個放進去,上面源碼中,call 參數有 i、jQuery.extend( {}, curOffset )
jQuery.extend( {}, curOffset )
暫不解析jQuery.extend() ,但這里的作用 不用看源碼,也知道是將 element.offset() 的屬性賦值給新建的空對象 {} 。
所以 $().offset(function(){}) 的本質即:相對于 element.offset() ,對其 top,left進行操作,而不是像 offset({top:xxx,left:xxx}) 那樣相對于左上角原點進行操作(這樣就需要先減去offset()中的top、left的值了)。
本文結束,五一愉快~
(完)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104064.html
摘要:注意的本質是的解析整體上看,是一個語句由于的元素,是相對于瀏覽器窗口進行定位的,所以它的偏移就是,即獲取某個元素相對于視窗的位置。注意的本質是的完 showImg(https://segmentfault.com/img/remote/1460000019072306); position()作用:返回被選元素相對于父元素(parent)的偏移坐標 使用:直接調用$().positio...
摘要:獲得當前元素相對于的位置。返回一個對象含有和當給定一個含有和屬性對象時,使用這些值來對集合中每一個元素進行相對于的定位。獲取對象集合中第一個元素相對于其的位置。結尾以上就是中與偏移相關的幾個的解析,歡迎指出其中的問題和有錯誤的地方。 前言 這篇文章主要想說一下Zepto中與偏移相關的一些事,很久很久以前,我們經常會使用offset、position、scrollTop、scrollLe...
摘要:干想了半天,認為可能還是本身的寫法問題。對象提供了一種通過定義函數來獲取或設置特定值的方法。簡單來說,給我們暴露了一個鉤子,我們可以自己定義方法比如,來實現針對某個屬性的特定行為。 寫在最前 本次分享一下在一次jQuery賦值樣式失效的結果中來分析背后原因的過程。在翻jQuery源碼的過程中,感覺真是還不能說自己只是會用jQuery,我好像連會用都達不到(逃 歡迎關注我的博客,不定期更...
摘要:干想了半天,認為可能還是本身的寫法問題。對象提供了一種通過定義函數來獲取或設置特定值的方法。簡單來說,給我們暴露了一個鉤子,我們可以自己定義方法比如,來實現針對某個屬性的特定行為。 寫在最前 本次分享一下在一次jQuery賦值樣式失效的結果中來分析背后原因的過程。在翻jQuery源碼的過程中,感覺真是還不能說自己只是會用jQuery,我好像連會用都達不到(逃 歡迎關注我的博客,不定期更...
閱讀 3222·2021-11-11 16:55
閱讀 2458·2021-10-13 09:39
閱讀 2392·2021-09-13 10:27
閱讀 2155·2019-08-30 15:55
閱讀 3083·2019-08-30 15:54
閱讀 3127·2019-08-29 16:34
閱讀 1819·2019-08-29 12:41
閱讀 1065·2019-08-29 11:33