jQuery源码阅读笔记(7)

文档插入

再看一组逻辑一致的方法,按一样的套路解决

  • append(content|fn) – 将参数添加至匹配元素尾部
  • prepend(content|fn) – 将参数添加至匹配元素头部
  • after(content|fn) – 将参数添加至匹配元素后方
  • before(content|fn) – 将参数添加至匹配元素前方

通用逻辑

  • 概述:将参数插入至匹配元素相应的位置
  • 解析:
    • 与前面的不同,这边参数接收的尺度要宽一些
    • 对于字符串,不会再当作选择器处理,直接以HTML形式插入
    • 对于数字,当作字符串处理,对于普通对象不搭理,对于数组,则遍历按规矩处理
    • 对于函数
      • 遍历当前的调用者,将遍历的索引值和当前遍历元素的内容作为参数提供给函数,且函数执行时的this指向此元素
      • 将执行函数的返回值重新塞入进行判断
    • 返回值为调用者

因为已经有经验,那么此处就直接展示最后的集合版

jquery.each([
    {
      type: "append",
      position: "beforeend",
    }, {
      type: "prepend",
      position: "afterbegin",
    }, {
      type: "after",
      position: "afterend",
    }, {
      type: "before",
      position: "beforebegin",
    },
  ], (_i, { type, position }) => {
    jquery.fn[type] = function(content) {
      //不接受null 和 undefined
      if (content == null) {
        return this;
      } else if (isFunction(content)) {//对于函数,将返回值重新重新塞入
        return this.each(function(index) {
          jquery(this)[type](content.call(this, index, this.innerHTML));
        });
      } else if (isArrayLike(content)) {//对于数组
        const n = this.length;//记录当前调用者的长度
        return this.each( function (index) {
          //创造一个定位节点
          const node = document.createElement("div");
          //将节点插入至相应的位置
          this.insertAdjacentElement(position, node);
          //获取定位节点的父节点,由它来操控定位节点
          const father = node.parentNode;
          //当遍历不为最后一次时,需要检查是否有节点元素,进行克隆
		  if (index === n - 1) {
            $.each(content, (_i, target) => {
              if (typeof target === "object" && this.nodeType) {
                father.insertBefore(target, node);
              } else {
                node.insertAdjacentHTML('beforebegin', target);
              }
            });
          } else {
            $.each(content, (_i, target) => {
              if (typeof target === "object" && this.nodeType) {
                father.insertBefore(target.cloneNode(true), node);
              } else {
                node.insertAdjacentHTML('beforebegin', target);
              }
            });
          }
          //最后移除掉定位节点
          node.remove();
        });
      } else if (content.nodeType) {//对于DOM元素节点,需要保留样本,克隆
        return this.each((index, value) => {
          if (index === this.length - 1) {
            value.insertAdjacentElement(position, content);
          } else {
            value.insertAdjacentElement(position, content.cloneNode(true));
          }
        });
      } else if (typeof content !== "object") {//普通的对象不接收
        return this.each(function() {
          this.insertAdjacentHTML(position, content);
        });
      }
    };
  });

因为参数的宽大政策,导致结构更加的复杂,这一点很坑

对于数组参数的处理当中,我是想直接遍历数组,将元素一个个塞入,但是对于头部插入时又会导致上下颠倒,强行遍历也需要根据数据类型来定,不过这么写条件限制也不会有好结果,点到为止

对于文档处理的函数,都涉及到了克隆,不仅仅是节点本身克隆,还有事件,所以后续的几个方法暂时略过,等完成事件处理后再回补

属性操作

属性的操作上,分了三批

  • HTML内容、纯文本、value值

  • CSS类

  • 属性与属性节点

HTML内容、纯文本、value值

从这三个函数入手

  • html([val|fn])

  • text([val|fn])

  • val([val|fn])

对于参数的逻辑处理是一致,只是读取和修改的值不一样

三者的逻辑总结

  • 没有参数时,返回第一个匹配元素的内容
  • 有参数,则将参数设定为所有匹配元素的内容
  • 对于函数参数,则会执行遍历,提供相应的参数,有效的返回值将作为对应元素的内容

对于内容,原生DOM元素都有相应可读可写的属性

//HTML\text\value
jquery.fn.extend({
    html(value) {
        return modifiedData.call(this, "innerHTML", value);
    },
    text(value) {
        return modifiedData.call(this, "innerText", value);
    },
    val(value) {
        return modifiedData.call(this, "value", value);
    },
});

再搭建modifiedData()函数

//type对应属性 value对应收到的参数
const modifiedData = function(type, value) {
    if (typeof value == 'undefined') {//null可以接受,作为清空属性使用
        return this[0][type];
    } else if (isFunction(value)) {
        return this.each(function(index) {
            const data = value.call(this, index, this[type]);
            if (typeof data != 'undefined') {
                this[type] = data;
            }
        });
    } else {
        return this.each(function() {
            this[type] = value;
        });
    }
};

需要注意的是,这三个都是属性,修改value值时,并不会改变属性节点value

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值