学习jQuery设计思想有感

306 阅读2分钟

前言

马上就快到2022年了,jQuery已然过时,那我们新人是否还有学习jQuery的必要呢?

我认为是有的,因为jQuery中也蕴含了很多编程套路,我们新人应该学习一些jQuery的思想,它可以作为一个过渡,帮助我们更好地理解Vue和React等更为复杂的框架

设计思想

我们知道,jQuery的基本设计思想和主要用法,就是"选择某个网页元素,然后对其进行某种操作"。
展开来讲就是:提供一个函数,这个函数接受一个选择器(或数组),根据这个选择器获取一些元素,然后返回一个对象(我们称为api),这个对象有一些方法可以操作这些元素。

根据这个思想,我们就可以简单地写出一个丐版jQuery

window.$ = window.jQuery = function(selectorOrArray){
    let elements
    if(typeof selectorOrArray ==='string'){
        elements = document.querySelectorAll(selectorOrArray)
    }else if(selectorOrArray instanceof Array){
        elements  = selectorOrArray
    }
    let api = {
        addClass(className){
            for(let i=0;i<elements.length;i++){
                elements[i].classList.add(className)
            }
            return this
        },
        find(selector){
            let array = []
            for(let i=0;i<elements.length;i++){
               const elements2 = Array.from(elements[i].querySelectorAll(selector))//新建一个elements2等于把遍历到的元素组成的数组
               array = array.concat(elements2)//把elements2放入空数组 
            }
            array.oldApi = this //this是旧api,这个oldApi只是放在数组里面,所以需要添加oldApi:selectorOrArray.oldApi,让它可以放在选择器或数组里面
            return jQuery(array)//新建一个Api对象,让jQuery接受数组,新的Api来操作这个数组
        },
        oldApi:selectorOrArray.oldApi,
        end(){
            ......
        },
        each(fn){
            ......
        }
    }
     return api
}

光是通过这段简短代码,就能够体现jQuery的两个核心设计思想

闭包

这里的addClass和find函数访问了外部的变量elements,这样的好处是:
用户永远不能直接操作elements只能用过函数操作elements,只要函数不死,elements就不会死,因为这个函数在访问elements,被访问的东西是不能随便删掉的

链式调用

(以下jQuery()均写为$)
上述代码中是通过addClass的return this(这个this就是api),来实现这个操作
它有什么用途?

$('div').find('h3').eq(2).html('Hello');
//找到所有的div元素,在div元素了找到h3标签,选择第三个h3标签,替换文本内容

可以看到,这样连起来调用的方式就称为链式调用,它在下次调用函数时,新的函数包含了上一个函数返回的值,所以它可以把不同的操作连在一起
不仅如此,jQuery还提供了一个end方法,使得结果集可以返回上一步

  $('div')
   .find('h3')
   .eq(2)
   .html('Hello')
   .end() //退回到选中所有的h3元素的那一步
   .eq(0) //选中第一个h3元素
   .html('World'); //将它的内容改为World

jQuery还有很多其他的设计思想,如:

getter/setter

  $('h1').html(); //html()没有参数,表示取出h1的值
  $('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值

重载

运用函数的重载,一个函数可以同时处理多个不同的参数
如,$()的参数不能可以是选择器,还可以是html标签等

$('.red')
$('<div><span>你好<span></div>')

其余设计思想,请看阮一峰老师的博客:jQuery设计思想

学习这些设计思想,可以让我们学会很多编程技巧,帮助我们自己造轮子,而不是只会一味的调用其他库或框架提供的功能

常见的API

获取元素

表达式可以是CSS选择器:

  • $(document) 选择整个文档对象
  • $('#myId') 选择ID为myId的网页元素
  • $('div.myClass') 选择class为myClass的div元素
  • $('input[name=first]') 选择name属性等于first的input元素
  • ......

也可以是jQuery特有的表达式

  • $('a:first') 选择网页中第一个a元素
  • $('tr:odd') 选择表格的奇数行
  • $('#myForm :input') 选择表单中的input元素
  • $('div:visible') 选择可见的div元素
  • ......

  • $('.inner').append('<p>Test</p>')
    • 在所有class为inner的元素最后面添加一个p标签,简单来说,就是用来添加老幺
  • $('<p>Test</p>').appendTo('.inner')
    • 作用与append相同,但是语法顺序不同
  • $('.inner').prepend('<p>Test</p>')
    • 在所有class为inner的元素最前面添加一个p标签,简单来说,就是用来添加老大
  • $('<p>Test</p>').prependTo('.inner')
    • 作用与prepend相同,语法不同
  • $('<div/>').after('<p>Test</p>')$('<p>Test</p>').insertAfter('.inner')
    • 作用与append,appendTo相同
  • ('<div/>').before('<p>Test</p>')$('<p>Test</p>').insertBefore('.inner')
    • 作用与prepend,prepend相同

  • $('.hello').empty()
    • 删除class为hello里的所有子节点
  • $('.hello').remove()
    • 删除class为hello的元素,如果hello里面包含子节点,子节点同样会被移除
  • $('div').remove('.hello')
    • 添加一个可选的选择器参数来过滤匹配的元素,删除div里面class为hello的元素

改和查

  • $('div').insertAfter($('p'))

    • 如果div和p都是现有元素,那么这个方法可以把div移到p后面
    • $('p').after($('div')) 也可以实现这个操作
    • 它们的不同就是返回的元素不一样,第一种返回的是div,第二种是p
    • 同样地,在增操作里的所有API都可以实现这样的移动功能
  • 读写内容

  $('h1').html(); //html()没有参数,表示取出h1的值
  $('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值

类似地,取值和赋值函数有:

 .html() 取出或设置html内容
 .text() 取出或设置text内容
 .attr() 取出或设置某个属性的值
 ......
  • 读写CSS
//读
$(div).css("background-color") 读取div的背景色
$(div).css(["width", "height", "color", "background-color"]) 读取div的多个属性值
//写
$(div).css("color","red") 更改div的颜色
$(div).css({'background-color' : 'yellow', 'font-weight' : 'bolder'}) 更改div的多个属性值
  • $(div).on('click', fn)
    • 给div添加一个名为click的监听事件
  • $(div).off('click', fn)
    • 删除这个监听事件

完整API 请参考:jQuery_API中文文档