jQuery开发技术笔记
HTML DOM 加载步骤
1、 解析 HTML 结构
2、加载外部脚本和样式表文件
3、解析并执行脚本代码
4、构造 HTML DOM 模型
5、加载图片等外部文件
6、页面加载
一、总体架构
1.1:jQuery 的核心特征:
兼容主流浏览器:支持 IE 6.0+、Chrome、Firefox 3.6+、Safari 5.0+、Opera等。
具有的特的链式语法和短小清晰的多功能接口。
具有高效灵活的 CSS 选择器,并且可对 CSS 选择器进行扩展。
拥有便捷的插件扩展机制和丰富的插件。
1.2:总体架构
jQuery 的模块可以分为 3 个部分:入口模块、底层模块、功能模块。
在底层支持模块中,回调函数列表模块用于增强对回调函数的管理,支持添加、移除、触发、锁定、禁用回调函数等功能;异步队列模块用于解耦异步任务和回调函数,它在回调函数刘表的基础上为回调函数增加了状态,并提供了多个回调函数列表,支持传播任意同步或异步回调函数的成功或失败状态;数据缓存模块用于为 DOM 元素和 JavaScript 对象附加任意类型的数据;队列模块用于管理一组函数,支持函数的入队和出队操作,并确保函数按顺序执行,它基于数据缓存模块实现。
在功能模块中,事件系统提供了统一的时间绑定、响应、手动触发和移除机制,它并没有将事件直接绑定到 DOM 元素上,而是基于数据缓存模块来管理事件;ajax 模块允许从服务器上加载数据,而不用刷新页面,它基于异步队列模块来管理和触发回调函数;动画模块用于向网页中添加动画效果,它基于队列模块来管理和执行动画函数;属性操作模块用于对 HTML 属性和 DOM 属性惊醒读取、设置和移除操作;DOM 遍历模块用于在 DOM 树中遍历父元素、子元素和兄弟元素;DOM 操作模块用于插入、移除、复制和替换 DOM
元素;样式操作模块用于获取计算样式或设置内联样式;坐标模块用于读取或设置 DOM 元素的文档坐标;尺寸模块用于获取 DOM 元素的高度和宽度。
二、jQuery 特征
1、jQuery项目的4个部分:jQuery core(核心库)、jQuery UI(界面库)、sizzle(css选择器)、QUnit(测试套件)
2、jQuery选择器:
var i = 0;
$("input[type='text']").each(function(){ i += parseInt($(this).val()); });
$("input:lt(2)").add('label').css('border','none').css('borderBottom', 'solid 1px navy').css({'width':30px'})
(1) each() 方法遍历所有匹配的文本框
(2) 函数parseInt() 可以把获取的字符串类型的值转换为数值类型。
(3) $("input:lt(2)") 选择器能够匹配文档中的所有input 元素,然后筛选出排在前面的两个input元素,其中的伪类 :lt 表示序号小于某个值的意思。
3、jQuery事件
(1) HTML 文档加载步骤:解析 HTML 结构、加载外部脚本和样式表文件、解析并执行脚本代码、构造 HTML DOM模型、
加载图片等外部文件、页面加载完毕。
(2)执行时机:load 事件必须等到网页中所有内容全部加载完毕后,才被执行。如果一个页面中包含了大数据的多媒体文件,则就会出现网页文档已经呈现出来,而由于网页数据还没完全加载完毕,导致load事件不能够及时触发。
而 jQuery 的 ready 事件是在 DOM结构绘制完毕之后就执行,也就是说它先于外部文件的加载就被执行了,这样就能够确保文档呈现和脚本初始化设置保持同步。
总之,ready 事件先于 load 事件被激活,如果网页文档中没有加载外部文本文件,则他们的响应时间基本上是相同的。
4、jQuery类数组操作:元素定位、查找、复制和删除。也可以通过迭代器和映射器扩展对数组的操作功能。
(1)定位元素:
get() 和 index() 方法用来定位元素,这是集合操作的最基本方法。
jQuery还定义了get(index) 和 eq(index) 方法,读取指定位置的元素。
get(index)方法用于读取集合中的元素,它与直接通过 [i] 来读取元素的方法完全相同。
eq(index) 方法用于克隆集合中的元素,也就是说不修改数组元素。
(2)复制元素:
jQuery模拟Array的 slice() 的方法实现元素复制功能
另:模拟数组的concate() 方法定义了一个全局函数 merge().
(3)添加元素:add()方法可以将其他的元素增加到类数组中来
(4)过滤元素:fliter() 方法和 not() 方法。
filter() 方法可以筛选出与制定表达式匹配的元素集合,也可以通过该方法来筛选当前 jQuery 对象的元素,或者使用逗号分割的多个表达式。
filter() 是 grep() 和 multiFilter() 函数功能的综合,如果参数是函数,就采用 jQuery.grep() 函数来完成,否则就采用 jQuery.multiFilter() 函数进行 selector 方式的过滤。
jQuery.grep() 函数提供了以自定义函数回调的形式来过滤集合不需要的元素,最后形成需要的数组,与map() 函数功能相类似。
jQuery.multiFilter() 函数与 jQuery.filter() 函数区别不大。multiFilter 支持采用“,”符号分隔的 selector 多表达式。
例: jQuery.multiFilter = function(expr, elems, not){ if(not){ expr = ":not("+expr+")"; } return Sizzle.matches(expr, elems) }
jQuery.multiFilter() 函数可以作为筛选器,与 jQuery.filter() 函数一样, selector 的多表达式也可以只是筛选器的组合,即 .、#、:、[ 这四种符号做分隔的表达式。
not() 方法也是根据 selector 来过滤不符合条件的函数,但是not() 方法建立在filter() 方法基础之上,只想效率更高。
(5)映射元素:each() 和 map()。
each() 方法是对集合中每个元素都执行回调函数,而 map() 方法还能够手机每个回调函数的返回结果组成一个新的函数
三、构造jQuery对象
jQuery 对象是一个类数组对象,含有连续的整型属性、length属性和大量的jQuery方法。jQuery 对象由构造函数 jQuery() 创建,$() 则是 jQuery() 的缩写。
1:构造幻术jQuery()。
如果调用构造函数 jQuery() 是传入的参数不同,创建 jQuery 对象的逻辑也会随之不同。构造函数 jQuery() 有 7 中用法。
四、jQuery选择器引擎Sizzle工作原理
1、选择器引擎Sizze:
主要包括元素getElementsByTagName() 和 getElementsById()方法,以及元素的 childNodes、firstChild、nextSibling、parentNode、previousSinbling 属性。
2、选择器与过滤器
由:a、$("div[id=value]");选择器,就知道JavaScript 先匹配 div 元素,然后判断 div 元素的 id 属性是否等于 value,如果不等于就从结果集中进行操作。
b、对于$("div#value"); 选择器也是一样的, div#value 与 div[id=value] 是完全相同的操作,同样的,对于div.class也可以转换为属性选择器符进行操作。
得:可以把CSS选择器拆分为两大组成部分,或者说可以把选择器分为两类。
第一类:选择器(selector)。即根据给定的选择符,从DOM 文档树找到相关的元素节点,并存储到结果集中。
第二类:过滤器(Filter)。根据表达式的条件,在结果集中过滤元素。
3、Sizzle 过滤器:
第一部分:过滤函数(jQuery.filter()),在该函数中将对需要过滤的表达式及其对应的表达式处理函数执行分析,并返回过滤后的jQuery对象。
第二部分:过滤表达式对象(Expr = Sizzle.selectors), 该对象包含了所有表达式处理的方法和匹配的正则表达式。
4、注:
第一:多用ID选择器。即使不存在 ID 选择器,也可以从父级元素中添加一个 ID 选择器,这样就会缩短节点访问的路程。
第二:少直接使用 class 选择器。可以使用复合选择器,例如,使用 tag.class 代替 .class。文档的标签是有限的,但是类可以拓展标签的语义,那么在大部分情况下,使用同一个类的标签也是相同的。当然,对于不必要的复合表达式就应该进行简化,例如 #id2#id1 或者tag#id1 表达式,不如直接使用 #id1即可。
第三:多用父子关系,少用嵌套关系。例如,使用parent>child 代替 parent child。因为 ">" 是 child 选择器,只从子节点中匹配,不递归。 而 ”“表示为后代选择器,递归匹配所有子节点及子节点的子节点,即后代节点。
第四:缓存 jQuery 对象。如果选出结果不发生变化,则不妨缓存 jQuery 对象,这样就可以提高系统性能,养成缓存 jQuery 对象的习惯可以让你在不经意间就能够完成主要的性能优化。
三、节点操作
1-1、获取结点 :
getElementById() 方法可以精确获取指定结点的引用指针。 var a = document.getElementById(id);
getElementByTagName() 方法获取指定标签名称的所有元素对象。 a = document.getElementByTagName(tagName);
1-2、创建结点:
createElement() 方法能够根据参数指定的元素名创建一个新的结点,并返回新结点的引用指针。var e = document.createElement("element");
基本用法:使用 createElement() 方法创建的新结点不会被加载到文档中,因为新结点还没有nodeParent 属性,仅在 JavaScript 上下文中有效。所以还需要使用appendChild()、insertBefore()、replaceChild() 方法实现。
1-3、复制结点:cloneNode() 方法来复制一个结点。
1-4、删除结点:removeChild()方法。(如果方法多次使用,应当将方法封装)
1-5、替换结点:replaceChild() 方法。 例:a = e.replaceChild(newNode, oldNode);
2-1、获取结点属性:getAttribute() 方法可以获取指定元素的属性。
例:获取 id 属性:
var red = document.getElementById("red");
var attr = red.getAttribute("id"); 或 var attr = red.id。
2-2、设置结点属性:setAttrbute() 方法。
e.setAttrbute(name,value); (注:e 表示指定的元素对象;name表示属性的名称;value表示属性值)
如果元素中已存在指定的属性,则它的值将被刷新,否则此方法将为元素创建爱你该属性并赋值。
2-3、删除结点操作:removeAttribute(name)。例:e.removeAttribute(name). 注:e 表示一个元素对象,name表示元素属性名。
五、使用jQuery操作DOM
1、使用jQuery 插入元素
方法 | 描述 |
Append() | 向每个匹配的元素内追加内容 内部 |
appendTo()注意大小写,我试验时appendto没通过。 |
该方法和Append()相反,a.Append(b)是将b追加到a中,而appendTo()是将b追求到a中 内部 |
Prepend() | 向每个匹配的元素内部前置内容 内部 |
prependTo() | 该方法和Prepend()相反,a. Prepend (b)是将b前置到a中,而prependTo ()是将b前置到a中 内部 |
After() | 在每个匹配的元素之后插入内容,是之后 外部 |
insertAfter() | 和After()相反 外部 |
Before() | 在每个匹配的元素之前插入内容 外部 |
insertBefore() | 和Before()相反 外部 |
2、删除元素。即remove()和empty();
remove()方法:从 DOM 中删除所有匹配的元素。
$(“p”).remove();// 我们可以获取到要删除的元素,然后调用remove()方法
$(“ul li:eq(0)”).remove().appendTo(“ul”);// 删除ul下面的第一个li标记,然后再把删除的li标记重新加到ul里面,remove()方法返回删除元素的引用,这时你可以继续使用
$(“ul li”).remove(“li[title!=ABC]“);//remove可以接受通过参数来选择性的删除符合条件的元素;
empty()方法:删除匹配的元素集合中的所有子结点。 注:严格来讲,empty()方法并不是删除元素,而是清空
例:HTML代码
<ul> <li title=”AAA”>AAA</li> </ul>
JQuery代码: $(“ul li:eq(0)”).empty();
结果: <ul> <li title=”AAA”></li> </ul>
记住,只会清空内容,不会请空属性;
3、复制元素: clone().
4、替换元素:replaceWidth() 方法和 replaceAll() 方法,与之对应的 DOM 定义了replaceChild() 方法。
replaceWidth() 方法能够将所有匹配的元素替换成指定的 html 或者 DOM元素,replaceAll() 方法功能相同,但是操作相反。
例:替换所有 p 元素为 div 元素:
a、$("p").replaceWidth("<div>盒子</div>") ;b、$("<div>盒子</div>").replaceAll("p");
5、包裹元素:wrap()、wrapAll()、wrapInner()。
6、操作样式表:
绝对偏移位置:offset();和相对偏移位置 postion()。
所谓绝对便宜位置就是获取指定元素距离浏览器窗口左上角的偏移距离
元素的高和宽:height()、width()。
outerHeight() 和 outerWidth():返回元素的总宽和总高(包括宽高、不白和边框宽度)
innerHeight() 和 innerWidth():返回元素内容的宽度和高度(包括宽高和补白)
六、事件模型
1、事件流(DOM 2.0标准规范化了两种事件流:捕获型和冒泡型)
含义一、事件的发生是有序响应的,而不是无序触发的。即 JavaScript 事件总是从上到下或从下到上触发响应,并进行转播。
含义二、在页面中,可以多个元素同时响应同一个事件。流意味着多的意思,多个对象同时响应同一个事件,犹如流水一般,蔚为壮观。
(1)事件在传播过程中可以分为 3 个阶段。
a、捕捉阶段:首先,事件从 document 对象沿着 DOM 树向下传播到目标结点,如果目标元素的任何一个父结点注册了该事件,就有机会捕捉事件,并调用事件处理函数。
b、目标阶段:事件传播的第二阶段局势目标结点自身,注册在目标结点上的相应的事件处理函数就会被调用、执行。
c、气泡阶段:最后事件从目标结点开始返回向上进行传播。如果父结点注册了相应的事件处理函数,就会被调用。当然,并不是所有事件类型都有气泡阶段,例如:表单提交事件就只能够在当前元素身上响应,它不会向上气泡,传播给上级元素。
(2)冒泡事件流:冒泡型事件流的基本思路是是事件流按照从最特定的时间目标(即最具体的事件绑定对象)到最不特定的事件目标(Document对象)得触发顺序。也就是说,事件从下向上传递。
(3)标准事件流:
DOM2.0对事件流进行了标准化,并同时支持冒泡型事件流和捕获型事件流。但是 DOM2.0 标准规定捕获事件流先进行响应,然后才响应冒泡事件流。这两种事件流会触及 DOM 中的所有对象,从Document 对象开始,最后在Document 对象结束。
不过大部分浏览器在支持DOM标准事件流时,会影响到 window对象。
在默认情况下,事件使用冒泡事件流,而不使用捕获事件流。
2、DOM 2 级事件模型:
(1)此模型是按模块化进行开发的,整个模型共包括 4 个子模块:HTMLEvents、MutationEvents、UIEvents、MouseEvents。
模型构成:
模块 | 事件接口 | 支持的事件模型 |
HTMLEvents | Event |
abort、blur、change、error、focus、load、resize、scroll、select、submit、
unload
|
MouseEvents | MouseEvent | click、mousedown、mousemove、mouseout、mouseover、mouseup |
UIEvents | UIEvent | DOMActivate、DOMFocusIn、DOMFocusOut |
MutationEvents | MutationEvent |
注:a、HTMLEvents 和 MouseEvents 模型定义的事件类型与 0 级事件模块中的事件类型相似。
b、UIEvents 模块定的事件类型与 HTML 表单元素支持的获取焦点、失去焦点、和单击事件相似,不过对他们进行了推广,任何能接受焦点或以其他方式及获得文档元素都可以生成这类事件。
c、MutationEvents 模块定义的事件是在文档改变(意在突变)是生成的。
(3)绑定事件:
DOM 2 级规范为所有元素定义了两个方法:addEventListener() 和 removeEventListener(),他们分别用来为指定元素绑定和销毁事件类型。
addEventListener(String type, Function listener,bollean useCapture);
第一个参数:表示要绑定事件的类名称。事件类型与事件属性不同,事件类型名没有事件处理函数名前缀 on。例:对事件处理函数 onclick 来说,所对应的事件类型为 click。
第二个参数:表示回调函数,在指定类型的事件发生时调用该函数。在调用这个函数时,传递给它的唯一参数是 Event 对象。事件对象存储着与事件类型相关的信息。
第三个参数:是一个布尔值。如果为 true,则在事件传播的捕捉阶段触发响应;如果该参数值为 false,则在事件传播的冒泡阶段触发响应。
(4)销毁事件:
使用 removeEventListener() 方法从指定对象中删除已经注册的事件处理函数,设置参数和具体用法与 addEventListener() 方法相同。当临时注册一个事件处理函数是,可以在处理完毕之后迅速删除它,这样能够节省系统资源。
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
<script type="text/javascript">
var btn = document.getElementsByTagName("button");
var f = function(){ alert(this.innerHtml); }
for (var i = 0; i < btn.length; i++) {
btn[i].addEventListener("click", function(){ //绑定事件
alert(this.innerHtml);
}, true);
}
for (var i = 0; i < btn.length; i++) {
btn[i].removeEventListener("click", function(){ //销毁事件
alert(this.innerHtml);
}, true);
}
</script>
3、兼容 IE 的事件处理方法
<p id="p1">为对象注册多个事件</p>
<script type="text/javascript">
var p1 = document.getElementById("p1");
p1.onmouseover = function(){ this.style.background = "blue"; }
p1.onmouseout = function(){ this.style.background = "red"; }
p1.addEventListener("mouseover", function(){
this.style.background = "blue";
}, true);
p
</script>
七、jQuery事件模型
1.1:绑定事件:使用 bind() 绑定。
如果既想取消元素特定事件类型默认的行为,又想阻止时间起泡,可以设置事件处理函数返回值为false即可。
或者使用 preventDefault() 方法只取消默认的行为;还可以通过使用 stopPropagation() 方法阻止一个事件气泡。
1.2:使用 one() 绑定。
one() 方法是 bind() 方法的一个特例,由它绑定的事件在执行一次响应之后就会失效,其用法和 bind() 方法相同。
1.3:注销事件:unbind()。
unbind()方法与bind()方法是反向操作,能够从每一个匹配的元素中删除绑定事件。如果没有指定参数,则删除所有绑定的事件,包括 bind() 方法注册的自定义事件。如果提供了事件类型的参数,则只删除该类型的绑定事件。
例:分别为 p 元素绑定 click、mouseover、mouseout 和 dbclick 事件类型。在 dbclick 事件类型的事件处理函数中调用 unbind()。这样在没有双击段落文本之前,鼠标的移过、移动、和单击都会触发响应,一旦双击段落文本,则所有类型的事件都被注销,鼠标的移过、移动和单击动作就不再响应。
1.4:事件触发:trigger();
<p>事件触发机制</p>
$("p").click(function(){
$("p").text("鼠标点击事件");
});
$("p").mouseover(function(){
$("p").trigger("click");
})
1.5:事件切换:toggle();
八、辅助工具:
1.1:修建字符串:trim() 。
trim() 方法用于修剪字符串,清理字符串前后的空白。是一个全局函数。
1.2:序列化字符串: param()。
param() 函数能够将表单元素数组或者对象序列化,它是在serialize() 方法的基础。
序列化就是数组或者 jQuery 对象按照名/值(name/value)对格式进行序列化,而JavaScript 普通对象按照key/value 格式进行序列化。
1.3:转换数组:makeArray();
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
<script type="text/javascript">
$(function(){
var arr = $.makeArray($("li")); //转换为数组
var arr = $("li"); //会显示编译错误
$("ul").html(arr.reverse()); //用于颠倒数组中元素的顺序。
})
</script>
注:使用jQuery 获取文档中所有 li 元素,则返回的应该是一个类似数组结构的对象,但是如果直接为其调用 reverse() 数组方法,则会出现编译错误。因为 $("li"); 返回的是一个类数组结构的对象,而不是数组类型的数据。
1.4:过滤数组:grep();函数
该函数能够根据过滤函数过滤掉数组中不符合条件的元素。
jQuery.grep(array, callback, [invert]);
参数array 表示要过滤的数组,callback 表示过滤函数。第三个参数是一个布尔值,如果为 false 或者没有设置,则返回数组中有过滤函数返回 true 的元素;如果该参数为 true,则返回过滤函数中返回 false的元素。
1.5:映射数组:map();
该函数拥有 grep() 函数的过滤功能,同时还可以把当前数组根据处理函数处理后,映射为新的数组,甚至可以在影射过程中发达数组。
2:队列:
定义队列:queue(name, callback); 获取队列queue(name); 删除队列dbqueue()
九、异步通信开发
1.1 :认识 HTTP : 主要组成部分:请求(Request)和响应(Response)。
1.2:HTTP 请求:请求信息分三部分:请求行、消息报头、请求正文(可选)
1.3:HTTP 响应:状态行、消息报头、响应正文(可选)。
2:使用隐藏框架实现异步通信
2.1:隐藏框架
所谓隐藏框架,就是设置框架页显示高度为 0,以达到隐藏显示的目的。关于这个技术也被人称为远程脚本(Remote Scripting)技术,即远程过程(函数)调用。