jQuery是总入口,选择器支持9种方式的处理
(1)基本
#id
element
.class
*
selector1,selector2,selectorN
(2)层次选择器:
ancestor descendant
parent > child
prev + next
prev ~ siblings
(3)基本过滤器选择器
:first
:last
:not
:even
:odd
:eq
:gt
:lt
:header
:animated
(4)内容过滤器选择器
:contains
:empty
:has
:parent
(5)可见性过滤器选择器
:hidden
:visible
(6)属性过滤器选择器
[attribute]
[attribute=value]
[attribute!=value]
[attribute^=value]
[attribute$=value]
[attribute*=value]
[attrSel1][attrSel2][attrSelN]
(7)子元素过滤器选择器
:nth-child
:first-child
:last-child
:only-child
(8)表单选择器
:input
:text
:password
:radio
:checkbox
:submit
:image
:reset
:button
:file
:hidden
(9)表单过滤器选择器
:enabled
:disabled
:checked
:selected
jQuery查询的的对象是dom元素,查询到目标元素后,如何存储?
查询的到结果储存到jQuery对象内部,由于查询的dom可能是单一元素,也可能是合集
jQuery内部应该要定义一个合集数组,用于存在选择后的dom元素,
当然啦,根据API,jQuery构建的不仅仅只是DOM元素,还有HTML字符串,Object,[] 等等…
ownerDocument和documentElement的区别
- ownerDocument是Node对象的一个属性,返回的是某个元素的根节点文档对象:即document对象
- documentElement是Document对象的属性,返回的是文档根节点
- 对于HTML文档来说,documentElement是<html>标签对应的Element对象,ownerDocument是document对象
jQuery.parseHTML
使用原生的DOM元素的创建函数将字符串转换为一组DOM元素,然后,可以插入到文档中。
str = "hello, <b>my name is</b> jQuery.",
html = $.parseHTML( str ),
~jQuery 构造器~
从本质上来说,构建的jQuery对象,其实不仅仅只是dom,还有很多附加的元素,用数组的方式存储,当然各种组合有不一样,但是存储的方式是一样的
总的来说分2大类:
单个DOM元素,如$(ID),直接把DOM元素作数组传递给this对象
多个DOM元素,集合形式,可以通过CSS选择器匹配是有的DOM元素,过滤操作,构建数据结构
CSS选择器是通过jQuery.find(selector)函数完成的,通过它可以分析选择器字符串,并在DOM文档树中查找符合语法的元素集合
为什么排版引擎解析CSS选择器时一定要从右往左解析
而如果按从左到右的方式进行查找
- 先找到所有div节点
- 第一个div节点内找到所有的子div,并且是class=”Aaron”
- 然后再一次匹配p span.red等情况
- 遇到不匹配的情况,就必须回溯到一开始搜索的div或者p节点,然后去搜索下个节点,重复这样的过程。这样的搜索过程对于一个只是匹配很少节点的选择器来说,效率是极低的,因为我们花费了大量的时间在回溯匹配不符合规则的节点。
如果换个思路,我们一开始过滤出跟目标节点最符合的集合出来,再在这个集合进行搜索,大大降低了搜索空间
从右到左来解析选择器
则首先就查找到<span class='red'>的元素。
firefox称这种查找方式为key selector(关键字查询),所谓的关键字就是样式规则中最后(最右边)的规则,上面的key就是span.red。
紧接着我们判断这些节点中的前兄弟节点是否符合p这个规则,这样就又减少了集合的元素,只有符合当前的子规则才会匹配再上一条子规则
要知道DOM树是一个什么样的结构,一个元素可能有若干子元素,如果每一个都去判断一下显然性能太差。而一个子元素只有一个父元素,所以找起来非常方便。你可以看看css的选择器的设计,完全是为了优化从子元素找父元素而决定的。
所以浏览器解析CSS的引擎就是用这样的算法去解析
什么是JavaScript的“预编译”?
- 按理说,两个签名完全相同的函数,在其他编程语言中应该是非法的。但在JavaScript中,这没错。不过,程序运行之后却发现一个奇怪的现象:两次调用都只是最后那个函数里输出的值!显然第一个函数没有起到任何作用。这又是为什么呢?
- JavaScript执行引擎并非一行一行地分析和执行程序,而是一段一段地进行预编译后让后 再执行的。而且,在同一段程序中,函数 在被执行之前 会被预定义,后定定义的 同名函数 会覆盖 先定义的函数。在调用函数的时候,只会调用后一个预定义的函数(因为后一个预定义的函数把前一个预定义的函数覆盖了)。也就是说,在第一次调用myfunc之前,第一个函数语句定义的代码逻辑,已被第二个函数定义语句覆盖了。所以,两次都调用都是执行最后一个函数逻辑了。
一段代码中的定义式函数语句会优先执行,这似乎有点象静态语言的编译概念。所以,这一特征也被有些人称为:JavaScript的“预编译”
所以总结下:JS 解析器在执行语句前会将函数声明和变量定义进行"预编译",而这个"预编译",并非一个页面一个页面地"预编译",而是一段一段地预编译,所谓的段就是一 个 <script> 块。
JavaScript是一门单线程语言,因此一旦有某个API阻塞了当前线程,就相当于阻塞了整个程序,所以“异步”在JavaScript编程中占有很重要的地位。异步编程对程序执行效果的好处这里就不多谈了,但是异步编程对于开发者来说十分麻烦,它会将程序逻辑拆分地支离破碎,语义完全丢失。因此,许多程序员都在打造一些异步编程模型已经相关的API来简化异步编程工作,例如Promise模型
现在有的异步流程控制大多是基于CommonJS Promises规范,比如 jsdeferred,jQuery自己的deferred等等
网友评论