DOM操作分类
一般来说,DOM操作分为3个方面,即DOM Core、HTML-DOM、CSS-DOM。
DOM Core
DOM Core不专属于JavaScript,任何一种支持DOM的程序设计语言都可以使用它。它的用途并非仅限于处理网页,也可以用来处理任何一种使用标记语言编写出来的文档,例如XML。
JavaScript中的getElementById(),getElementsByTagName(),getAttribute(),setAttribute()等方法,这些都是DOM Core的组成部分。
HTML-DOM
在使用JavaScript和DOM为HTML文件编写脚本时,有许多专属于HTML-DOM的属性。HTML-DOM的出现甚至比DOM Core还要早,它提供了一些更简明的记号来描述各种HTML元素的属性。
使用HTML-DOM来获取某元素的src属性的方法;
element.src
CSS-DOM
CSS-DOM是针对CSS的操作。在JavaScript中,CSS-DOM技术的主要作用是获取和设置style对象的各种属性。通过改变style对象的各种属性,可以使网页呈现不同的效果。
设置某元素style对象字体颜色的方法;
element.style.color = "red";
jQuery作为JavaScript库,继承并发扬了JavaScript和DOM对象的操作的特性。
HTML:
你最喜欢的水果是?
- 苹果
- 橘子
- 菠萝
jQuery——查找节点
查找元素节点
var $li = $("ul li:eq(1)"); // 获取里第二个- 节点
var li_txt = $li.text(); // 获取上例节点的文本内容
console.log(li_txt); // 打印文本内容
以上代码获取了
- 元素内第二个
- 节点,并将它的文本内容
橘子
打印出来。查找属性节点
查找到需要的元素之后,就可以利用attr()方法获取它的各种属性的值,attr()方法的参数可以是一个,也可以是两个。当参数是一个时,则是要查询的属性的名字。获取属性节点并打印出它的文本内容
var $para = $("p"); var p_text = $para.attr("title"); console.log(p_text); // 选择你最喜欢的水果.
jQuery——创建节点
创建元素节点
需求:- 创建两个
- 新元素
- 将这两个新元素插入文档中。
$(html);
$(html)方法会根据传入的HTML标记字符串,创建一个DOM对象,并将这个DOM对象包成一个jQuery对象后返回。首先创建两个li元素:
var $li_1 = $(""); var $li_2 = $("");
然后将这个两个新元素插入文档中,可以使用append()等方法。
$("ul").append($li_1); // 添加到
- 节点中
$("ul").append($li_2); // 可以采用链式写法:$("ul").append($li_1).append($li_2);
- 动态创建的新元素节点不会被自动添加到文档中,而是需要使用其他方法将其插入文档中。
- 当创建单个元素时,要注意闭合标签和使用标准的XHTML格式。
创建文本节点
var $li_1 = $("
- 香蕉
"); var $li_2 = $("- 雪梨
");创建属性节点
创建属性节点与创建文本节点类似,也是直接在创建元素节点时一起创建。var $li_1 = $("
- 香蕉
"); var $li_2 = $("- 雪梨
");
jQuery——插入节点
- append():向每个匹配的元素内部追加内容
html
我想说:
jquery
$("p").append("你好"); //
我想说:你好
- appendTo():将所有匹配的元素追加到指定的元素中。实际上,使用该方法是颠倒了常规的$(A).append(B)的操作,即不是将B追加到A中,而是将A追加到B中。一个是A添加?,一个是将?添加到A中。
html
我想说:
jquery
$("你好").appendTo("p");
效果同上
- prepend():向每个匹配的元素内部前置内容
$("p").prepend("你好"); // 你好我想说:
- prependTo():将所有匹配的元素前置到指定元素中。
$("你好").prependTo("p"); // 你好我想说:
- after():在每个匹配的元素之后插入内容
$("p").after("你好"); //
我想说:
你好注意:和append()注意区分,append()是在匹配的元素内部追加内容,after()是在匹配的元素之后追加内容。
- insertAfter():将所有匹配的元素插入到指定元素后面。
$("你好").insertAfter("p"); //
我想说:
你好- before():在每个匹配的元素之前插入内容。
$("p").before("你好"); // => 你好
我想说:
- insertBefore():将所有匹配的元素插入到指定的元素前面。
$("你好").insertBefore("p"); // => 你好
我想说:
jQuery——删除节点
remove()
作用是从DOM中删除所有匹配的元素,传入的参数用于根据jQuery表达式来筛选元素。- 苹果
- 橘子
- 菠萝
例如我们要删除橘子这个
- 元素节点
$("ul li:eq(1)").remove();
这样,橘子就“消失“了。
**当某个节点用remove()方法删除后,该节点所包含的所有后代节点将同时被删除。这个方法的返回值是一个指向已被删除的节点的引用,因此可以在以后再使用这些元素。
var $li = $("ul li:eq(1)").remove(); $($li).appendTo("ul");
删除的li返回后,用变量保存,在将他appendTo到ul元素的末尾。
另外,remove方法也可以通过传递参数来选择性的删除元素。
$("ul li").remove("li[title='菠萝']"); // 将
- 元素中属性title为菠萝的li元素删除
detach()
detach()和remove()一样,也是从DOM中去掉所有匹配的元素,但需要注意的是,这个方法不会把匹配的元素从jQuery对象中删除,因而可以在将来在使用这些匹配的元素。与remove()不同的是,所有绑定的事件、附加的数据等都会保留下来。$("ul li").click(function() { alert($(this).html()); }) var $li = $("ul li:eq(1)").detach(); $li.appendTo("ul");
首先给每个li元素都绑定了一个事件处理程序,然后我们删除第二个li元素,又将它appendTo到li元素里的末尾,此时,这最后一个li元素的事件处理程序,依旧可以响应,但是如果换成remove()就不行了。
empty()
严格来讲,empty()方法并不是删除节点,而是清空节点,而是清空节点,它能清空元素中的所有后代节点。$("ul li:eq(1)").empty(); // 获取第二个
- 元素节点后,清空此元素里的内容,注意,是元素里。
jQuery——复制节点
复制节点也是常用的DOM操作之一,比如一些购物网站,用户的鼠标拖动商品并放入购物车等操作,这个商品拖动就是用的复制节点,将用户选择的商品所处的节点复制一次,并将其随鼠标移动,从而达到效果。
继续沿用前面的例子:
- 苹果
- 橘子
- 菠萝
$("ul li").click(function() { $(this).clone().appendTo("ul"); })
但是,被复制的新元素不具有任何行为。如果需要新元素也具有复制功能(本例是单击事件),可以使用如下jQuery代码;
$("ul li").click(function() { $(this).clone(true).appendTo("ul"); })
参数:true,含义是复制元素的同时复制元素中所绑定的事件。因此该元素的副本也同样具有被复制元素的事件处理程序。
jQuery——替换节点
如果要替换某个节点,jquery提供了相应的方法,即
replaceWith()
和replaceAll()
。replaceWith()
作用是将所有匹配的元素都替换成指定的HTML或者DOM元素。$("p").replaceWith("你最不喜欢的水果是?");
也可以使用jQuery中另一个方法replaceAll()来实现,该方法与replaceWith()方法的作用相同,只是颠倒了replaceWith()操作。
$("你最不喜欢的水果是?").replaceAll("p");
同样的效果。
注意:如果在替换之前,已经为元素绑定事件,替换后原先绑定的事件将会与被替换的元素一起消失,需要在新元素上重新绑定事件。
jQuery——包裹节点
1. wrap()
如果要将某个节点用其他标记包裹起来,jQuery提供了相应的方法,即wrap(),该方法对于需要在文档中插入额外的结构化标记非常有用,而且它不会破坏原始文档的语义。
$("strong").wrap(""); // 用标签把元素包裹起来
得到的结果:
你最喜欢的水果是?
2. wrapAll()
该方法会将所有匹配的元素用一个元素来包裹。它不同与wrap()方法,wrap()方法是将所有的元素进行单独的包裹。为了使效果更突出,在网页中在加入一个元素。
你最喜欢的水果是? 你最喜欢的水果是?
- 苹果
- 橘子
- 菠萝
如果使用wrap()方法包裹元素,jQuery代码如下:
$("strong").wrap("");
得到如下结果:
使用wrapAll()包裹元素,jQuery代码如下:
$("strong").wrapAll("");
3. wrapInner()
该方法将每一个匹配的元素的子内容(包括文本节点)用其他结构化的标记包裹起来。$("strong").wrapInner("");
jQuery——属性操作
在jQuery中,用attr()方法来获取和设置元素属性,removeAttr()方法来删除元素属性。
1. 获取属性和设置属性
获取元素的属性title:
var $para = $("p"); var p_txt = $para.attr("title");
如果要设置
元素的属性title的值,也可以使用同一个方法,不同的是,需要传递两个参数即属性名称和对应的值。
$("p").attr("title","your title"); // 设置单个的属性值
如果需要一次性为同一个元素设置多个属性,可以使用下面的代码:
$("p").attr({"title":"your title","name":"test"}); // 将一个key/value形式的对象设置为匹配元素的属性
注意:jQuery中的很多方法都是用一个函数实现获取(getter)和设置(setter)的,例如上面的attr()方法,既能设置元素属性的值,也能获取元素属性的值。类似的还有html(),text(),height(),width(),val()和css()等方法。
2. 删除属性
在某些情况下,需要删除文档中某个元素的特定属性,可以使用removeAttr()方法来完成该任务。如果需要删除
元素title属性。
$("p").removeAttr("title");
jQuery——样式操作
1. 获取样式和设置样式
你最喜欢的水果是?
在上面的代码中,class也是
元素的属性,因此获取class和设置class都可以使用attr()方法来完成。
例如使用attr()方法来获取
元素的class:
var p_class = $("p").attr("class");
也可以使用attr()方法来设置
元素的class:
$("p").attr("class","high"); // 设置
元素的class为"high"
2. 追加样式:addClass()
jquery提供了专门儿的addClass()方法来追加样式。
$("p").addClass("another");
3. 移除样式:removeClass()
$("p").removeClass("high");
如若要移除多个样式,可:
$("p").removeClass("high high2 ...");
4. 切换样式:toggleClass()
$("p").toggleClass("another");
4. 判断是否含有某个样式:hasClass()
$("p").hasClass("another");
是返回true,否返回false。
jQuery——设置和获取HTML、文本和值
1. html()
此方法类似于JavaScript中的innerHTML属性,可以用来读取或者设置某个元素中的HTML内容。$("p").html(); // 你最喜欢的水果是?
如果要设置某元素的HTML代码,那么也可以使用该方法,不过需要为它传递一个参数。
$("p").html("你最喜欢的水果是?");
html()可以获得选择元素的字元素HTML字符串,但不能获得其本身。
- 1
- 2
- 3
- 4
console.log($("ul").html()); /*
- 1
- 2
- 3
- 4
*/不能获得
- 元素本身的HTML内容。
如果需要,可以这样:
console.log($("ul").prop("outerHTML")); /*
- 1
- 2
- 3
- 4
使用
prop("outerHTML")
属性。2. text()
此方法类似于JavaScript中的innerText属性,可以用来读取或者设置某个元素中的文本内容。- 当该方法用于返回一个值时,它会返回所有匹配元素的组合的文本内容(会删除 HTML 标记)。
- 当该方法用于设置值时,它会覆盖被选元素的所有内容。
栗子1
- 1
- 2
- 3
- 4
console.log($("ul").text()); /* 1 2 3 4 */
栗子2
this is p1
this is p2
console.log($("p").text()); /* this is p1this is p2 */
如果需要为其设置文本内容,那么也需要传递一个参数。
this is p1
this is p2
3. val()
此方法类似于JavaScript中的value属性,可以用来设置或获取元素的值。无论元素是文本框,下拉列表还是单选框,他都可以返回元素的值。如果元素为多选,返回一个包含所有选择的值的数组。HTML:
当地址框获取鼠标焦点时,如果地址框的值为"请输入邮箱地址",则将地址框中的值清空。
$("#address").focus(function() { var txt_value = $(this).val(); if (txt_value == "请输入邮箱地址") { $(this).val(""); } });
当地址框失去鼠标焦点时,如果地址框内容为空,则将地址框的值设置为:请输入邮箱地址。
$("#address").blur(function() { var txt_value = $(this).val(); if (txt_value == "") { $(this).val("请输入邮箱地址"); } });
- focus()方法相当于onfocus()方法,处理获得焦点时的事件。
- blur()方法相当于onblur()方法,处理失去焦点时的事件。在这个例子中,也可以使用表单元素的defaultValue属性来实现同样的功能。defaultValue属性包含该表单元素的初始值。
$("#address").focus(function() { // 地址框获取鼠标焦点 var txt_value = $(this).val(); // 得到当前文本框的值 if (txt_value == this.defaultValue) { // 使用defaultValue值 $(this).val(""); // 如果符合条件,则清空文本框内容 } }) $("address").blur(function() { // 地址框失去鼠标焦点 var txt_value = $(this).val(); // 得到当前文本框的值 if (txt_value == "") { $(this).val(this.defaultValue); // 如果符合条件,则设置内容 } })
val()方法不仅能设置元素的值,同时也能获取元素的值。另外,val()方法还有另外一个用处,就是它能使select,checkbox,radio相应的选项被选中。
来看一个栗子:
多选1 多选2 多选3 多选4 单选1 单选2 单选3
其中一些元素是默认选中的,可以通过val()方法来改变它们的选中项。如,使第1个下拉框的第二项被选中:
$("#single").val("选择2号");
jQuery——遍历节点
1. children()
该方法用于取得匹配元素的子元素集合。你最喜欢的水果是?
- 苹果
- 橘子
- 菠萝
var $body = $("body").children(); // 元素下的子元素个数 var $p = $("p").children(); //
元素下的子元素个数 var $ul = $("ul").children(); //
- 元素下的子元素个数
for (var i=0;i<$ul.length;i++) { // 循环输出
- 元素的HTML内容 console.log($ul[i].innerHTML); } // 苹果 // 橘子 // 菠萝
注意:children()方法只考虑子元素而不考虑后代元素
2. next()
该方法用于取得匹配元素后面紧邻的同辈元素var $p1 = $("p").next(); // 取得紧邻
元素后的同辈元素
得到
- 元素。
3. prev()
该方法用于取得匹配元素前面紧邻的同辈元素。你最喜欢的水果是?
- 苹果
- 橘子
- 菠萝
$("ul").prev(); // 取得紧邻
- 元素前的同辈元素
按照HTML,我们将会取到
元素。
4. siblings()
该方法用于取得匹配元素前后所有的同辈元素$("p").siblings(); // 取得
元素的同辈元素
按照上例的HTML结构,将会取到
- 元素。
- 元素添加颜色:
$(document).bind("click",function(e) { $(e.target).closest("li").css("color","red"); })
jQuery——CSS-DOM操作
CSS-DOM技术简单来说读取和设置style对象的各种对象。style属性很有用,但最大不足是无法通过它来提取到通过外部CSS设置的样式信息,然而在jQuery中,这些都是非常的简单。
可以直接利用css()方法获取元素的样式属性,jQuery代码如下:
$("p").css("color"); // 获取
元素的样式颜色
无论color属性时外部CSS导入,还是直接内联,css()方法都可以获取到属性style里的其他属性的值。
也可以直接利用css()参数设置某个元素的单个样式。
$("p").css("color","red");
与attr()方法一样,css()方法也可以同时设置多个样式属性:
$("p").css({"fontSize":"30px","backgroundColor":"#888"});
- 如果值是数字,将会自动转化为像素值
- 在css()方法中,如果属性中带有
-
符号,例如font-size和background-color属性,如果在设置这些属性的值的是偶不带引号,那么就要使用驼峰式写法。$("p").css({fontSize : "30px",backgroundColor : "#888"});
建议加上引号。
opacity()
对透明度的设置,可以直接使用opacity属性,jQuery已经处理好了兼容性的问题:$("p").css("opacity","0.5");
如果要获取某个元素的height属性,则可以:
$(element).css("height");
height()
在jQuery中还有另外一种方法也可以获取元素的高度,即height(),作用是取得匹配元素当前计算的高度之(px)。$("p").height();
height()方法也用于设置元素的高度,如果传递的值是一个数字,则默认单位为px。如果要用其他单位,则必须传递一个字符串。
$("p").height(100); // 100px $("p").height("10em"); // 10em
width()
取得匹配元素宽度值(px)。$("p").width();
同样的,width()也能用来设置元素宽度。
$("p").width("400px");
此外,CSS-DOM中,关于元素定位还有以下几个经常使用方法。
offset()
作用是,获取元素在当前视窗的相对偏移,其中返回的对象包含两个属性,即top和left,他只对可见元素有效。例如用它来获取元素的偏移量。
var offset = $("p").offset(); var left = offset.left; var top = offset.top;
position()
获取元素相对于最近一个position样式属性为relative或者absolute的祖父节点的相对偏移,与offset()一样,返回的对象也包括两个属性,即top和left。var position = $("p").position(); var left = position.left; var top = position.top;
scrollTop() or scrollLeft()
获取元素的滚动条距顶端的距离和距左侧的距离。var $p = $("p"); var scrollTop = $p.scrollTop(); var scrollLeft = $P.scrollLeft();
另外,可以为这两个方法指定一个参数,控制元素的滚动条滚动到指定位置。
$("textarea").scrollTop(300); // 元素的垂直滚动条滚动到指定的位置 $("textarea").scrollLeft(300); // 元素的横向滚动条滚动到指定的位置
案例
在现代浏览器中,超链接自带了超链接提示,只需在title标签中加入title属性就好了。
提示
然而这个提示效果的响应速度是非常缓慢的,考虑到良好的人机交互,需要的是当鼠标移动到超链接的那一瞬间就出现提示,这时就需要移除标签中的title提示效果。
然后为class为tooltip的超链接添加mouseover和mouseout事件。
$("a.tooltip").mouseover(function() { // show title }).mouseout(function() { // hide title });
- 当鼠标滑入超链接
- 创建一个div元素,div元素内容为title属性的值
- 为创建的元素追加到文档中
- 为它设置x坐标,y坐标,使它显示在鼠标位置的旁边
- 当鼠标划出超链接时,移除div元素。
$(function() { $("a.tooltip").mouseover(function(e) { var tooltip = "
" + this.title + ""; $("body").append(tooltip); $("#tootip").css({ "top" : e.pageX + "px", "left" : e.pageY + "px" }).show("fast"); }).mouseout(function() { $("#tooltip").remove(); }) })此时效果又有两个问题,首先是,鼠标滑过之后,标签中的title属性的提示也会出现;其次,是设置x,y坐标的问题,由于自制的提示与鼠标的距离抬进,有时候会引起无法提示的问题(鼠标焦点变化引起mouseout事件)。
- 当鼠标滑入时,给对象添加一个新属性,并把title的值传给这个属性,然后清空title的值。
this.myTitle = this.title; this.title = ""; var tooltip = "
" + this.myTitle + "";- 当鼠标滑出时,再把对象的myTitle的值赋给属性title。
this.title = this.myTitle;
为了解决自制提示和鼠标的距离太近导致的无法提示问题,需要重新设置元素的top和left的值。
var x = 10; var y = 20; $("#tooltip").css({ "top" : (e.pageY+y) + "px", "left" : (e.pageX+x) + "px" })
此时,鼠标滑入和滑出显示已经没问题了,但当鼠标在超链接上移动时,提示效果并不会跟着鼠标移动,如果需要提示效果跟随鼠标移动,可以为超链接加上一个mousemove事件。
$("a.tootip").mousemove(function(e) { $("#tooltip").css({ "top" : (e.pageY+y) + "px", "left" : (e.pageX+x) + "px" }); })
5. closet()
该方法用于取得最近的匹配元素。首先检查当前元素是否匹配,如果匹配则直接返回元素本身。如果不匹配则向上查找父元素,逐级向上直到找到匹配选择器的元素。如果什么都没找到则返回一个空的jQuery对象。比如,给点击的目标元素的最近的