从 0 开始开发 jquery 工具库(五)

3,814 阅读2分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。

写在前面

  • 前面一篇文章,实现了 jquery 中操作页面元素的样式的方法
  • 同时也留下疑问,jquery 中立足未来的设计指的是什么?
  • 前面实现的设置元素样式的方法中,接受的参数都是字符串,那么样式的值为数字时,该怎么办呢?

立足未来

  • 我们都知道 css 规范是由 W3C 组织进行维护的,因此 css 会在未来很长一段时间内,都是稳定持续的发展
  • 而 jquery 并没有相应的组织对其进行长期稳定的维护
  • 那么未来某一天,当 css 中出现了新的属性时,jquery 还如何能够支持呢?

cssNumber

  • 我们首先解决,第一个问题,元素属性值为数字时,怎么判断是否加上单位 px
  • 解决办法非常简单粗暴,给 $ 全局属性增加一个属性名为 cssNumber 的配置对象
  • 代码如下
$.cssNumber = {
  animationIterationCount: true,
  columnCount: true,
  fillOpacity: true,
  flexGrow: true,
  flexShrink: true,
  fontWeight: true,
  gridArea: true,
  gridColumn: true,
  gridColumnEnd: true,
  gridColumnStart: true,
  gridRow: true,
  gridRowEnd: true,
  gridRowStart: true,
  lineHeight: true,
  opacity: true,
  order: true,
  orphans: true,
  widows: true,
  zIndex: true,
  zoom: true,
};
  • 该对象的属性名为 css 属性名,值为布尔类型
  • 当属性名对应的值为 true 时,表示该 css 属性值为数字
  • 因此需要改写 #setStyle
  #setStyle(ele, attr, value) {
    if (typeof value === "number" && !(attr in $.cssNumber)) {
      value += "px";
    }
      
    ele.style[attr] = value;
  }
  • 当设置样式时,传入的数字,并且其属性名不存在于 cssNumber 中时,才给属性值加上单位 "px"

cssHooks

  • cssHooks 就是文章开头说的立足未来的设计
  • 一旦 css 的发展中出现了,jquery 未能支持的属性操作时,可以由开发者自行设计并实现该属性的相应操作
  • 其实 cssHooks 就是一个空对象
$.cssHooks = {};
  • 下面是我们使用 cssHooks 的场景
    $.cssHooks.wh = {
      get(ele) {
        console.log(ele);
        return getComputedStyle(ele, null)["width"] + "-" + getComputedStyle(ele, null)["height"];
      },
      set(ele, styleValue) {
        ele.style["width"] = styleValue;
        ele.style["height"] = styleValue;
      },
    };
    $(".btn").css("wh", "100px"); // set
    console.log($(".btn").css("wh")); // get
  • 上面是假定的一个 css 属性 wh,有了 cssHooks ,开发者可以完全自定义该属性的设置和获取的行为
  • 为了兼容 cssHooks,就需要改写 #getStyle 与 #setStyle
  #setStyle(ele, attr, value) {
    if (typeof value === "number" && !(attr in $.cssNumber)) {
      value += "px";
    }

    if (attr in $.cssHooks) {
      $.cssHooks[attr].set(ele, value);
    } else {
      ele.style[attr] = value;
    }
  }

  #getStyle(ele, attr) {
    if (attr in $.cssHooks) {
      return $.cssHooks[attr].get(ele);
    }

    // return getComputedStyle(ele, null).getPropertyValue(attr);
    return getComputedStyle(ele, null)[attr];
  }
  • 如果样式名在 cssHooks 中,则直接使用预先由开发者在 cssHooks 中定义的样式获取和设置方法

小结

  • 至此,我们已经实现了 my-jquery 中多事件绑定,链式调用,操作节点回滚、样式操作,以及立足未来的样式操作等功能
  • 下篇文章我们总结前面所有的 my-jquery 所实现的功能,实现一个动画函数 animate

最后

  • 今天的分享就到这里了,欢迎大家在评论区里面进行讨论 👏。
  • 如果觉得文章写的不错的话,希望大家不要吝惜点赞,大家的鼓励是我分享的最大动力 🥰