写在前面
参考文献:莫振杰《从0到1:jQuery快速上手》
这期主讲DOM和事件,下面开始。
DOM基础
DOM对象,也就是文档对象模型。
DOM操作,可以理解为“元素操作”。
这里可以参考之前的JS。
下面复习一下:
DOM结构
DOM结构,也就是“树形结构”,所谓树形结构也就是使用“树节点”来表示页面中的每一个元素。
DOM结构,也被称为“DOM树”。
其中,html是树根,也叫做“根元素”。
树结构中的关系:兄弟元素、父子元素、以及其他祖孙元素。
常见的DOM操作
创建元素
插入节点
删除元素
复制元素
替换元素
包裹元素
遍历元素
为什么其他都是元素,只有插入是节点,而不是元素?
这是因为,节点包含元素、属性、文本三种节点。
插入操作,不仅可以插入元素,还可以插入文本。
下面,我们着重讲一下重点的,一些非重点,我就去掉了。
创建元素
在JQ中,我们可以使用字符串的形式来创建一个元素节点,也就是“<h1>这是标题</h1>”这种形式。
语法:
$().append(str)
你也可以直接使用字符串来替代str,效果都是一样的。
这里写str是为了更加方便理解,str是一个形参。
一般来说,我们在命名的时候,喜欢使用$字符来作为前缀,以区分参数。
创建其实很简单,下面说说插入操作。
插入节点
在JS中,插入节点只有appendChild()和insertBefore()两种方法。
但是,在JQ中,主要有以下四种方法:
prepend()和prependTo()
append()和appendTo()
before()和insertBefore()
after()和insertAfter()
这种方法其实都很简单,我们要根据字面意思去理解、记忆。
这8个方法,一共分为两大类,左边一类,右边一类,具体细节,我们展开说。
prepend()和prependTo()
先说前面那个,下同。
插入位置:开始处。
语法:
$(A).prepend(B)
$(A),这里指的是选取父元素A。
prepend(B),这里指的是要插入的子元素B。
为了方便理解,下面我还是用A元素表示父元素,B元素表示要插入的子元素。
语法:
$(B).prependTo(A)
$(B),这里指的是要插入的子元素B。
prependTo(A),这里指的是插入到A元素。
注意,插入和插入到的区别。
虽然两者的效果是一致的,但是还是有以下区别。
区别:
两者的操作对象是颠倒的。
第一个的操作对象是A,第二个的操作对象是B。
注意这个区别。
append()和appendTo()
插入位置:末尾处
语法:
$(A).append(B)
$(B).appendTo(A)
区别跟上面的是一样的,虽然操作对象不一样,但是都表示是在A元素内的末尾处插入B元素。
上面说的都是在元素内部插入,下面说一下在元素外部插入。
before()和insertBefore()
插入位置:定位元素的前面
定位元素是什么?先接着看。
语法:
$(A).before(B)
$(B).insertBefore(A)
上面说的定位元素就是A,这里的定位指的并不是position定位,而是指元素插入位置的定位。
两者的区别还是操作对象的不同。
after()和insertAfter()
插入位置:定位元素的后面
语法:
$(A).after(B)
$(B).insertAfter(B)
不展开说。
总结:
我们一般都是使用第二类,因为To的含义已经非常明确了。
删除元素
在JS中,删除元素有一种方法。
在JQ中,删除元素有三个方法:
remove()、detach()、empty()
这三个别看功能都是为了删除元素,但实际上,还是有着不小的区别的。
不过,这三个的语法却是出奇地一致:
$(要删除的对象).删除方法()
remove()
remove方法的使用:
$().remove()
调用方法后,会返回一个值——被删除的元素。
这跟数组中的哪些方法是一致的?
使用场景:
跟插入节点操作组合,可以实现两个元素的互换。
detach()
这个方法跟remove有相同点,也有不同点,下面展开说说。
相同点:
将某个元素及其内部所有内容删除。
不同点:
remove()方法用于彻底删除元素,不仅会删除元素,还会把元素绑定的事件删除掉。
detach()方法只会删除元素,不会删除元素的事件。
empty()
这个方法是三个方法里面最不一样的方法。
它是清空的意思,主要是用来清空某个后代元素。
清空某个后代元素是什么意思?
也就是,不会删除本身,只会删除后代元素。
复制元素
这个方法其实没什么好说的。
语法:
$().clone(bool)
bool表示布尔值,布尔值就两个取值,要么true,要么false。
true:复制元素,也复制元素的事件
false:复制元素,不复制元素的事件
这跟JS中的复制元素是不一样的,JS中的true和false表示的是是否复制后代元素。
替换元素
替换元素,其实主要有两种方法:
replaceWith()
replaceAll()
下面展开细说。
replaceWith()
语法:
$(A).replaceWith(B)
也就是,用B元素替换A元素。
replaceAll()
语法:
$(B).replaceAll(A)
注意:
操作对象不一样。
前面的操作对象是A,后面的操作对象是B。
包裹元素
包裹元素一共有三个方法:
wrap()
wrapAll()
wrapInner()
wrap()
语法:
$(A).wrap(B)
将A元素用B元素包裹起来,这个是包裹单个的。
wrapAll()
语法:
$(A).wrapAll(B)
将所有的A元素用B元素包裹起来。
注意,这里说的是所有A元素,就算A元素不是连续在一起的,也会被包裹在一起——会打乱原有顺序。
这两个效果都是包裹A元素本身,下面这个效果是不一样的:包裹A的内容。
wrapInner()
语法:
$(A).wrapInner(B)
使用B元素将A元素里的所有内容包裹起来。
也就是说,A>B>A的内容。
最后一个是遍历元素,这个是最重要的,一定要掌握好。
遍历元素
遍历操作是最常用的一个功能,在很多地方上我们都会用到遍历。
比如说,数组的遍历。
在JQ中,我们不需要使用for循环来遍历元素,而是使用特定语法进行遍历。
语法:
$().each(function(index, ele){
...
)
each方法的参数是一个函数,这个函数是匿名函数。
匿名函数里有两个参数,第一个是index,也就是我们常说的下标;第二个是当前遍历到的元素。
不过,这两个参数都是可选的,我们一般都默认index是必选的,因为我们可以使用this来替代ele。
如果需要退出循环,直接return false即可。
使用场景:
给每个li添加不同的背景颜色。
不过,这需要我们先做好一个数组。
跟使用:first-child有所区别。
至此,DOM基础已经讲完了,下面展开说说DOM进阶。
跟JS一样,DOM进阶主要讲的也是属性操作、以及CSS属性相关这些知识。
OK, now let's GO.
DOM进阶
属性操作
属性操作,指的是HTML属性,不是CSS属性(这个待会说)。
HTML属性操作一共有:
获取属性
设置属性
删除属性
prop()方法
前面三个好理解,就是对属性值进行操作。
后面这个是补充操作,主要作用是啥,往下看~
获取属性
既然你要操作属性值,就要先获取到这个属性值,才能对这个属性值进行设置、删除操作。
语法:
$().attr('属性名')
返回结果是属性值。
在JS中,我们的获取属性操作是啥?
设置属性
语法:
$().attr("属性名", "属性值")
$().attr( { "属性名1": "属性值1", "属性名2": "属性值2", ... } )
第一个是设置一个属性的属性值。
第二个是设置多个属性的属性值,采用的是键值对的对象方式传值。
删除属性
语法:
$().removeAttr("属性名")
跟JS一样,更多是用于整体控制元素的样式属性。
可以看出,这些非常简单。
下面这个就有点难度了,但是也不多。
prop()
其实在本质上,prop()和attr()是差不多的,都是用来获取、设置元素的HTML属性的。
但是,两者使用的场景是有区别的:
prop()方法更适合用于具有true和false两种取值的属性。
比如说,表单里面的checked、selected、disabled属性。
也就是说,prop()方法是对attr()方法的补充。
语法:
$().prop("属性名")
样式操作
样式操作,也就是CSS操作。
在JQ中,样式操作分为以下三种:
CSS属性操作
CSS类名操作
个别样式操作
下面一个一个说。
CSS属性操作
CSS属性操作其实还分为两个操作,也就是获取,然后再进行设置操作。
但是,归根结底都是对CSS属性值的操作。
获取CSS属性:
$().css("属性名")
设置CSS属性:
$().css("属性", "取值")
$().css( { "属性1": "取值1", "属性2": "属性2", ... } )
可以设置一个,也可以使用键值对的对象形式同时设置多个。
CSS类名操作:
什么是类名?
也就是说自己定义的一串CSS属性:
.class {
...
}
其中class就是类名。
从结构来看,CSS类名操作主要作用就是整体控制元素的样式。
在JQ中,CSS类名操作主要有以下三种:
添加、删除、切换类名
添加类名:
顾名思义,就是给获取到的JQ对象加上某个CSS类。
语法:
$().addClass("类名")
这个方法跟同时设置多个CSS属性是一致的,但是这个可读性更好。
删除类名:
语法:
$().removeClass("类名")
上面两个方法组合在一起,可以进行样式的切换,可以用于网页的深色模式的切换。
但是,有个更加简单的方法,那就是切换类名。
切换类名:
语法:
$().toggleClass("类名")
很多以为,这切换是在两个类名之间进行切换,但实际上完全不是。
这个切换是指切换类名的状态——存在与否。
如果toggle()方法检测到类名存在,就删除;否则,就添加。
犯迷糊:
如果我们想要获取设置CSS样式属性,该用什么方法?是用CSS属性操作呢,还是用CSS类名操作?
如果样式比较少,使用CSS属性操作。
如果样式比较多,使用CSS类名操作——需要事先准备好对应的CSS类。
个别样式操作
什么叫做个别样式操作呢?
那就是一些很特别的样式。
主要包含以下三种:
元素的宽高
元素的位置
滚动条的距离
这么一看,是不是两眼一黑?
元素的宽高:
其实我们可以使用css()方法来获取到元素的宽高的,只不过这个不大方便,所以就有了以下两类方法(宽度和高度):
width()和height()
innerWidth()和innerHeight()
outerWidth()和outHeight()
第一个我理解,但是后面两个,emm...下面展开说。
都知道盒子模型吧?
不知道的,可以去看CSS那篇,就专门说过,这里简单说一下:
一个盒子的构成:元素自身的宽高,padding、border、margin。
盒子模型主要分为两种:标准盒子模型,和怪异模式(IE盒子模型)。
至于什么是标准盒子模型,什么是怪异模式,建议去看CSS那篇。
补充:
什么是box-sizing呢?
box-sizing是CSS中的一个属性,主要是用来改变盒子模型的计算方式。
什么是content-box呢?什么是border-box?
content-box是box-sizing默认的,也就是只包括content区域——也就是元素的宽高。
border-box是另外一个常用的属性值,不仅包括content区域,还包括padding——背景,border——边框。
OK,补充完成,下面接着介绍。
width()方法,包括width(也就是content-box的宽度)。
innerWidth()方法,包括width和padding。
outerWidth()方法,包括width和padding、border(也就是border-box的宽度)。
高度是类似的,这里不展开讲。
值得注意的是,不管是什么方法,都没有包含外边距margin的,盒子模型也是如此。
获取和设置一个元素的宽高要怎么做?
$().width()
$().width(n)
第一个是获取,第二个是设置。
是的,获取和设置区别不大。
不过,要注意的是,n是一个正整数,而不是字符串——13px。
可以知道的是,获取宽度的返回值也是一个正整数。
高度是类似的,这里不展开讲。
元素的位置:
如何获取元素的位置?
offset()
postion()
offset()
$().offset().top
$().offset().left
offset()方法返回的是一个坐标对象,该对象有两个属性,这两个属性的返回值都是不带单位的数字。
top属性,表示获取元素相对于当前文档“顶部”的距离。
left属性,表示获取元素相对于当前文档“左侧”的距离。
注意参考对象。
position()
$().position().top
$().position().left
position()方法返回的是一个坐标对象,该对象有两个属性,这两个属性返回的都是一个不带单位的数字。
top属性,表示获取元素相对于最近被定位的祖先元素“顶部”的距离。
left属性,表示获取元素相对于最近被定位的祖先元素“左侧”的距离。
滚动条的距离:
滚动条距离有什么用?
作用可不小~
$().scrollTop() 获取滚动距离
$().scrollTop(n) 设置滚动距离,n是一个整数,表示n像素
主要用于获取元素相对于滚动条“顶边”的距离。
使用场景:回到顶部。
说完了属性操作、CSS操作,咱们接着说说内容操作。
内容操作
什么是内容操作?
或者说,什么是内容?
内容就是元素内的文本内容、值内容等。
内容操作就是对这些东西进行操作,共分为以下三种方法:
html()
text()
val()
html()
$().html() 获取
$().html("html内容") 设置
html()方法和innerHTML的效果是一样的。
只不过,html()方法是JQ中的方法,innerHTML是JS中的方法。
text()
$().text() 获取
$().text("文本内容") 设置
text()方法和innerText的效果是一样的。
只不过,text()方法是JQ中的方法,innerText是JS中的方法。
区别:
html()获取的是元素内部所有的内容
text()获取的是仅仅是文本内容
val()
这个方法是独属于表单元素的。
为什么?
因为表格元素的值都是通过value属性来定义的,所以我们不能通过html()和text()方法去获取。
$().val() // 获取
$().val("值内容") // 设置
写在最后
OK,以上就这节的内容了。
本来还想着写事件的,但是发现写完DOM已经接近6K字了...算了,下次吧。