样式操作模块可用于管理DOM元素的样式、坐标和尺寸,本节讲解一下样式相关,样式操作通过jQuery实例的css方法来实现,该方法有很多的执行方法,如下:

  • css(obj)             ;参数1是一个对象时,表示一次性设置多个css样式
  • css(name,func)       ;参数2是函数时,设置的是函数返回值
  • css(name,'')            ;参数2是空字符串时,表示删除该样式(删除style属性上的)
  • css(name)              ;如果忽略第二个参数,则获取第一个匹配元素的name样式
  • css(name,value)    ;设置每个匹配的元素的name样式为值value。

writer by:大沙漠 QQ:22969969

举个栗子:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
<style>
div{width: 200px;height: 200px;background: #0ff;}
</style>
</head>
<body>
<div> </div>
<button id="b1">设置背景和边框</button>
<button id="b2">移除边框</button>
<button id="b3">获取宽度</button>
<script>
$('#b1').click(()=>{
$('div').css({background:'#ff0',border:'1px solid #f00'})
})
$('#b2').click(()=>{
$('div').css('border','')
})
$('#b3').click(()=>{
$('div').text($('div').css('height') ) })
</script>
</body>
</html>

效果如下:

我们设置了三个按钮,分别通过css方法进行设置、删除和获取样式,比较好用哈

源码分析


jquery实例css方法实现如下:

jQuery.fn.css = function( name, value ) {            //获取匹配元素集合中第一个元素的计算样式 或者 在每个匹配元素上设置一个或多个内联样式。
// Setting 'undefined' is a no-op
if ( arguments.length === 2 && value === undefined ) {
return this;
} return jQuery.access( this, name, value, true, function( elem, name, value ) { //调用jQuery.access()遍历匹配元素集合,并在每个元素上执行传入的回调函数
return value !== undefined ?
jQuery.style( elem, name, value ) : //如果传入了参数则调用jQuery.style()设置内联样式
jQuery.css( elem, name ); //否则调用jQuery.css()来读取计算样式
});
};

通过access工具函数来实现的,这样参数就支持多种形式了,access在html篇里讲解过了,可以看这个地址:https://www.cnblogs.com/greatdesert/p/11670682.html

可以源码看到,jQuery内部对于css的实现是通过静态的style和css方法来实现的,前者负责设置DOM元素的内联样式,后者用于读取elem元素上name的值,style的实现如下:

jQuery.extend({
style: function( elem, name, value, extra ) { //读取或设置DOM元素的内联样式。elem:DOM元素、name:待读取或设置的样式名、value:待设置的样式值、extra:用于指示获取宽度、高度的计算公式字符串。
// Don't set styles on text and comment nodes
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { //如果是文本节点或注释节点 或者不是文本、注释节点但是没有style属性
return; //直接返回,不做处理
} // Make sure that we're working with the right name
var ret, type, origName = jQuery.camelCase( name ),
style = elem.style, hooks = jQuery.cssHooks[ origName ]; //将style设置为elem.style name = jQuery.cssProps[ origName ] || origName; // Check if we're setting a value
if ( value !== undefined ) { //如果传入了value值,则设置相对值。
type = typeof value; // convert relative number strings (+= or -=) to relative numbers. #7345
if ( type === "string" && (ret = rrelNum.exec( value )) ) { //如果value是相对值字符串,则计算相对值。value格式是+=..或-=...。rrelNum = /^([\-+])=([\-+.\de]+)/,
value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
// Fixes bug #9237
type = "number";
} // Make sure that NaN and null values aren't set. See: #7116
if ( value == null || type === "number" && isNaN( value ) ) { //过滤null、NaN类型,不做任何处理,如果要删除某个内联样式,请传入空字符串
return;
} // If a number was passed in, add 'px' to the (except for certain CSS properties)
if ( type === "number" && !jQuery.cssNumber[ origName ] ) { //如果待设置的样式值是一个数值,且该样式不在cssNumber中定义的,则自动追加单位px。cssNumber定义在6492行,是一个数组。
value += "px";
} // If a hook was provided, use that value, otherwise just set the specified value
if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { //优先调用修正对象爱那个的修正方法set();
// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
// Fixes bug #5509
try {
style[ name ] = value; //其次设置style[name]属性。
} catch(e) {}
} } else { //如果未传入value参数,则读取内联样式。
// If a hook was provided get the non-computed value from there
if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { //优先调用修正对象的get()修正方法,并返回。
return ret;
} // Otherwise just get the value from the style object
return style[ name ]; //没有修正方法则读取属性style[name]。
}
},
})

从源码里看到我们可以每次递增一些属性,例如:$("div").css('width','+=20')这样去累加宽度的,默认单位为px。

对于css的实现如下:

jQuery.extend({
css: function( elem, name, extra ) { //负责读取DOM元素的计算样式。elem:待读取的DOM元素,name:待设置的样式名,extra:一个字符串,用于指示获取高度、宽度的计算公式。
var ret, hooks; // Make sure that we're working with the right name
name = jQuery.camelCase( name ); //将样式名转换为驼峰式
hooks = jQuery.cssHooks[ name ]; //hooks指向驼峰式样式名对应的修正对象。
name = jQuery.cssProps[ name ] || name; //修正驼峰式样式名,如果origName是float则把name修正为cssFloat或styleFloat // cssFloat needs a special treatment
if ( name === "cssFloat" ) { //如果样式名为cssFloat
name = "float"; //则修正为float
} // If a hook was provided get the computed value from there
if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { //优先调用修正对象的get()修正方法。
return ret; // Otherwise, if a way to get the computed value exists, use that
} else if ( curCSS ) {
return curCSS( elem, name ); //其他调用curCSS(elem,name)读取计算样式。定义在6765行
}
},
})

curCSS是jQuery内部定义的一个工具函数,用于获取某个样式,实现如下:

curCSS = getComputedStyle || currentStyle;

默认等于getComputedStyle(window.getComputedStyle存在的情况下,IE及其它浏览器),currentStyle是jQuery内部实现的一个另一个兼容方案,就不讨论了,getComputedStyle实现如下:

if ( document.defaultView && document.defaultView.getComputedStyle ) {        //在IE9+和其他浏览器中。如果window.getComputedStyle属性存在。document.defaultView即window对象。
getComputedStyle = function( elem, name ) { ////定义getComputedStyle()函数
var ret, defaultView, computedStyle; name = name.replace( rupper, "-$1" ).toLowerCase(); //将可能的驼峰式央视名转换为连字符式。rupper = /([A-Z]|^ms)/g, if ( (defaultView = elem.ownerDocument.defaultView) &&
(computedStyle = defaultView.getComputedStyle( elem, null )) ) { //defaultView即window对象 调用window.getComputedStyle()方法获取该节点的样式集合
ret = computedStyle.getPropertyValue( name ); //调用getPropertyValue()方法获取name样式的值。
if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { //如果没取到计算样式,并且当前元素不再文档中
ret = jQuery.style( elem, name ); //调用jQuery.style()读取内联样式。
}
} return ret;
};
}

通过代码可以看到jQuery优先调用window.getComputedStyle()属性获取样式的。

jQuery 源码解析(二十六) 样式操作模块 样式详解的更多相关文章

  1. jQuery 源码解析(二十五) DOM操作模块 html和text方法的区别

    html和text都可以获取和修改DOM节点里的内容,方法如下: html(value)     ;获取匹配元素集合中的一个元素的innerHTML内容,或者设置每个元素的innerHTML内容,   ...

  2. jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解

    本节说一下DOM操作模块里的包裹元素子模块,该模块可将当前匹配的元素替换指定的DOM元素,有如下方法: wrap(html)               ;在每个匹配元素的外层添加一层DOM元素   ...

  3. Vue.js 源码分析(二十六) 高级应用 作用域插槽 详解

    普通的插槽里面的数据是在父组件里定义的,而作用域插槽里的数据是在子组件定义的. 有时候作用域插槽很有用,比如使用Element-ui表格自定义模板时就用到了作用域插槽,Element-ui定义了每个单 ...

  4. jQuery 源码解析(二十九) 样式操作模块 尺寸详解

    样式操作模块可用于管理DOM元素的样式.坐标和尺寸,本节讲解一下尺寸这一块 jQuery通过样式操作模块里的尺寸相关的API可以很方便的获取一个元素的宽度.高度,而且可以很方便的区分padding.b ...

  5. jQuery 源码解析(二十八) 样式操作模块 scrollLeft和scrollTop详解

    scrollLeft和scrollTop用于获取/设置滚动条的,如下: scrollLeft(val) ;读取或设置整个页面的水平滚动条距离 scrollTop(val) ;读取或设置整个页面的垂直滚 ...

  6. jQuery 源码解析(二十二) DOM操作模块 复制元素 详解

    本节说一下DOM操作模块里的复制元素子模块,该模块可以复制一个DOM节点,并且可选择的设置是否复制其数据缓存对象(包含事件信息)和是否深度复制(子孙节点等),API如下: $.clone(elem, ...

  7. Vue.js 源码分析(二十八) 高级应用 transition组件 详解

    transition组件可以给任何元素和组件添加进入/离开过渡,但只能给单个组件实行过渡效果(多个元素可以用transition-group组件,下一节再讲),调用该内置组件时,可以传入如下特性: n ...

  8. Vue.js 源码分析(二十四) 高级应用 自定义指令详解

    除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令. 官网介绍的比较抽象,显得很高大上,我个人对自定义指令的理解是:当自定义指令作用在一些DOM元素或组件上 ...

  9. Vue.js 源码分析(二十九) 高级应用 transition-group组件 详解

    对于过度动画如果要同时渲染整个列表时,可以使用transition-group组件. transition-group组件的props和transition组件类似,不同点是transition-gr ...

随机推荐

  1. 6张图说清楚Tomcat原理及请求流程

    前言 很多东西在时序图中体现的已经非常清楚了,没有必要再一步一步的作介绍,本文以图为主,然后对部分内容加以简单解释. 绘制图形使用的工具是 PlantUML + Visual Studio Code ...

  2. Real World CTF一日游

    今天去感受了长亭举办的RWCTF现场,参加了技术论坛,也学到了很多的知识 比较有印象的就是 智能安全在Web防护中的探索和实践 阿里云安全防护构建的AI架构体系: 基线检测 基础过滤 异常检测 攻击识 ...

  3. go 利用chan的阻塞机制,实现协程的开始、阻塞、返回控制器

    一.使用场景 大背景是从kafka 中读取oplog进行增量处理,但是当我想发一条命令将这个增量过程阻塞,然后开始进行一次全量同步之后,在开始继续增量. 所以需要对多个协程进行控制. 二.使用知识 1 ...

  4. LeetCode刷题总结-二分查找和贪心法篇

    本文介绍LeetCode上有关二分查找和贪心法的算法题,推荐刷题总数为16道.具体考点归纳如下: 一.二分查找 1.数学问题 题号:29. 两数相除,难度中等 题号:668. 乘法表中第k小的数,难度 ...

  5. windows10远程桌面 删除IP记录

    注册表位置: HKEY_CURRENT_USER/ Software/ Microsoft/ Terminal Server  client/ servers/ 删除不需要的IP地址即可.

  6. 灵魂拷问:创建 Java 字符串,用""还是构造函数

    在逛 programcreek 的时候,我发现了一些小而精悍的主题.比如说:创建 Java 字符串,用 "" 还是构造函数?像这类灵魂拷问的主题,非常值得深入地研究一下. 01.& ...

  7. WebShell代码分析溯源(七)

    WebShell代码分析溯源(七) 一.一句话变形马样本 <?php $e = $_REQUEST['e'];$arr = array($_POST['POST'],);array_map(ba ...

  8. SecureCRT登陆liunx 方向键失效

    使用SecureCRT登陆liunx(CenterOS)系统,发现删除(backspace)键.和上下左右键不起作用,解决如下: 先打开Options–>Session Options–> ...

  9. asp.net core的AOP记录

    序曲:学习编程最好的方式就是敲代码,没有比这个更好的方法,哪怕你看了上百G的视频,都不如你自己敲几行代码更为有效.还有要记得敲完代码然后写一篇随笔来记录一下你所学所想. 什么叫AOP? AOP面向切面 ...

  10. Git worktree 使用笔记【转】

    gitworktree 本地仓库的多个分支在对应的文件夹内管理,能够减少很多操作,便捷高效~ 一 worktree 的基本概念和操作 再也不用克隆多个仓库啦!git worktree 一个 git 仓 ...