美文网首页
自己动手构造API理解jQuery

自己动手构造API理解jQuery

作者: kiterumer | 来源:发表于2019-04-10 20:15 被阅读0次

封装两个函数,一个用来获取某个节点的兄弟姐妹,一个用来给元素添加类
现在有一个无序列表。循序渐进,体会jQuery设计思想。

<!-- ul>li[id=item$]{选项$}*5 -->
    <ul>
        <li id="item1">选项1</li>
        <li id="item2">选项2</li>
        <li id="item3">选项3</li>
        <li id="item4">选项4</li>
        <li id="item5">选项5</li>
    </ul>

封装两个函数

封装一个获取兄弟姐妹函数getSiblings

function getSiblings(node){  /* API */
    var allChildren = node.parentNode.children ;
    // 伪数组
    var array = {
        length: 0
    }
    // 获取node的兄弟姐妹
    for (let i = 0; i < allChildren.length; i++){
        if(allChildren[i] !== node){
            // array是伪数组,没有push方法
            array[array.length] = allChildren[i];
            array.length += 1;
        }
    }
    return array
}

封装添加类函数addClass

//添加的类用数组表示
function addClass(node,classes){
    classes.forEach(value => {
        node.classList.add(value)
    });
}

命名空间

两个函数不能就这么随意的放着,赋予一个命名空间

// getSiblings,addClass作为yyydom对象的方法
window.yyydom = {}
yyydom.getSiblings = getSiblings
yyydom.addClass = addClass

yyydom.addClass(item2,['a','b'])
//这种调用方式并不好,我们希望将node节点放在前面

把node放在前面进行调用

有两种方法:

  1. 扩展 Node 接口,直接在 Node.prototype 上加函数
  2. 自己创建新的接口

1.篡改Node.prototype,添加函数

Node.prototype.getSiblings = function(){
 var allChildren = this.parentNode.children ;
    // 伪数组
    var array = {
        length: 0
    }
    // 获取node的兄弟姐妹
    for (let i = 0; i < allChildren.length; i++){
        if(allChildren[i] !== this){
            // array是伪数组,没有push方法
            array[array.length] = allChildren[i];
            array.length += 1;
        }
    }
    return array
}

Node.prototype.addClass2 = function(classes){
 classes.forEach(value => {
        this.classList.add(value)
    });
}
// 用call显示this,call的第一个参数就是this
// item3.getSiblings()
// item3.getSiblings.call(item3) ,等价上
// item3.addClass(['q','w','e'])
// item3.addClass(item3,['q','w','e'])  等价上

但是,在Node原型上增加方法也不好,如果有多个人修改容易造成冲突。既然这样,不如自己创建一个新Node构造函数。自己动手,丰衣足食。

2.自己创建新的接口(无侵入)

window.Node2 = function(node){
    return {
        getSiblings:function(){
            var allChildren = node.parentNode.children ;
            // 伪数组
            var array = {
            length: 0
            }
            // 获取node的兄弟姐妹
            for (let i = 0; i < allChildren.length; i++){
            if(allChildren[i] !== node){
            // array是伪数组,没有push方法
            array[array.length] = allChildren[i];
            array.length += 1;
            }
            }
            return array
        },
        addClass:function(classes){
            classes.forEach(value => {
                node.classList.add(value)
            });
        }
    }
}
var node2 = Node2(item3)
node2.getSiblings()
node2.addClass(['p','o'])

构造函数Node2返回一个新对象,这个对象有getSiblings和addClass两个方法,里面还是调用的原生API。似乎离目标越来越近了。

Node2是随意取的,改为jQuery,于是

var node2 = jQuery(item3)
node2.getSiblings()

再进一步,window.$ = jQuery,再省略window,于是就变成了

var node2 = $(item3)
node2.getSiblings()

是不是很熟悉呢?

选择器多样化

目前我们所创建的构造函数只能获取节点,如果是其他选择器呢,比如$('ul>li:nth-child(3)'),那么需要加一些判断

window.jQuery = function(nodeOrSelector){
    //是否为字符串
    if(typeof nodeOrSelector === 'string'){
  //利用了原生的document.querySelector
        node = document.querySelector(nodeOrSelector)
    }else{
        node = nodeOrSelector
    }

    return {
        getSiblings:function(){
            var allChildren = node.parentNode.children ;
            // 伪数组
            var array = {
            length: 0
            }
            // 获取node的兄弟姐妹
            for (let i = 0; i < allChildren.length; i++){
            if(allChildren[i] !== node){
            // array是伪数组,没有push方法
            array[array.length] = allChildren[i];
            array.length += 1;
            }
            }
            return array
        },
        addClass:function(classes){
            classes.forEach(value => {
                node.classList.add(value)
            });
        }
    }

}

//获取列表第五个元素
var node2 = jQuery('ul>li:nth-child(5)')
// 给我旧的对象,返回新的对象
node2.addClass(['red'])

那么要获取多个节点呢,这是里面就要用到document.querySelectorAll,而且部分逻辑也有变化

window.jQuery2 = function(nodeOrSelector){
    let nodes  //最后要返回的对象
    if(typeof nodeOrSelector === 'string'){
        nodes = document.querySelectorAll(nodeOrSelector) //伪数组
    }else if(nodeOrSelector instanceof Node){
        // 保证返回结果一致,都为伪数组
        nodes = {
            0: nodeOrSelector,
            length: 1
        }
    }
   //添加类
    nodes.addClass = function(classes){
        classes.forEach((value) => {
            // 给nodes数组里每一项添加类
            for (let i = 0;i < nodes.length; i++){
                nodes[i].classList.add(value)
            }
        })
    }
    // 获取元素文本
    nodes.getText = function(){
        var texts = []
        for(let i = 0;i < nodes.length;i++){
            texts.push(nodes[i].textContent)
        }
        return texts
    }
    // 设置文本
    nodes.setText = function(text){
        for(let i=0;i<nodes.length;i++){
            nodes[i].textContent = text
        }
    }
    // 两者合并,这种在jQuery中非常常见
    nodes.text = function(text){
        if(text === undefined){
            var texts = []
            for(let i = 0;i < nodes.length;i++){
            texts.push(nodes[i].textContent)
            }
            return texts
        }else{
            for(let i=0;i<nodes.length;i++){
                nodes[i].textContent = text
            }
        }
    }
    return nodes
}
var node3 = jQuery2('ul>li')
node3.addClass(['red'])
node3.text('yyy')
//这大概就是最终体了

相关文章

  • 自己动手构造API理解jQuery

    封装两个函数,一个用来获取某个节点的兄弟姐妹,一个用来给元素添加类现在有一个无序列表。循序渐进,体会jQuery设...

  • 自定义封装一个简易jQuery

    jQuery实质为构造函数,这个构造函数接受一个参数,jQuery内部通过这个参数利用原生的API找到相对应的DO...

  • jquery内部实现原理

    含摘录,非原创 jQuery实质上是一个构造函数,该构造函数接受一个参数,jQuery通过这个参数利用原生API找...

  • 封装几个简单的jQuery方法

    Query实质上是一个构造函数,该构造函数接受一个参数,jQuery通过这个参数利用原生API找到节点,之后返回...

  • 初识 jQuery API

    最近在了解 jQuery API的相关知识,方方老师通过自己写一个jQery API,告诉我们jQuery API...

  • 初探jQuery

    jQuery API的实现 自己模拟jQuery的一个API预览:http://js.jirengu.com/pa...

  • js 中的 function.prototype 在jQuery

    在jQuery源码中,jQuery是一个构造函数,而这个特殊的构造函数使得 “ jQuery() ” 就可以构造出...

  • 实现一个jQuery 的 API

    一、需求:构造一个名叫“ jQuery” 的 库,含有API:1.addClass():给所选元素添加一个clas...

  • 实现一个 jQuery 的 API

    jQuery实质上就是一个构造函数,和DOM一样,提供我们一些API,使得节点通过这些API来构成一个对象,从而使...

  • jQuery |动画

    利用jQuery ,自己动手做动画。使用jQuery 的animate() 方法,制作动画。 语法: $(sele...

网友评论

      本文标题:自己动手构造API理解jQuery

      本文链接:https://www.haomeiwen.com/subject/rfwoiqtx.html