您好,欢迎来到爱够旅游网。
搜索
您的当前位置:首页jQueryoffset()源码解析

jQueryoffset()源码解析

来源:爱够旅游网
jQueryoffset()源码解析

⾸先是原型上的offset⽅法,根据arguments判断到底是取值还是设值。如果是设置,就遍历调⽤静态⽅法jQuery.offset.setOffset如果是取值。那么就是从\"var docElem,win\"这⾥开始了。

jQuery.fn.offset = function( options ) { if ( arguments.length ) {//设置元素坐标

return options === undefined ?//如果传⼊的参数是undefined,直接返回 this :

this.each(function( i ) {//遍历然后调⽤jQuery.offset.setOffset jQuery.offset.setOffset( this, options, i ); }); }

var docElem, win, elem = this[ 0 ],

box = { top: 0, left: 0 },

doc = elem && elem.ownerDocument;//当前⽂档 if ( !doc ) { return; }

docElem = doc.documentElement;

// Make sure it's not a disconnected DOM node

if ( !jQuery.contains( docElem, elem ) ) {//如果元素没有被documentElement包含,就返回 0 0 return box; }

// If we don't have gBCR, just use 0,0 rather than error // BlackBerry 5, iOS 3 (original iPhone)

if ( typeof elem.getBoundingClientRect !== core_strundefined ) {//如果元素有getBoundingClientRect⽅法 box = elem.getBoundingClientRect();//调⽤该⽅法 }

win = getWindow( doc );//如果是window就返回window,如果是document,返回document.defaultView return {

//元素相对于视窗的距离+滚动距离-边框宽度

top: box.top + win.pageYOffset - docElem.clientTop, left: box.left + win.pageXOffset - docElem.clientLeft };};

取值中,它考虑了元素没有被documentElement包含的情况,没有渲染,⾃然是没有offset的,于是它很神奇的返回了{\"top\":0,\"left\":0}。因为看的是jQuery 2.x的版本,这⾥它⽤到了getBoundingClientRect⽅法,从名字就可以看出,它返回的是相对于视窗的距离,这不是我们需要的offset,jQuery.offset返回的是相对于⽂档的距离,所以还要做进⼀步的计算:

return {

//元素相对于视窗的距离+滚动距离-边框宽度

top: box.top + win.pageYOffset - docElem.clientTop, left: box.left + win.pageXOffset - docElem.clientLeft };

关于getWindow,看看函数声明:

function getWindow( elem ) {

return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;}

如果elem是window,直接返回window,如果是document,则返回document.defaultView。不是很理解为什么要使⽤document.defaultView,群⾥的⼩伙伴说可能是多frame的情况

然后我在stackoverflow上找到的帖⼦ http://stackoverflow.com/questions/9183555/whats-the-point-of-document-defaultview 也有类似的答案,然后另⼀种可能是为了修复Firefox 3.6中getComputedStyle的bug(⊙o⊙)…接下来是静态⽅法设置offset。。。

jQuery.offset = {

setOffset: function( elem, options, i ) {

var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, position = jQuery.css( elem, \"position\" ),//获取当前元素的position属性 curElem = jQuery( elem ),//缓存当前元素 props = {};

// Set position first, in-case top/left are set even on static elem

if ( position === \"static\" ) {//如果原元素是静态定位的,改成相对定位 elem.style.position = \"relative\"; }

curOffset = curElem.offset();//获取当前元素的offset curCSSTop = jQuery.css( elem, \"top\" ); curCSSLeft = jQuery.css( elem, \"left\" );

//如果元素的position为absolute或者fixed,⽽且其top和left属性中⾄少有⼀项的值是auto,calculatePosition为true

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 {//如果calculatePosition为false,元素相对定位或者原本就有top、left值 curTop = parseFloat( curCSSTop ) || 0; curLeft = parseFloat( curCSSLeft ) || 0; }

if ( jQuery.isFunction( options ) ) {//如果options是函数,遍历调⽤ options = options.call( elem, i, curOffset ); }

//计算props值,因为offset是相对⽂档定位,新的css的top/left值 //需要根据原来的offset和css的top/left值计算 if ( options.top != null ) {

props.top = ( options.top - curOffset.top ) + curTop; }

if ( options.left != null ) {

props.left = ( options.left - curOffset.left ) + curLeft; }

//如果有using这个参数,可以调⽤using⽅法 if ( \"using\" in options ) {

options.using.call( elem, props ); } else {//如果没有,设置css偏移。 curElem.css( props ); } }};

关于using这个选项,之前在jQuery API中没有看到过。发现隐藏技能了(⊙o⊙)…??好吧,刚在百度上试了下

$('#page').offset({\"top\":1000,\"left\":100,\"using\":function(prop){console.log(prop)}});//Object {top: -302, left: 100}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务