06-操作元素
19.5 操作元素
现在已经有了一些jQuery对象,可以用它们做什么呢?使用jQuery可以很容易的添加和移除元素。熟悉这些例子的最好方式就是在浏览器中加载示例中的HTML,并在控制台中执行它们。准备好不断重新加载文件吧!接下来会有很多移除、添加和修改内容的操作。
jQuery提供的text和html方法分别等同于对DOM元素的textContent和innerHTML属性进行赋值。例如,将每个段落替换成相同的文本:
$('p').text('ALL PARAGRAPHS REPLACED');
同样地,可以调用html方法来使用HTML的内容:
$('p').html('<i>ALL</i> PARAGRAPHS REPLACED');
这里蕴含了jQuery的一个重要知识点:jQuery可以很容易地一次性操作多个元素。虽然在使用DOM API时,document.querySelectorAll()也会返回多个元素,但是依然要手动遍历它们,才能执行一些操作。而jQuery会处理所有的迭代工作,它会默认假定要对jQuery对象中的每个元素都执行操作。那么,如果只想修改第三个段落怎么办?jQuery提供了eq方法,通过它可以获得一个包含单个元素的新的jQuery对象:
$('p') // 匹配所有段落
.eq(2) // 第三个段落 (下标从0开始)
.html('<i>THIRD</i> PARAGRAPH REPLACED');
要移除元素,调用jQuery对象的remove方法即可。下面的代码可以移除所有段落:
$('p').remove();
上例演示了jQuery开发中另一个重要的范式:链式调用。由于所有jQuery方法都返回了一个jQuery对象,这样一来,就可以像刚才那样进行链式调用。链式调用是一种非常强大且简洁的多元素操作方式。
jQuery提供了很多添加内容的方法。其中一个是append,它只是简单地往jQuery对象中的每个元素追加所提供的内容。比如,如果想给每个段落添加脚注,只要这样做:
$('p')
.append('<sup>*</sup>');
append会给所有匹配的元素添加一个子节点,还可以使用before或after来插入兄弟节点。下面看一个例子,它给每个段落的前、后分别添加
:
$('p')
.after('<hr>')
.before('<hr>');
与这些插入方法对应,appendTo、insertBefore和insertAfter这些方法颠倒了插入顺序,它们在一些特定的场景中非常有用,来看个例子:
$('<sup>*</sup>').appendTo('p'); // 等同于 $('p').append('<sup>*</sup>')
$('<hr>').insertBefore('p'); // 等同于$('p').before('<hr>')
$('<hr>').insertAfter('p'); // 等同于$('p').after('<hr>');
jQuery也可以很容易的修改元素的样式。比如,使用addClass添加一个class、removeClass可以移除class,或者用 toggleClass (如果元素当前不包含指定class,就添加,反之移除)来切换class。另外,可以直接使用css方法来操作样式。后续还会介绍:even和:odd选择器,可以用来间隔地选择元素。例如,如果想让段落间隔地变成红色,可以这么做:
$('p:odd').css('color', 'red');
在jQuery链中,有时候需要从匹配的元素中选出一个子集。前面已经知道使用eq方法可以将jQuery对象缩减至一个元素,不过还可以使用filter、not和find修改选中的元素。filter会将集合缩减至符合选择器的元素。例如,可以先在调用链中修改每个段落,再用filter将段落间隔地变成红色:
$('p')
.after('<hr>')
.append('<sup>*</sup>')
.filter(':odd')
.css('color', 'red');
not实际上是反选filter。例如,如果想在每个段落之后添加一个
,然后给那些不包含highlight这个class的段落加上缩进:
$('p')
.after('<hr>')
.not('.highlight')
.css('margin-left', '20px');
最后,find会返回一个符合查询条件并且包含所有子元素的元素集合(不像filter会过滤现有的集合)。例如,想在每个段落之前添加一个
,然后再将具有code这个class的元素字体放大(在这个例子中,这些元素是段落的子节点):
$('p')
.before('<hr>')
.find('.code')
.css('font-size', '30px');