jQuery 设计思想

359 阅读1分钟

输入“选择器”,输出可以操作网页元素的api对象

jQuery的基本设计思想和主要用法,就是"选择某个网页元素,然后对其进行某种操作"。

jQuery(选择器)用于获取对应的元素,但它不返回这些元素,

相反,它返回一个对象,称为api, 这个对象可以直接操作对应的元素

下面,我们手写一个简单的window.jQuery

window.jQuery = function(selectorOrArrayOrTemplate) {
    let elements
    if(typeof selectorOrArray === 'string'){
        // 传进来的是HTML标签
        elements = document.querySelectorAll(selectorOrArray)
    }else if(selectorOrArray instanceof Array){
        // 传进来的是数组
        elements = selectorOrArray
    }

    //elements就是要操作的元素或者节点

    let api = {
        // 下面这些函数可以操作 elements
        find(selector){
            let array = []
            for(let i =0;i<elements.length;i++){
                const elements2 = Array.from(elements[i].querySelectorAll(selector))
                array.push(...elements2)
            }
            array.oldApi = this // this 就是 旧 api
            return jQuery(array)
        },
        appendTo(selector) {

        },
        addClass(className) {
            
        },
        end(className){
            
        }

    }

    return api
}

链式调用

jQuery的黑魔法之一就是支持链式调用,即

$('div')
  .find('h3')
  .addClass('red')
  .text('hi 我是新加的内容');
// 找到所有的div元素,在所有的div元素里找到h3标签,给h3标签增加'red'类,并且替换文本内容

这一点能实现就是因为jQuery(selector)返回的是一个可以操作被选中元素的api

jQuery还提供end方法,使得结果集可以后退一步:

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

getter, setter设计模式

jQuery的设计思想之三就是使用同一个函数,来完成取值(getter)和赋值(setter)。到底是取值还是赋值,由函数的参数决定,这也是函数的重载。

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

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

四、运用函数重载

运用函数重载,一个函数可以同时处理多种不同的参数

举例,$()的参数不仅可以是选择器,还可以是html标签

$('.red')
$('<div><span>哈哈哈哈<span></div>')
$(元素数组)

这是怎么实现的?答案是通过函数重载,写不同的if else判断情况

window.jQuery = function(selectorOrArrayOrTemplate){
  let elements
  if(typeof selectorOrArrayOrTemplate === 'string'){
    if(selectorOrArrayOrTemplate.trim().indexOf('<') === 0){
      // 传进来的字符串是HTML标签,例如$('<div><span>哈哈哈哈<span></div>'),
      // 所以我们需要创建对应的HTML标签,然后返回
      elements=[createElement(selectorOrArrayOrTemplate)]
    }else{
      // 查找 div 例如 $('.red')
      elements = document.querySelectorAll(selectorOrArrayOrTemplate)
    }
  }else if(selectorOrArrayOrTemplate instanceof Array){
    // 传进来的是节点数组,那么就赋值给elements, 开始下面的处理
    elements = selectorOrArrayOrTemplate
  }

  function createElement(string){
    const container = document.createElement("template");
    container.innerHTML = string.trim();
    return container.content.firstChild;
  }
  
  // api可以操作elements, this就是api, api就是this
  let api = {
    addClass(className){},
    find(selector){},
    each(){}  
  }
  
  return api

五、常用API

  • $('div').**append**(选择器/ jQuery对象) 在div的子元素里,在最后一个位置添加元素,通俗来说就是**加一个小儿子**

  • $('<h2>哈哈哈</h2>').appendTo(选择器/ jQuery对象) 在选择器选中的元素的子元素里,从尾部添加“哈哈哈” - $('div').**prepend**('h2') 在div的所有子元素里,**从头**插入h2,通俗来说就是**加一个大儿子**

    • 类似的还有$('h2').prependTo($('div'))
    • $('#test').after($div) 加一个弟弟
    • $('#test').before($div) 加一个哥哥

$div.remove()

$div.empty()

改和查

$div.text(?) 读写文本内容

$div.html(?) 读写HTML内容

$div.css({'color': 'red'}) 读写css

$div.on('click', fn)

$div.off('click', fn)