首先是原型上的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}

jQuery offset()源码解析的更多相关文章

  1. jquery 部分函数源码解析

    JSON.stringify源码(在看extend文档的时候看到) var object1 = { apple: 0, banana: {weight: 52, price: 100}, cherry ...

  2. jquery extend源码解析

    $.extend(obj1,0bj2,{"name":"s","age":22}) //target 要拷贝到哪个对象上 // i 要执行拷 ...

  3. jQuery源码解析资源便签

    最近开始解读jQuery源码,下面的链接都是搜过来的,当然妙味课堂 有相关的一系列视频,长达100多期,就像一只蜗牛慢慢爬, 至少品读三个框架,以后可以打打怪,自己造造轮子. 完全理解jQuery源代 ...

  4. jquery源码解析:代码结构分析

    本系列是针对jquery2.0.3版本进行的讲解.此版本不支持IE8及以下版本. (function(){ (21, 94)     定义了一些变量和函数,   jQuery = function() ...

  5. jQuery整体架构源码解析(转载)

    jQuery整体架构源码解析 最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性, ...

  6. JQuery源码解析(一)

    写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...

  7. jquery 源码解析

    静态与实力方法共享设计 遍历方法 $(".a").each() //作为实例方法存在 $.each() //作为静态方法存在 Jquery源码 jQuery.prototype = ...

  8. jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究

    终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...

  9. jQuery整体架构源码解析

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

随机推荐

  1. .net2.0 C# Json反序列化

    http://cjl20082002.blog.163.com/blog/static/120827332009511103457637/ 去:http://json.codeplex.com/下载  ...

  2. Objective-C学习之解析XML

    通过soap请求webservice时,返回的数据是XML类型,有时候也需要解析本地的xml数据等,苹果自带类NSXMLParser解析xml还是很方便的,简单轻便 本文以解析本地XML为例,网络获取 ...

  3. 调试windows服务最简单的方法之一

    先看一下这段启动代码: using System; using System.Collections.Generic; using System.Linq; using System.ServiceP ...

  4. Power Strings--KMP

    https://cn.vjudge.net/problem/POJ-2406 上面是比赛链接. 题目意思很明确,问最多是多少个子串连接而成的? 这个需要用到KMP,很好的理解KMP的Next数组.Ne ...

  5. 【C/C++】获取当前系统时间

    #include<iostream> #include<Ctime> using namespace std; int main() { time_t t; time(& ...

  6. 洛谷P4145上帝造题的七分钟——区间修改

    题目:https://www.luogu.org/problemnew/show/P4145 区间开平方,可以发现其实开几次就变成1,不需要开了,所以标记一下,每次只去开需要开的地方: 原来写的并查集 ...

  7. springboot中使用@Value读取配置文件

    一.配置文件配置 直接配置 在src/main/resources下添加配置文件application.properties 例如修改端口号 #端口号 server.port=8089 分环境配置 在 ...

  8. tabbar

    1 tabbar不显示的问题: 命名在app.json中配置了tabbar但是不显示可能的问题: app.json中的pages中第一个路径没有在tabbar中设置 原因:app.json中配置的pa ...

  9. js遍历checkbox获取数据

    function GetCurrenetPoint() { debugger var currentTypes = ""; var display = $("#input ...

  10. 爬虫库之BeautifulSoup学习(一)

    Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据. 官方解释如下: Beautiful Soup提供一些简单的.pytho ...