《jQuery基础教程》-- 操作DOM

1.操作属性

之前的css方法还有addClass、removeClass、toggleClass都是对DOM元素进行style属性的操作。而对于其他属性则可以使用attr和removeAttr来实现。

例如:

$('a[href*="wikipedia"]').attr({
		rel:'external',
		title:function(){
			return 'Learn more about ' + $(this).text() + ' from wikipedia.';
		},
		id:function(index, oldValue){
			return 'wikilink-' + index;
		}
});
这里指定了a标签的rel属性、title属性还有id属性,并使用值回调处理属性值。

另外,如果想要操作一些DOM属性(非HTML属性)则需要使用prop方法

prop方法的用法和attr方法没有什么不同,他们既支持一次性包含多个属性值的映射,同样也支持值回调。

2.DOM树操作

首先,先来看DOM元素的添加。要将一个DOM元素加入到一个DOM树中,所需要的步骤就是:a.创建这个DOM元素;b.将这个元素插入到已有的DOM树中。

如代码所示:

//创建2个a标签,并且插入到指定DOM位置
$('<a href="#top">back to top</a>').insertAfter('div.chapter');
$('<a id="top"></a>').prependTo('body');
这里首先使用$() 创建了两个a标签。然后分别使用insertAfter和prependTo,插入到已有的DOM树中。对应的插入方法有:

insertAfter、insertBefore 在现有元素外部的之后、之前加入

appendTo、prependTo 在现有元素内部的之后、之前加入

具体的DOM树操作还有更加复杂的方法,在开发中,我们常常要针对同一个环境$(this)对象做连缀操作。jQuery为我们提供了对应的反向插入方法:

after、before

append、prepend

这一组插入方法和之前的一组最大的区别可以理解为以……为主,将……插入到或者说是……不动,将……移动到。对比一下:

$a.appendTo($b) 表示,以b为主,将a插入到b的后面。(或者说 b 不动,将a移动到b后面)

$a.append($b) 表示,以a为主,将b插入到a后面。(或者说a不动,将b移动到a后面)

这样就可以对于同一个DOM对象进行操作,如下:

//移动元素
var $notes = $('<ol id="notes"></ol>').insertBefore('#footer');
$('span.footnote').each(function(index){
		$(this).before(['<a id="content_',index+1,'" href="#footnote_',index+1,'" class="context"><sup>',index+1,'</sup></a>'].join(''))
		.appendTo($notes).append(['<a href="#content_',index+1,'">(content)</a>'].join(''))
		.wrap('<li id="footnote_'+index+'"></li>');
});
这里使用join函数进行字符数组的链接,取代+号连字符有时所带来的不必要的麻烦。还有,有必要解释一下这里还使用到了wrap包装方法,将目标元素包装到li内。

3.复制元素

简单的说复制元素就是使用方法clone。使用这个方法需要注意的是,这个方法默认是不复制与元素一起绑定的事件的,如果需要一并复制所绑定的事件,需要加入参数true,如:$a.clone(true);

下面是一个综合使用复制元素和移动元素的例子:

//复制元素示例:加入侧边引用
$('span.pull-quote').each(function(index){
		var $parentParagraph = $(this).parent('p');
		$parentParagraph.css('position','relative');
		
		var $clonedCopy = $(this).clone();
		$clonedCopy.addClass('pulled')
			.find('span.drop').html('…').end()
			.text($clonedCopy.text())
			.prependTo($parentParagraph)
			.addClass('rounded-top')
			.wrapInner('<div class="rounded-bottom"></div>');
});
解释本例。首先通过clone获得了包含<span class="pull-quote">的段落<p>的一个副本。

接着为其套用pulled样式,

替换特定span的内容为...,

去掉特殊的text显示,

移动元素,

加入圆角样式,并把一个包装div加入到这个复制的元素内包装其内容。(其实CSS3提供了更加简便的呈现圆角+阴影的方法。参考css3学习)

4.其他DOM操作方法

替换:replaceWith()、replaceAll();

移除匹配元素:empty();

移除匹配元素以及其后代所有子元素:remove()、detach();

5.高级DOM操作方法--排序表格行

这里提到的表格行,是对于一个表格来说,使用本地javascript方法,将表格的全部tr行进行排序,达到某一列按照期望顺序呈现的目的。

主要使用的方法是sort方法。这里jQuery对象没有sort这类dom原生数组方法。所以切记要使用get来获得DOM元素。

如下例:(关键部位已经注释)

//通过index方法返回列索引
var column = $(this).index();
		
//使用get方法将jQuery对象转换为DOM节点数组
//转换的原因是要使用原生数组方法sort必须转换,另外‘>’号的作用是:仅匹配儿子辈,不匹配孙子辈
var rows = $table.find('tbody > tr').get();
//为rows添加字母排序
rows.sort(function(a, b){
			//获得传入的参数a的子元素的相应列td的文本值
			var keyA = $(a).children('td').eq(column).text();
			//将keyA值去掉首尾括号,并且大写。
			keyA = $.trim(keyA).toUpperCase();
			var keyB = $(b).children('td').eq(column).text();
			keyB = $.trim(keyB).toUpperCase();
			if(keyA > keyB)
			{
				return 1;
			}
			else if(keyA < keyB)
			{
				return -1;
			}
			return 0;
});
//遍历排序并加入tbody中
		$.each(rows, function(index, row){
			$table.children('tbody').append(row);
});
这种做法可以附加到比如表格标题th的a标签事件中。

当然这种排序方法的确实现了需求,但是速度还不是很理想。使用jQuery的data函数,可以将要排序的数据预存起来,使用起来就比较快捷了。如下

var rows = $table.find('tbody > tr').each(function(){
			var key = $(this).children('td').eq(column).text();
			//将tr中的相对应的td值使用data方法将计算结果(这里是获得key并且trim后并转为大写)为值,
			//附以键‘sortKey’保存到每个tr的jQuery对象中。
			$(this).data('sortKey',$.trim(key).toUpperCase());
		}).get();
		
		rows.sort(function(a, b){
			var keyA = $(a).data('sortKey');
			var keyB = $(b).data('sortKey');
			if(keyA > keyB)
			{
				return 1;
			}
			else if(keyA < keyB)
			{
				return -1;
			}
			return 0;
});
而这些都算是一种对于表格的预先计算,可以一定程度的提高表格排序的响应速度。以下例子则介绍了更多预先的额外计算,分别用于处理数字型、日期型、名字组合、排序方向等内容:

var $table = $('#t-1');
//使用slice方法跳过表格的第一个th元素。
var $headers = $table.find('thead th').slice(1);
$headers.each(function(){
		//储存keyType数据类型
		var keyType = this.className.replace(/^sort-/,'');
		$(this).data('keyType', keyType);
	}).wrapInner('<a href="#"></a>')
	.addClass('sort');
	
	//构造sortKeys方法,分别针对不同的类型的不同方法。
	var sortKeys = {
		alpha:function($cell){
			var key = $cell.find('span.sort-key').text() + ' ';
			key += $.trim($cell.text()).toUpperCase();
			return key;
		},
		numeric:function($cell){
			var num = $cell.text().replace(/^[^\d.]*/,'');
			var key = parseFloat(num);
			//将值为NaN的转换成0
			if(isNaN(key)){
				key = 0;
			}
			return key;
		},
		date:function($cell){
			//使用javascript原生Date对象的parse函数,用来构建日期对象。
			//由于本例$cell.text()不包含日期,所以前面加入‘1 ’
			var key = Date.parse('1 ' + $cell.text());
			return key;
		}
	};
	
	$headers.bind('click',function(event){
		event.preventDefault();
		var $header = $(this),
			column = $header.index(),
			keyType = $header.data('keyType'),
			sortDirection = 1;
		
		//判断sortKeys方法是否存在
		if(!$.isFunction(sortKeys[keyType])){
			return;
		}
		
		if($header.hasClass('sort-asc')){
			sortDirection = -1;
		}
		
		var rows = $table.find('tbody > tr').each(function(){
			var $cell = $(this).children('td').eq(column);
			//使用函数的数组表示法调用sortKeys[keyType]相应的函数。
			$(this).data('sortKey',sortKeys[keyType]($cell));
		}).get();
		
		rows.sort(function(a, b){
			var keyA = $(a).data('sortKey');
			var keyB = $(b).data('sortKey');
			if(keyA < keyB) return -sortDirection;
			if(keyA > keyB) return sortDirection;
			return 0;
		});
		
		$headers.removeClass('sorted-asc sorted-desc');
		$header.addClass(sortDirection==1?'sorted-asc':'sorted-desc');
		
		$.each(rows, function(index, row){
			$table.children('tbody').append(row);
		});
		
});
如上例,定义了一个sortKeys[keyType]方法,会根据keyType的不同而实现不同的排序内容:如alpha针对于名称、字符串排序;numeric针对于数字、单价等排序;date针对于日期排序这样。例子稍微有些复杂,不过不难理解。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值