经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » jQuery » 查看文章
jQuery 源码分析(十四) 数据操作模块 类样式操作 详解
来源:cnblogs  作者:大沙漠  时间:2019/10/23 8:52:40  对本文有异议

jQuery的属性操作模块总共有4个部分,本篇说一下第3个部分:类样式操作部分,用于修改DOM元素的class特性的,对于类样式操作来说,jQuery并没有定义静态方法,而只定义了实例方法,如下:

  • addClass(value)      ;为匹配元素集合中的每个元素添加一个或多个类样式,通过修改DOM属性className来修改类样式,value可以是个以空格分隔的类样式或者一个函数(返回一个或多个以空格分隔的类样式)
  • hasClass(selector)       ;检测匹配元素中的任意元素是否含有指定的类样式,只要其中一个元素含有就返回true,selector是一个类样式。
  • removeClass(value)    ;从匹配元素集合中的每个元素上移除一个或多个或全部类样式,value可以为空(全部移除)、以空格分隔的类样式(移除多个样式),或者是个函数(该函数返回一个或多个以空格分隔的类样式)
  • toggleClass(value,stateVal) ;对设置或移除被选元素的一个或多个类进行切换,有五种用法

 writer by:大沙漠 QQ:22969969

    ·toggleClass()                  ;未传入参数                    ;这时如果当前元素含有样式则移除所有类,如果没有则尝试恢复。
    ·toggleClass(stateVal)          ;只传入一个布尔值类型              ;如果stateVal是true,则等同于toggleClass();如果是false则总是移除所有类。
    ·toggleClass(value)           ;参数1是字符串或函数,未传入参数2        ;value是字符串时表示一个或多个样式,用空格分隔,下同;value是函数时返回字符串格式。如果匹配元素含有指定的类样式,则移除,否则添加该样式。
    ·toggleClass(value,stateVal)     ;参数1是字符串或函数,参数2是布尔值    ;当stateVal是true时总是添加,是false时则总是移除

对于toggleClass切换样式时,jQuery内部实现会将所有类暂时保存在数据缓存对象的__className__数据中,等下次恢复时尝试读取。

举个栗子吧:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
  7. <style>
  8. .color{color: #f00;}
  9. .back{background: #ccc;}
  10. </style>
  11. </head>
  12. <body>
  13. <p>Hello World!</p>
  14. <button id="b1">设置所有样式</button>
  15. <button id="b2">切换color样式</button>
  16. <button id="b3">取消所有样式</button>
  17. <script>
  18. let b1 = document.getElementById('b1'),
  19. b2 = document.getElementById('b2'),
  20. b3 = document.getElementById('b3');
  21. b1.onclick = ()=>{
  22. $('p').addClass('color back'); //添加所有样式
  23. }
  24. b2.onclick = ()=>{
  25. $('p').toggleClass('color'); //切换color样式
  26. }
  27. b3.onclick = ()=>{
  28. $('p').removeClass(); //取消所有样式
  29. }
  30. </script>
  31. </body>
  32. </html>

这里我们在style自定义了两个class:color和back,前者修改字体的颜色,后者修改字体的背景色,然后定义了三个按钮分别用于操作样式,渲染如下:

点击设置所有样式,将在p这个DOM元素上添加color和back两个class,如下:

 当点击切换color样式时,由于p元素上的color这个class已经存在了,因此会取消掉:

当再次点击切换color样式这个按钮时,由于p元素上的color这个class已经取消了,因此此时会显示出来,如下:

 当我们点击取消所有样式时将会把p元素上的所有class给删掉,又回到初始状态,如下:

 

源码分析


 jQuery内部对于样式的操作是修改对应DOM元素的className属性来实现的,中间通过字符串的indexOf和replace操作实现查找和替换,对于添加样式和删除样式的逻辑如下:

  1. jQuery.fn.extend({
  2. addClass: function( value ) { //添加类样式
  3. var classNames, i, l, elem,
  4. setClass, c, cl;
  5. if ( jQuery.isFunction( value ) ) { //如果value是函数
  6. return this.each(function( j ) {
  7. jQuery( this ).addClass( value.call(this, j, this.className) ); //在每个匹配元素上执行该函数并且取其返回值作为待添加的类样式,然后调用.addClass(className)添加类样式。执行函数时,传入两个参数,分别是元素在集合中的下标位置和当前样式值。
  8. });
  9. }
  10. if ( value && typeof value === "string" ) { //如果value是字符串,可以是空格分隔的多个样式
  11. classNames = value.split( rspace ); //用/\s+/对value进行分隔
  12.  
  13. for ( i = 0, l = this.length; i < l; i++ ) { //遍历匹配元素
  14. elem = this[ i ];
  15. if ( elem.nodeType === 1 ) { //只针对元素节点
  16. if ( !elem.className && classNames.length === 1 ) { //如果elem.className不存在,且待添加的样式个数为1,则直接设置elem.className
  17. elem.className = value;
  18. } else {
  19. setClass = " " + elem.className + " "; //在待添加的类样式className前后加空格
  20.  
  21. for ( c = 0, cl = classNames.length; c < cl; c++ ) { //历要添加的类样式value
  22. if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { //如果classNames中的某个样式不存在setClass中
  23. setClass += classNames[ c ] + " "; //则添加该样式
  24. }
  25. }
  26. elem.className = jQuery.trim( setClass ); //最后去除类样式两边的空格,再设置到elem.className中
  27. }
  28. }
  29. }
  30. }
  31. return this;
  32. },
  33. removeClass: function( value ) { //从匹配元素集合中的每个元素上移除一个或多个或全部类样式。通过修改DOM属性className来移除类样式。
  34. var classNames, i, l, elem, className, c, cl;
  35. if ( jQuery.isFunction( value ) ) { //如果value是一个函数
  36. return this.each(function( j ) { //遍历匹配元素
  37. jQuery( this ).removeClass( value.call(this, j, this.className) ); //调用每个匹配元素的removeClass()函数,参数是value函数的返回值
  38. });
  39. }
  40. if ( (value && typeof value === "string") || value === undefined ) { //如果value存在且是一个字符串 或者 value未定义
  41. classNames = ( value || "" ).split( rspace ); //用空白符分隔value以支持一次移除多个类样式。这里如果value是空的,那么结果是[""],该数组的length等于1
  42.  
  43. for ( i = 0, l = this.length; i < l; i++ ) { //遍历匹配元素
  44. elem = this[ i ]; //elem是匹配的元素
  45.  
  46. if ( elem.nodeType === 1 && elem.className ) { //只支持已经设置了className的元素节点。
  47. if ( value ) { //如果传入了value值,则表示是设置样式
  48. className = (" " + elem.className + " ").replace( rclass, " " ); //classNames是当前元素的类样式,两边加个空格,再去除出换行、制表、回车符。var rclass = /[\n\t\r]/g,
  49. for ( c = 0, cl = classNames.length; c < cl; c++ ) { //遍历要移除的类样式数组classNames
  50. className = className.replace(" " + classNames[ c ] + " ", " "); //调用字符串方法replace()逐个从当前类样式中移除
  51. }
  52. elem.className = jQuery.trim( className ); //去掉空白字符,在设置elem.className属性
  53. } else {
  54. elem.className = "";
  55. }
  56. }
  57. }
  58. }
  59. return this;
  60. },
  61. /**/
  62. })

当我们在页面里做各种动画效果时还是会用到这个API的,挺方便的,配合css可以实现各种的动画效果。

原文链接:http://www.cnblogs.com/greatdesert/p/11672871.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号