Skip to content
/ tQuery Public

一个类 jQuery Api 的基础库,仅实现元素检索、DOM/CSS操作和Event部分。

License

Notifications You must be signed in to change notification settings

zhliner/tQuery

Repository files navigation

tQuery - 轻量节点检索器

前言

传统的 jQuery 使用十分方便友好,但随着 ES6HTML5/CSS3 的逐步成熟,我们可以编写一个轻量级的类 jQuery 工具,这就是 tQuery。它采用 ES6 语法编写,仅包含 jQuery 中有关 DOMCSSEvent 的部分,即省略了 AjaxDeferredEffect 等,因为这些部分可由 ES6/HTML5 中原生的 FetchPromiseCSS3 来支持。

tQuery 名称里的 t 来源于 Tpb 里的 Template,但也可以认为是 tiny

注:
本设计的接口虽然大部分与 jQuery 相似,但并不兼容,同名的接口只是在功能上相似而已。
可以打开 test.html 在浏览器控制台执行 console.dir($)console.dir($().__proto__) 简单地查看接口分布情况。

Api 设计

jQuery 中对检索结果集的操作,在这里都有一个单元素的版本,如:$.next(el, slr)$.hasClass(el, names) ,以及相应的集合版本:$('xx').next(...)$('xx').hasClass(...)。单元素版如果没有值需要返回,通常返回 $ 自身,集合版会返回一个值集合或一个新的 Collector 实例。与 jQuery 中类似,集合版的 Collector 返回值可以链式调用。

jQuery 相比,大多数同名接口的行为相似,但不少地方依然区别明显。如对元素集的属性取值,jQuery 中仅是对集合内首个成员取值,如 $('a').attr('href') 取首个 <a> 元素的 href 属性值,而 tQuery 中则会返回集合里全部元素的属性值(一个数组)。

又如 $.html 方法,jQuery 中它既可以处理文本,也处理节点元素,效果与连续的 $.empty().append() 调用相似。但在 tQuery 中该接口只负责文本的逻辑:设置元素内容时接收HTML文本或提取来源元素的 outerHTML 值,获取源码时提取元素的 innerHTML 值。另外也支持插入位置和HTML编码功能。

在实现上,代码不对浏览器的原生事件对象产生侵入,元素上也不存储任何数据(因此没有 .data() 方法)。设计上尽量精简,只要有可能就把任务交给原生的 ES6HTML5/CSS3 去处理。

与 jQuery 的差异简表

下面接口的名称中,前置 $. 的指 $ 的成员,前置 . 表示 $(...) 检索结果(Collector 实例)的成员。

  • .contains()

    • jQuery: 仅针对内部子孙元素,不含容器元素自身测试。
    • tQuery: 包含容器元素自身测试,与DOM同名接口行为相同。
  • .hasClass()

    • jQuery: 对空格分隔的名称序列视为一个整体。
    • tQuery: 空格分隔的名称序列被视为多个名称,逐个判断,因此 class="A B"class="B A" 是一样的。
  • .is()

    • jQuery: 只要集合中有一个匹配即为true,且可接受多种类型的参数。
    • tQuery: 对集合中每一个元素判断,返回一个true和false值混合的集合(数组),参数类型较为简单。
  • .first()/.last()

    • jQuery: 简单返回集合中首个或最后一个成员。
    • tQuery: 返回集合中首个或最后一个匹配的成员。接受一个可选的选择器匹配参数,无实参调用时与jQuery相同。
  • .next()/.prev()

    • jQuery: 简单返回下一个或前一个兄弟元素,可以传递一个选择器测试是否匹配,不匹配则返回 null
    • tQuery: 返回下一个或前一个匹配的兄弟元素,如果未传入匹配测试条件,则无条件匹配(同jQuery)。匹配测试支持函数(函数支持迭代计数)。
  • $.data()/.data()

    • jQuery: 存储与目标元素关联的任意数据,或者返回集合中匹配首个元素的存储的值。
    • tQuery: 没有该接口。元素的data-xx系属性融入在 attrprop 接口中,支持名称简写(-xx 表示 data-xx)。
  • $.get()/.get()

    • jQuery: $.get 为用 Ajax 方式通过 GET 方法获取目标网站的内容。.get 为获取集合内的某个成员。
    • tQuery: $.get 为获取文档中单个元素的版本,如通过 id 定位或 querySelector 检索。.get 为集合版的同功能接口,获取集合内某个成员采用 .item 接口。
  • $.wrap()/.wrap()/$.wrapInner()/.wrapInner()

    • jQuery: 传递包含子元素的包裹容器时,会递进到最深层子元素为实际包裹容器,整个容器为复制方式。支持选择器选择目标元素。返回原始被包裹元素的集合。
    • tQuery: 与jQuery相同,包含子元素的包裹容器会递进到最深层子元素为包裹元素,但容器元素的克隆是可选的,并且返回的是包裹容器(根)本身,同时也支持被包裹内容为文本。如果包裹元素是既有的元素,可以指定是否同时克隆元素(及其子孙元素)上绑定的事件处理器。另外,集合版支持包裹元素的数组式指定(与被包裹数据一一对应)和前值默认的功能。
  • .wrapAll()

    • jQuery: 用目标容器元素包裹集合内的全部成员,与 $.wrap() 等接口类似,容器元素会递进到首个最深层子元素(也为克隆方式),返回原始被包裹内容的集合。
    • tQuery: 用目标容器元素包裹集合内的全部成员,也与本库的 $.wrap() 等接口类似,支持包裹元素的克隆选项,返回包裹容器本身(Collector 封装),因此可以简单的链式调用(如 .appendTo() 等)。
  • $.html()/.html()

    • jQuery: 接收节点参数时,是执行简单的复制和移动,实参节点会从原来的地方脱离DOM树。数组实参会被合并为单一的值,然后拷贝赋值到各个目标。
    • tQuery: 接收节点参数时,会提取元素的 outerHTML 或文本节点的 textContent,这里是纯粹的文本逻辑,不会影响原节点,同时也可以指定插入的位置。集合版版中数组实参是一一对应的逻辑。
  • $.text()/.text()

    • jQuery: 接收节点参数时,只是简单地将节点转换为字符串,因此一个元素实际上会被转换为 [object HTMLElement] 之类的值。数组实参会被转换为数组的字符串表示,然后赋值。
    • tQuery: 接收节点参数时,会取节点的 textContent 值,不论这个节点是元素、文本节点还是注释节点。同样地,也可以指定插入的位置。集合版数组实参的说明参考 .html 接口说明。
  • $.val()/.val()

    • jQuery: 获取或设置表单控件 value 属性的值,不论该表单控件是否已 disabled,效果与 .prop('value', '...') 相同。
    • tQuery: 严格遵循表单逻辑:取值时返回 value 属性的值,设置时部分控件为对比目标值并改变控件状态(如单/复选按钮、选单等),而非修改 value 属性本身。例如不能对 <option> 控件直接取值或设置,因为它们由 <select> 管理。另外,如果控件已 disabled,则取值返回 null,设置不起作用。(:这是一个与 jQuery 版差异较大的接口)
  • $.scroll()/.scroll()

    • jQuery: 是绑定滚动事件处理器的便捷方法。
    • tQuery: 窗口/元素滚动条位置的获取或滚动到目标位置的执行(会触发事件)。:绑定事件处理器仅采用 $.on() 方法实施。

与 jQuery 的其它差异

注: tQuery 只涉及 jQuery 中与 DOM 相关的部分,因此差异对比也仅限于这一子集。

  1. 元素和节点创建。

    • jQuery: 通过 $( html ) 方式创建元素,但仅能创建元素(Element)而无法创建单纯的文本节点(Text)。
    • tQuery: 通过 $.Element( tag, data, conf ) 创建元素,通过 $.Text( data ) 创建文本节点。另外还有 SVG 和 Table 的特定接口。
  2. 数据集合对元素集合的赋值。

    • jQuery: 当数据赋值到jQuery检索的结果集时,数据被视为一个单元执行拷贝赋值。如:$('p').text([1, 3, 5]),数组被转化为一个字符串:1,3,5,然后拷贝赋值到集合中每一个段落元素。
    • tQuery: 当目标元素是集合时(Collector),部分接口中数据源的类型被区别对待:如果是一个数组,则是各自一一对应。如上述例子,集合中的前3个段落被分别填充为 123 等值。
  3. before/after/append/prepend/html/text 等接口的功能限定。

    • jQuery: 全部方法既支持节点/元素、也支持HTML字符串即时创建元素。
    • tQuery: before/after/append/prepend/replace/fill 六个方法被限定为仅支持节点/元素,因此也就支持节点/元素的克隆,以及元素上绑定的事件处理器的克隆。html/text 被严格限定为文本类操作,且支持插入位置参数和源码编解码的简单功能,条理更清晰一些。
  4. 事件委托绑定(delegate)的触发区别。

    • jQuery: 事件处理器的绑定可以用一个选择器限定事件触发的目标。从事件的触发起始元素(target)开始到委托绑定的元素,如果有多个目标元素匹配,就会触发多次事件处理器的调用。
    • tQuery: 委托绑定的规则与jQuery相同,但事件的触发仅有一次,触发的目标是从起始元素(target)开始(含 target),向上第一个匹配的元素。:从事件处理器接口(function(event, elo): Any)的第二个实参 elo 上取当前匹配元素(elo.current)。
  5. 节点变化事件(varyevent, bindevent)。

    为了跟踪DOM节点的变化,设计加入了如下定制事件:

    • attrvary, attrdone 元素特性设置:之前/完成 事件。由 .attr|.attribute|.removeAttr|.toggleAttr 接口触发。
    • propvary, propdone 元素属性设置:之前/完成 事件。由 .prop|.property|.val 接口触发。
    • stylevary, styledone 元素内联样式设置:之前/完成 事件。由 .css|.cssSets 接口触发。
    • classvary, classdone 元素类名设置:之前/完成 事件。由 .addClass|.removeClass|.toggleClass 接口触发。
    • nodein, nodeok, nodesdone 节点插入DOM:之前/完成/全部完成 事件。由5个接口 .prepend|.append|.before|.after|.replace 触发。也可能由复合类操作如 fill, wrap, wrapInner, html, text 等触发。
    • detach, detached 节点脱离DOM:之前/完成 事件。由接口 .remove 触发。
    • empty, emptied 节点内清空:之前/完成 事件。由接口 .empty 触发。
    • normalize, normalized 节点规范化:之前/完成 事件。由接口 .normalize 触发。

    这对于需要跟踪DOM节点变化的应用,可以获得节点改变之前、完成或出错三个阶段的监听处理能力。事件冒泡且不可取消,附加的消息(event.detail)包含了关联的数据。:出错和完成事件不会同时发生,两者仅有其一。

    另外,对于在元素上绑定和解绑事件处理器也提供了如下通知事件:

    • bind, bound 在元素上绑定事件处理器之前/后,适用 tQuery.on()/one() 接口。
    • unbind, unbound 在元素上解绑事件处理器之前/后,适用 tQuery.off() 接口。

    节点变化事件的功能默认关闭,需要执行 $.config( {bindevent:true, varyevent:true} ) 开启。

  6. 泛节点接口。 tQuery 中加入了5个包含非空文本和注释节点的检索接口,以便更仔细地分辨节点位置。它们是:

    • prevNode/nextNode 获取当前节点之前或之后的下一个节点,节点包含:元素、非空文本节点和可选的注释节点。如果迭代到末端依然没有条件符合,则返回 null
    • prevNodes/nextNodes 获取当前节点之前或之后的兄弟节点集,节点包含范围同上。
    • siblingNodes 获取当前节点同级的兄弟节点集,节点包含范围同上。

注意事项

tQuery 也支持 Sizzle 中很有用的直接子元素选择器 >...。如:$('>b, >a', ctx),表示选取 ctx<b><a> 直接子元素。

tQuery 可以脱离 Sizzle 使用,它采用了浏览器内置的 querySelector()/querySelectorAll() 通用方法,但该方法并不支持上面的选择器形式。实际上,tQuery 只是简单地用一个临时属性名补充到 > 之前,从而构造出一个合法的选择器(形如:P[___tquery_bcc6c0df_]>...)。

临时属性名由一个固定的前缀 ___tquery_ 和当前时间戳(16进制)以及一个结尾 _ 构成,以避免与应用冲突(您知道这点更好)。

About

一个类 jQuery Api 的基础库,仅实现元素检索、DOM/CSS操作和Event部分。

Resources

License

Stars

Watchers

Forks

Packages

No packages published