4-5 样式类操作
本节编程练习不计算学习进度,请电脑登录imooc.com操作

样式类操作

通过给元素添加删除指定的样式类名用来修改样式的方法有 addClass removeClass,为每个匹配的元素添加指定的样式类名,对元素的样式操作,底层的实现就是修改元素的className值,实现的功能:

增加一条样式规则: .addClass('myClass')
增加多条样式规则: .addClass('myClass yourClass')

传递回调遍历样式规则:

$("ul li:last").addClass(function(index) {
  return "item-" + index;
});

从接口传参去分析这个实现手法,参考右边的代码addClass我把代码简略的分了几个步骤:

这里就不详讲,看看代码就能理解重点说一下传递回调函数的设计,官方给的测试案例:

<p class ='selected highlight'>Goodbye</p>
<p class ='selected1 highlight1'>Goodbye</p>
<p class ='selected2 highlight2'>Goodbye</p>

增加样式代码:

$(p).addClass(function(index,className){
        index  className
        0 "selected highlight"
        1 "selected1 highlight1"
        2 "selected2 highlight2"
});

遍历出所有的 P 节点,并找其对应的 class,返回给每一个回调函数,看看源码的设计:

//如果传递的是回调函数,递归调用  ⑴
if ( jQuery.isFunction( value ) ) {
    return this.each(function( j ) {   //each addClass回调
        jQuery( this ).addClass( value.call( this, j, this.className ) );  
    });
}

不管是写插件还是其他的,只要是设计操作 DOM 的,在 jQuery 内部就的到 this.each 方法,原因很简单jQuery就是一个数组保存着所有对应的节点的下标

内部在传递一个编写好的回调函数,传递给 each 方法 ,each 方法理解就是一个循环方法,分解出 jQuery 数组中每一个下标元,然后把每一个元素返回给外部回调。

这里再进一步替换下代码就很明显了:

function(  i, obj[ i ]  ) {  
   jQuery( this ).addClass( value.call( this, j, this.className ) )
}

这里的 this 是指向的每一个 p 元素节点,因为 callback.call 了一下,把每一个上下文指定到当前的函数了,所以 this 就是对应的 obj[i],最后执行的代码就是:

value.call( this, j, this.className )

value 就是最外层用户定义的回调了,复制代码:

$(p).addClass(function(index,className){
//        index  className
//        0 "selected highlight"
//        1 "selected1 highlight1"
//        2 "selected2 highlight2"
});

这里意外的发现 jQuery Api没给出还包装了一层 jQuery( this ).addClass ,那么意味着 jQuery 还可以接受用户最外层的返回参数,然后再调用 addClass 给当前节点增加新的类名:

jQuery( this ).addClass( value.call( this, j, this.className ) );
  p.addClass(function(index,className){
        return 'aaaa'
});

 

任务

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
  5.  
  6. <style>
  7. .test { margin: 4px; font-size:16px; font-weight:bolder; }
  8. .blue { color:blue; }
  9. .under { text-decoration:underline; }
  10. .highlight { background:yellow; }
  11. </style>
  12. <script src="http://code.jquery.com/jquery-latest.js"></script>
  13. <title></title>
  14. </head>
  15. <body>
  16.  
  17. <p class="under">慕课网</p>
  18.  
  19. <button id="addClass">模拟jQuery的addClass("blue highlight under")方法</button>
  20. <button id="removeClass">模拟jQuery的removeClass("blue highlight under")方法</button>
  21.  
  22. <script type="text/javascript">
  23.  
  24. var p = $("p")[0];
  25.  
  26. ///////////
  27. //增加多个样式 //
  28. ///////////
  29. $("#addClass").click(function(){
  30. addClass(p, "blue highlight under")
  31. })
  32.  
  33.  
  34. $("#removeClass").click(function(){
  35. removeClass(p, "blue highlight under")
  36. })
  37.  
  38.  
  39. /////////
  40. //增加样式 //
  41. /////////
  42. function addClass(elem,value) {
  43.  
  44. var classes, cur, clazz, j, finalValue
  45. // 如果参数是多个样式设置"blue highlight under"按照\/S+\g空格分割
  46. classes = (value || "").match(/\S+/g) || [];
  47.  
  48. //如果是元素节点,并且有class属性
  49. //拼接成 " blue highlight under "形式,加上前后空格
  50. cur = elem.nodeType === 1 && (elem.className ?
  51. (" " + elem.className + " ").replace(/[\t\r\n\f]/g, " ") :
  52. " "
  53. );
  54.  
  55. //如果存在样式
  56. if (cur) {
  57. j = 0;
  58. while ((clazz = classes[j++])) {
  59. //查找下是否不是有重复的,没有就叠加
  60. if (cur.indexOf(" " + clazz + " ") < 0) {
  61. cur += clazz + " ";
  62. }
  63. }
  64.  
  65. // 去掉前后的空格
  66. finalValue = jQuery.trim(cur);
  67.  
  68. if (elem.className !== finalValue) {
  69. //赋值
  70. elem.className = finalValue;
  71. }
  72. }
  73. }
  74.  
  75.  
  76. /////////
  77. //移除样式 //
  78. /////////
  79. function removeClass(elem, value) {
  80.  
  81. var classes, cur, clazz, j, finalValue
  82. // 如果参数是多个样式设置"blue highlight under"按照\/S+\g空格分割
  83. classes = (value || "").match(/\S+/g) || [];
  84.  
  85. //如果是元素节点,并且有class属性
  86. //拼接成 " blue highlight under "形式,加上前后空格
  87. cur = elem.nodeType === 1 && (elem.className ?
  88. (" " + elem.className + " ").replace(/[\t\r\n\f]/g, " ") :
  89. " "
  90. );
  91.  
  92. //如果存在样式
  93. if (cur) {
  94. j = 0;
  95. while ((clazz = classes[j++])) {
  96. //与addClass的区别在这里
  97. while (cur.indexOf(" " + clazz + " ") >= 0) {
  98. cur = cur.replace(" " + clazz + " ", " ");
  99. }
  100. }
  101.  
  102. // 去掉前后的空格
  103. finalValue = jQuery.trim(cur);
  104.  
  105. if (elem.className !== finalValue) {
  106. //赋值
  107. elem.className = finalValue;
  108. }
  109. }
  110. }
  111.  
  112.  
  113.  
  114.  
  115.  
  116. </script>
  117. </body>
  118. </html>
下一节