jquery源码分析——元素大小

本文深入探讨HTML中与窗口大小相关的样式属性,包括offsetWidth、offsetHeight、offsetLeft、offsetTop、clientWidth、clientHeight、scrollWidth、scrollHeight、scrollLeft、scrollTop等,并详细对比了不同浏览器环境下这些属性的差异性,特别强调了在不同浏览器中获取窗口宽度、文档宽度、可视区域宽度的方法及其背后的逻辑。此外,文章还解析了jQuery中对窗口大小获取的实现方式,通过生成方法扩展了获取窗口大小的灵活性与兼容性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HTML息息相关的的样式

偏移量

offsetWidth offsetHeight offsetLeft offsetTop

image

offsetHeight/offsetWidth: 表述元素的外尺寸:元素内容+内边距+边框(不包括外边距)

offsetLeft/offsetTop: 表示该元素的左上角(边框外边缘)与已定位的父容器(offsetParent对象)左上角的距离。

offsetParent元素是指元素最近的定位(relative,absolute)祖先元素,可递归上溯。

 

 


客户区大小

clientWidth clientHeight 

image

clientWidth/clientHeight: 用于描述元素的内尺寸:元素内容+两边内边距

 

 


滚动大小

scrollWidth scrollHeight scrollLeft scrollTop

image

scrollHeight/scrollWidth: 元素内容的总高度或宽度

scrollLeft/scrollTop:是指元素滚动条位置,它们是可写的(被隐藏的内容区域左侧/上方的像素)

浏览器窗口的滚动条位置:window对象的pageXoffset和pageYoffset, IE 8及更早版本可以通过scrollLeft和scrollTop属性获得滚动条位置

 


以下是网上的总结,我收集下

Chrome/FF/Safari/opera 
对这些浏览器而言,window有个属性innerWidth/innerHeight包含的是整个文档的可视区域尺寸,注意,这个尺寸是包含滚动条大小的。 
如果我们不计滚动条的影响,就可以直接使用这两个属性。 
如果滚动条会影响(比如最大化弹出框),那么应该想另外的办法。

 

document.documentElementy与document.body

Document对象是每个DOM树的根,但是它并不代表树中的一个HTML元素,document.documentElement属性引用了作为文档根元素的html标记,document.body属性引用了body标记 
我们这里获取常见的三个值(scrollWidth、offsetWidth和clientwidth)来比较一下

document.documentElement.scrollWidth返回整个文档的宽度
document.documentElement.offsetWidth返回整个文档的可见宽度
document.documentElement.clientwidth返回整个文档的可见宽度(不包含边框),clientwidth = offsetWidth - borderWidth

不过一般来说,我们不会给document.documentElement来设置边框,所以这里的clientwidth 与 offsetWidth一致

 

document.body.scrollWidth返回body的宽度 
注意,这里的scrollWidth有个不一致的地方,基于webkit的浏览器(chrome和safari)返回的是整个文档的宽度,也就是和document.documentElement.scrollWidth一致, 
opera和FF返回的就是标准的body 的scrollWidth,个人觉得opera和FF算是比较合理的。


document.body.offsetWidth返回body的offsetWidth 
document.body.clientwidth返回body的clientwidth(不包含边框),clientwidth = offsetWidth - borderWidth

我们看上面的例子,会发现

body和documentElement的有些值是相等的,这并不是表示他们是等同的。而是因为当我们没有给body设置宽度的时候,document.body默认占满整个窗口宽度,

于是就有:

document.body.scrollWidth = document.documentElement.scrollWidth
document.body.offsetWidth = document.documentElement.offsetWidth
document.body.clientwidth = document.documentElement.clientwidth - document.body.borderWidth(body的边框宽度)


当我们给body设置了一个宽度的时候,区别就出来了。

 

IE9/IE8 
这两个差不多,唯一的区别是IE9包含window.innerWidth属性,而IE8不包含window.innerWidth属性。 
document.documentElement.scrollWidth返回整个文档的宽度,和FF等浏览器一致 
document.documentElement.offsetWidth返回整个文档的可见宽度(包含滚动条,值和innerWidth一致),注意,这里和FF等浏览器又有点区别。 
document.documentElement.clientwidth返回整个文档的可见宽度(不包含边框),和FF等浏览器一致。clientwidth = offsetWidth - 滚动条宽度

document.body.scrollWidth返回body的宽度,注意,这里的scrollWidth和FF等浏览器有点区别,这里并不包括body本身的border宽度。 
因此例子中,相比FF少了10px。 
document.body.offsetWidth返回body的offsetWidth,和FF等浏览器一致 
document.body.clientwidth返回body的clientwidth(不包含边框),和FF等浏览器一致,clientwidth = offsetWidth – borderWidth

 

IE7与IE9/IE8的主要区别是 
第一、document.documentElement.offsetWidth的返回值不一样, 
参见上面说的,IE9/IE8的document.documentElement.offsetWidth包含滚动条,但是,IE7的document.documentElement.offsetWidth不包含滚动条。 
第二、document.documentElement.scrollWidth返回整个文档的宽度,注意,这里和IE9/IE8、FF等浏览器又有不一致,对于IE9/IE8、FF等浏览器,scrollWidth最小不会小于窗口的宽度,但是在IE下没有这个限制,文档有多小,这个就有多小 
其他倒是挺一致的。

 

IE6了 
IE6的document.documentElement返回值与IE9/IE8没有区别(由此可见,对于document.documentElement,IE7就是个奇葩)。 
话说回来,IE的document.body就是个奇葩,当没有给body设置宽度的时候,body是默认占满整个文档的(注意,其他的浏览器都是占满整个窗口),当然,最小值是整个窗口的大小,就是说body指向了根元素。 
因此,在算上IE6在解析width方面的bug,和其他的浏览器的区别就淋漓尽致了。 
document.body.scrollWidth返回body的宽度,和IE9/IE8/IE7一致 
document.body.offsetWidth返回body的offsetWidth,注意,由于body的不同,这里的offsetWidth = scrollWidth + borderWidth 
document.body.clientwidth返回body的clientwidth(不包含边框)clientwidth = offsetWidth - borderWidth 
另外,有一点和IE7同样,就是document.documentElement.scrollWidth没有最小宽度限制。

 

 


源码解析

先看jQuery对窗口大小六种相似方法的生成

 

jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
        jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
      
//执行代码
        });
    });

扩展方法还是用的合并的模式,把具有相同特性的方法采用合并处理

循环生成是艺术,需要深刻了解它们的功能与共同点,然后将特异点组成一个对象,好处自然是省代码了,然后可以集中处理

 

执行代码

例如:.width()

为匹配的元素集合中获取第一个元素的当前计算宽度值。

复制代码
return jQuery.access( this, function( elem, type, value ) {
    var doc;
    if ( jQuery.isWindow( elem ) ) {
        return elem.document.documentElement[ "client" + name ];
    }

    // Get document width or height
    if ( elem.nodeType === 9 ) {
        doc = elem.documentElement;
        return Math.max(
            elem.body[ "scroll" + name ], doc[ "scroll" + name ],
            elem.body[ "offset" + name ], doc[ "offset" + name ],
            doc[ "client" + name ]
        );
    }

    return value === undefined ?
        jQuery.css( elem, type, extra ) :
        jQuery.style( elem, type, value, extra );
}, type, chainable ? margin : undefined, chainable, null );
复制代码

 

A.首先先解释下普通元素和非普通元素,

非普通元素是指window,document这些 元素对象,

普通元素是指除window,document之外的元素,如:div

 

B.css(width) 和 .width()之间的区别?

  • 对于非普通元素,只能使用 .width()

  • 对于普通的元素 ,他们的作用相同

  • 后者返回一个没有单位的数值(例如,400),前者是返回带有完整单位的字符串(例如,400px)。当一个元素的宽度需要数学计算的时候推荐使用.width() 方法

     

    C.非普通元素的获取

    如:window

    $(window).width();   //浏览器窗口
    即返回HTML的窗口,所以代码就是document.documentElement[“clientWidth”]
    if ( jQuery.isWindow( elem ) ) {
            return elem.document.documentElement[ "client" + name ];
        }
     
    document
    $(document).width();   //HTML文档窗口

    取最大值,因为可以带卷滚条溢出

    复制代码
    if ( elem.nodeType === 9 ) {
        doc = elem.documentElement;
    
        // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
        // whichever is greatest
        return Math.max(
            elem.body[ "scroll" + name ], doc[ "scroll" + name ],
            elem.body[ "offset" + name ], doc[ "offset" + name ],
            doc[ "client" + name ]
        );
    }
    复制代码
     

    D.普通元素取值

    jQuery.cssHooks

    因为有些样式不是简单的读写属性就可以的,比如width就不是简单地读取el.style.width。为了解决这个问题,jquery定义了一个属性 $.cssHooks,这里可以自定义对某个属性的get和set操作。而且jquery中就是用cssHooks来处理某些特殊属性的

    对CSS的操作都是通过统一的API调用,操作的属性是

    1. borderWidth: Object
    2. height: Object
    3. margin: Object
    4. opacity: Object
    5. padding: Object
    6. width: Object

    此时就会用jQuery.cssHooks方法处理兼容问题,

     

    width,height的钩子方法

    复制代码
    jQuery.each([ "height", "width" ], function( i, name ) {
            jQuery.cssHooks[ name ] = {
                get: function( elem, computed, extra ) {
                    if ( computed ) {
                        return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
                            jQuery.swap( elem, cssShow, function() {
                                return getWidthOrHeight( elem, name, extra );
                            }) :
                            getWidthOrHeight( elem, name, extra );
                    }
                },
    
                set: function( elem, value, extra ) {
                    var styles = extra && getStyles( elem );
                    return setPositiveNumber( elem, value, extra ?
                        augmentWidthOrHeight(
                            elem,
                            name,
                            extra,
                            jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
                            styles
                        ) : 0
                    );
                }
            };
    复制代码

    get 方法:

    1 节点隐藏等情况下,height、width等获取值不准,此时需利用jQuery.swap方法来获得准确值

    2 getWidthOrHeight获取准确值

     

    本章大体回顾下了跟HTML相关处理的10种方法与jQuery中相对应的处理流,下章再具体分析jQuery中对应每种不同兼容的处理

标题基于SpringBoot+Vue的学生交流互助平台研究AI更换标题第1章引言介绍学生交流互助平台的研究背景、意义、现状、方法与创新点。1.1研究背景与意义分析学生交流互助平台在当前教育环境下的需求及其重要性。1.2国内外研究现状综述国内外在学生交流互助平台方面的研究进展与实践应用。1.3研究方法与创新点概述本研究采用的方法论、技术路线及预期的创新成果。第2章相关理论阐述SpringBoot与Vue框架的理论基础及在学生交流互助平台中的应用。2.1SpringBoot框架概述介绍SpringBoot框架的核心思想、特点及优势。2.2Vue框架概述阐述Vue框架的基本原理、组件化开发思想及与前端的交互机制。2.3SpringBoot与Vue的整合应用探讨SpringBoot与Vue在学生交流互助平台中的整合方式及优势。第3章平台需求分析深入分析学生交流互助平台的功能需求、非功能需求及用户体验要求。3.1功能需求分析详细阐述平台的各项功能需求,如用户管理、信息交流、互助学习等。3.2非功能需求分析对平台的性能、安全性、可扩展性等非功能需求进行分析。3.3用户体验要求从用户角度出发,提出平台在易用性、美观性等方面的要求。第4章平台设计与实现具体描述学生交流互助平台的架构设计、功能实现及前后端交互细节。4.1平台架构设计给出平台的整体架构设计,包括前后端分离、微服务架构等思想的应用。4.2功能模块实现详细阐述各个功能模块的实现过程,如用户登录注册、信息发布与查看、在线交流等。4.3前后端交互细节介绍前后端数据交互的方式、接口设计及数据传输过程中的安全问题。第5章平台测试与优化对平台进行全面的测试,发现并解决潜在问题,同时进行优化以提高性能。5.1测试环境与方案介绍测试环境的搭建及所采用的测试方案,包括单元测试、集成测试等。5.2测试结果分析对测试结果进行详细分析,找出问题的根源并
内容概要:本文详细介绍了一个基于灰狼优化算法(GWO)优化的卷积双向长短期记忆神经网络(CNN-BiLSTM)融合注意力机制的多变量多步时间序列预测项目。该项目旨在解决传统时序预测方法难以捕捉非线性、复杂时序依赖关系的问题,通过融合CNN的空间特征提取、BiLSTM的时序建模能力及注意力机制的动态权重调节能力,实现对多变量多步时间序列的精准预测。项目不仅涵盖了数据预处理、模型构建与训练、性能评估,还包括了GUI界面的设计与实现。此外,文章还讨论了模型的部署、应用领域及其未来改进方向。 适合人群:具备一定编程基础,特别是对深度学习、时间序列预测及优化算法有一定了解的研发人员和数据科学家。 使用场景及目标:①用于智能电网负荷预测、金融市场多资产价格预测、环境气象多参数预报、智能制造设备状态监测与预测维护、交通流量预测与智慧交通管理、医疗健康多指标预测等领域;②提升多变量多步时间序列预测精度,优化资源调度和风险管控;③实现自动化超参数优化,降低人工调参成本,提高模型训练效率;④增强模型对复杂时序数据特征的学习能力,促进智能决策支持应用。 阅读建议:此资源不仅提供了详细的代码实现和模型架构解析,还深入探讨了模型优化和实际应用中的挑战与解决方案。因此,在学习过程中,建议结合理论与实践,逐步理解各个模块的功能和实现细节,并尝试在自己的项目中应用这些技术和方法。同时,注意数据预处理的重要性,合理设置模型参数与网络结构,控制多步预测误差传播,防范过拟合,规划计算资源与训练时间,关注模型的可解释性和透明度,以及持续更新与迭代模型,以适应数据分布的变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值