成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

jQuery源碼解析之offset()

keke / 2354人閱讀

摘要:也就是說的本質(zhì)為參數(shù)的屬性減去對應(yīng)的默認(rèn)屬性加上上的對應(yīng)屬性。所以的本質(zhì)即相對于,對其,進(jìn)行操作,而不是像那樣相對于左上角原點(diǎn)進(jìn)行操作這樣就需要先減去中的的值了。

一、offset()

作用:
返回被選元素相對于文檔(document)的偏移坐標(biāo)

二、三種情況使用:

1、$().offset()



這是divTwo

源碼:

   //返回目標(biāo)元素相對于doucument的偏移坐標(biāo),
    //即距離瀏覽器左上角的距離

    // 返回偏移坐標(biāo):$(selector).offset()
    // 設(shè)置偏移坐標(biāo):$(selector).offset({top:value,left:value})
    // 使用函數(shù)設(shè)置偏移坐標(biāo):$(selector).offset(function(index,currentoffset))
    // offset() relates an element"s border box to the document origin
    //源碼10500行
    //options即參數(shù)
    //arguments是參數(shù)對象
    offset: function( options ) {
      // Preserve chaining for setter
      //如果是有參數(shù)的,參數(shù)是undefined則返回目標(biāo)元素本身,
      //否則為每個目標(biāo)元素設(shè)置options
      console.log(options,arguments,"arguments10476")
      //$().offset()不走這里
      if ( arguments.length ) {
        console.log("aaa","vvv10507")
        return options === undefined ?
          this :
          this.each( function( i ) {
            //為每個目標(biāo)元素設(shè)置options
            jQuery.offset.setOffset( this, options, i );
          } );
      }

      var rect, win,
        //獲取DOM節(jié)點(diǎn)
        elem = this[ 0 ];

      if ( !elem ) {
        return;
      }

      // jQuery不支持獲取隱藏元素的偏移坐標(biāo)。
      // 同理,也無法取得隱藏元素的 border, margin, 或 padding 信息
      //所以如果元素是隱藏的,默認(rèn)返回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();
      //返回所屬文檔的默認(rèn)窗口對象(只讀)
      //原點(diǎn)坐標(biāo)
      win = elem.ownerDocument.defaultView;
      //pageXOffset,pageYOffset 相當(dāng)于 scrollX 和 scrollY 
      //返回文檔在窗口左上角水平 x 和垂直 y 方向滾動的像素
      return {
        //16    0
        //
        top: rect.top + win.pageYOffset,
        //8     0
        left: rect.left + win.pageXOffset
      };
    },

解析:
由于$().offset()沒有參數(shù),所以源碼里的兩個 if 可以忽略,所以offset()的本質(zhì)即:

  let p = document.getElementById("pTwo");
  let rect=p.getBoundingClientRect()
  //返回所屬文檔的默認(rèn)窗口對象(只讀)
  //原點(diǎn)坐標(biāo)
  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等屬性,簡單點(diǎn)就是相對于原坐標(biāo)(默認(rèn)是左上角)的偏移量

(2)window.pageXOffset、window.pageYOffset
返回文檔在窗口左上角水平 x 和垂直 y 方向滾動的像素,相當(dāng)于 scrollX 和 scrollY,簡單點(diǎn)就是滾動的偏移量

所以offset()本質(zhì)即:
相對于原坐標(biāo)的偏移量+滾動的偏移量的總和。

2、$().offset({top:15,left:15})

$("#pTwo").offset({top:15,left:15})

源碼:
當(dāng)有參數(shù)的時候,就會走 if 中,通過jQuery.offset.setOffset( )來處理:

 if ( arguments.length ) {
        return options === undefined ?
          this :
          this.each( function( i ) {
            //為每個目標(biāo)元素設(shè)置options
            jQuery.offset.setOffset( this, options, i );
          } );
      }

jQuery.offset.setOffset( )

  //offset()的關(guān)鍵方法
  //源碼10403行
  jQuery.offset = {
    setOffset: function( elem, options, i ) {
      var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
        //獲取元素的position屬性的值
        //static
        position = jQuery.css( elem, "position" ),
        //過濾成標(biāo)準(zhǔn)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;
      }
      //如果傳的參數(shù)是function{}的話
      if ( isFunction( options ) ) {

        // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
        options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
      }
      //如果傳的參數(shù)的有top值
      if ( options.top != null ) {
        //參數(shù) top - offset().top + element.top
        props.top = ( options.top - curOffset.top ) + curTop;
      }
      //如果傳的參數(shù)的有l(wèi)eft值
      if ( options.left != null ) {
        //參數(shù) left - offset().left + element.left
        props.left = ( options.left - curOffset.left ) + curLeft;
      }
      //自己沒見過使用 using 的情況。。
      if ( "using" in options ) {
        options.using.call( elem, props );

      }
      //所以一般走這里,為當(dāng)前元素設(shè)置top,left屬性
      else {
        //position:relative
        //top:xxx
        //left:xxx
        curElem.css( props );
      }
    }
  };

解析:
(1)先判斷當(dāng)前元素的 position 的值,沒有設(shè)置 position 屬性的話,默認(rèn)為 relative,并獲取元素的 top、left 屬性的值
(2)返回一個對象 obj,obj 的 top 是參數(shù)的 top - 默認(rèn)偏移(offset)的 top + position 設(shè)置的 top(沒有設(shè)置,默認(rèn)為0),obj 的 left 同理。

也就是說 offset({top:15,;eft:15}) 的本質(zhì)為:
參數(shù)的屬性減去對應(yīng)的默認(rèn)offset屬性加上position上的對應(yīng)屬性。

//偽代碼
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;
  });

源碼:

//如果傳的參數(shù)是function{}的話
      if ( isFunction( options ) ) {
        // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
        options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
      }

解析:
讓當(dāng)前元素通過call 去調(diào)用參數(shù)中的 function(){} 方法,call 的參數(shù)必須一個一個放進(jìn)去,上面源碼中,call 參數(shù)有 i、jQuery.extend( {}, curOffset )

jQuery.extend( {}, curOffset )

暫不解析jQuery.extend() ,但這里的作用 不用看源碼,也知道是將 element.offset() 的屬性賦值給新建的空對象 {} 。

所以 $().offset(function(){}) 的本質(zhì)即:相對于 element.offset() ,對其 top,left進(jìn)行操作,而不是像 offset({top:xxx,left:xxx}) 那樣相對于左上角原點(diǎn)進(jìn)行操作(這樣就需要先減去offset()中的top、left的值了)。

本文結(jié)束,五一愉快~

(完)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/104064.html

相關(guān)文章

  • jQuery源碼解析position()

    摘要:注意的本質(zhì)是的解析整體上看,是一個語句由于的元素,是相對于瀏覽器窗口進(jìn)行定位的,所以它的偏移就是,即獲取某個元素相對于視窗的位置。注意的本質(zhì)是的完 showImg(https://segmentfault.com/img/remote/1460000019072306); position()作用:返回被選元素相對于父元素(parent)的偏移坐標(biāo) 使用:直接調(diào)用$().positio...

    sunsmell 評論0 收藏0
  • 向Zepto學(xué)習(xí)關(guān)于"偏移"的那些事

    摘要:獲得當(dāng)前元素相對于的位置。返回一個對象含有和當(dāng)給定一個含有和屬性對象時,使用這些值來對集合中每一個元素進(jìn)行相對于的定位。獲取對象集合中第一個元素相對于其的位置。結(jié)尾以上就是中與偏移相關(guān)的幾個的解析,歡迎指出其中的問題和有錯誤的地方。 前言 這篇文章主要想說一下Zepto中與偏移相關(guān)的一些事,很久很久以前,我們經(jīng)常會使用offset、position、scrollTop、scrollLe...

    hzx 評論0 收藏0
  • 由一個“bug”到鮮為人知的jQuery.cssHooks

    摘要:干想了半天,認(rèn)為可能還是本身的寫法問題。對象提供了一種通過定義函數(shù)來獲取或設(shè)置特定值的方法。簡單來說,給我們暴露了一個鉤子,我們可以自己定義方法比如,來實(shí)現(xiàn)針對某個屬性的特定行為。 寫在最前 本次分享一下在一次jQuery賦值樣式失效的結(jié)果中來分析背后原因的過程。在翻jQuery源碼的過程中,感覺真是還不能說自己只是會用jQuery,我好像連會用都達(dá)不到(逃 歡迎關(guān)注我的博客,不定期更...

    ernest.wang 評論0 收藏0
  • 由一個“bug”到鮮為人知的jQuery.cssHooks

    摘要:干想了半天,認(rèn)為可能還是本身的寫法問題。對象提供了一種通過定義函數(shù)來獲取或設(shè)置特定值的方法。簡單來說,給我們暴露了一個鉤子,我們可以自己定義方法比如,來實(shí)現(xiàn)針對某個屬性的特定行為。 寫在最前 本次分享一下在一次jQuery賦值樣式失效的結(jié)果中來分析背后原因的過程。在翻jQuery源碼的過程中,感覺真是還不能說自己只是會用jQuery,我好像連會用都達(dá)不到(逃 歡迎關(guān)注我的博客,不定期更...

    malakashi 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<