总结常用的api ,学习jQuery的设计模式
前言:之前参与项目时,连Javascript都没学明白的我,靠着jQuery也完成了任务,决定走前端这条道路后,我重头开始学JavaScript,DOM…… 学到jQuery时,这次我不再是拿来用用了,而是学习它的设计模式并自己模仿实现JQuery的部分API
👉学习jQuery的设计模式——手写jQuery
jQuery操作元素
选取元素
jQuery基础语法是:$(selector).action()——“选取元素,对其操作”,所以第一步就是学习jQuery 如何获取元素。
jQuery 使用 CSS 选择器来选取 HTML 元素,使用 XPath 表达式来选择带有给定属性的元素,也可以是使用特有的过滤表达式来选取元素。
css选择器
jQuery的选择器表达式可以是CSS 选择器来选取 HTML 元素
$("p") 选取 <p> 元素。
$("p.intro") 选取所有 class="intro" 的 <p> 元素。
$("p#demo") 选取所有 id="demo" 的 <p> 元素。
XPath表达式
jQuery的选择器表达式可以是XPath 表达式来选择带有给定属性的元素
$("[href]") 选取所有带有 href 属性的元素。
$("[href='#']") 选取所有带有 href 值等于 "#" 的元素。
$("[href!='#']") 选取所有带有 href 值不等于 "#" 的元素。
$("[href$='.jpg']") 选取所有 href 值以 ".jpg" 结尾的元素。
过滤表达式
jQuery的选择器表达式可以是jQuery特有的表达式 ,对元素进行过滤,获取到特定的元素
$('a:first') //选择网页中第一个a元素
$('tr:odd') //选择表格的奇数行
$('#myForm :input') // 选择表单中的input元素
$('div:visible') //选择可见的div元素
$('div:gt(2)') // 选择所有的div元素,除了前三个
$('div:animated') // 选择当前处于动画状态的div元素
查找元素
jQuery提供了在DOM树上移动的方法来查找元素,从被选(当前的)元素开始,在DOM树中向上移动(祖先),向下移动(子孙),水平移动(同胞),这种移动被也称为对 DOM 进行遍历。
$("span").parent();//返回每个 <span> 元素的的直接父元素
$("span").parents();//返回所有 <span> 元素的所有祖先
$("div").children();//返回每个 <div> 元素的所有直接子元素
$("div").find("span");//返回属于 <div> 后代的所有 <span> 元素
$("h2").siblings();//返回 <h2> 的所有同胞元素
$("h2").next();//返回 <h2> 的下一个同胞元素
//三个最基本的过滤方法是:first(), last() 和 eq()
$("div p").first();//first() 方法返回被选元素的首个元素
$("div p").last();//last() 方法返回被选元素的最后一个元素
$("p").eq(1);//选取第二个 <p> 元素
创建元素
创建新元素的方法非常简单,只要把新元素直接传入jQuery的构造函数就行了:
但是在上文介绍jQuery的基本语法中,括号中的内容是选择器,为什么现在可以直接传入HTML内容来创建元素?
这就是因为jQuery使用重载的设计模式。
$('<p>Hello</p>');
$('<li class="new">new list item</li>');
元素的取值和赋值
jQuery使用同一个API,根据接收参数的不同,来完成取值(getter)或赋值(setter),即"取值器"与"赋值器"合一,这也是jQuery中使用的一种优秀的设计模式。
- 举例:
$('h1').html(); //html()没有参数,表示取出h1的值
$('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值
- 常见的取值和赋值函数
.html() 取出或设置html内容
.text() 取出或设置text内容
.attr() 取出或设置某个属性的值
.width() 取出或设置某个元素的宽度
.height() 取出或设置某个元素的高度
.val() 取出某个表单元素的值
如果结果集包含多个元素,那么赋值的时候,将对其中所有的元素赋值。 取值的时候,则是只取出第一个元素的值(.text()例外,它取出所有元素的text内容)
移动元素
jQuery提供两组方法,来操作元素在网页中的位置移动。一组方法是直接移动该元素,另一组方法是移动其他元素,使得目标元素达到我们想要的位置
- 举例:
//第一种方法是使用.insertAfter()
//把div元素移动p元素后面
$('div').insertAfter($('p'));
//第二种方法是使用.after()
//把p元素加到div元素前面
$('p').after($('div'));
二者区别:返回的元素不一样。第一种方法返回div元素,第二种方法返回p元素。
- 类似操作方法共4对
.insertAfter()和.after() //在现存元素的外部,从后面插入元素
.insertBefore()和.before() //在现存元素的外部,从前面插入元素
.appendTo()和.append() //在现存元素的内部,从后面插入元素
.prependTo()和.prepend() //在现存元素的内部,从前面插入元素
删除元素
.remove()
——将匹配元素集合从DOM中删除。(注:同时移除元素上的事件及 jQuery 数据)
.detach()
——从DOM中去掉所有匹配的元素(注:保留元素上的事件及 jQuery 数据)
.empty()
——从DOM中移除集合中匹配元素的所有子节点
链式操作
jquery的核心操作:提供一个函数,参数是选择器,函数内部根据选择器获取这些元素后,返回一个jQuery对象(jquery函数构造出来的对象),后续每一步的jQuery操作也都是返回一个jQuery对象,就实现了链式操作。
$('#test2').find('.child').addClass('green').addClass('blue')
jQuery还提供了.end()方法,使得结果集可以后退一步:
$('#parent').find('.child').addClass('green').end().addClass('old');//退回到选中的parent上添加old类属性
PS:关于jQuery中其他API,事件、Ajax……参考jQuery中文文档
JQuery中的设计模式
模仿jQuery实现其中的部分API后,也学习到了jQuery中各种优秀的设计模式,现在来简单总结一下。
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,简单来说就是对优秀的代码模板,起个专业的名字。
链式调用
每一步的jQuery操作,返回的都是一个jQuery对象,参考上文中的链式操作
函数重载
构造函数$()
支持多种参数
- 参数:HTML —— 创建元素
- 参数:选择器 —— 查找元素
下面的代码模拟了jQuery中重载的实现:
if (typeof selectorOrArrayOrTemplate === "string") {
if (selectorOrArrayOrTemplate[0] === "<") {
// 创建
elements = [createElement(selectorOrArrayOrTemplate)];
} else {
// 查找
elements = document.querySelectorAll(selectorOrArrayOrTemplate);
}
} else if (selectorOrArrayOrTemplate instanceof Array) {
elements = selectorOrArrayOrTemplate;
}
getter/setter
jQuery使用同一个API,根据接收参数的不同,来完成取值(getter)或赋值(setter)
适配器
jQuery针对不同浏览器使用不同代码
如下代码中:innerText是IE支持的DOM操作,textContent是其他浏览器支持的DOM操作
text(node, string) {
if (arguments.length === 2) {
if ('innerText' in node) { //适配不同的浏览器
node.innerText = string //ie
} else {
node.textContent = string //chrome/firefox
}
} else if (arguments.length === 1) {
if ('innerText' in node) { //适配不同的浏览器
return node.innerText
} else {
return node.textContent
}
}
}
别名
避免浪费内存,jQuery中把所有共有的API放在了jQuery.prototype(原型)中,并为其起了别名jQuery.fn
window.$ = window.jQuery
jQuery.fn = jQuery.prototype
并且可以用原型继承实现插件系统
$.fn.modal = function(){ ... }
$('#div1').modal()
用闭包来隐藏细节
对象中各种函数和获得的elements(元素)形成闭包,让用户只能通过函数来操作元素,隐藏了细节
不使用new的构造函数
通过直接调用函数,返回一个对象的方法来得到jQuery对象。