jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解
本节说一下DOM操作模块里的包裹元素子模块,该模块可将当前匹配的元素替换指定的DOM元素,有如下方法:
- wrap(html) ;在每个匹配元素的外层添加一层DOM元素 ;该方法会遍历匹配元素集合,在每个元素上调用.wrapAll()方法 ;不同于wrapAll()的是该方法会在每个匹配元素外面都套一层html元素。
- wrapAll(html) ;会将html转化为一个DOM节点并放在第一个匹配元素的前面,再把其他匹配元素也依次放进去 ;html可以是html片段、选择器表达式、jQuery对象、DOM元素或函数,下同。
- wrapInner(html) ;在每个匹配元素的内容前后包裹HTML元素 ;该方法会遍历匹配元素集合,并通过调用方法.wrapAll()为每个匹配元素的所有内容包裹一段HTML结构。
- unwrap() ;移除匹配元素集合中每个元素的父标签,并把匹配元素留在父元素的位置上
举个栗子:
writer by:大沙漠 QQ:22969969
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<p>你好</p>
<p>Hello World</p>
<div>
<i>
<span>测试文本</span>
</i>
</div> <button id="b1">按钮1</button> <br/>
<button id="b2">按钮2</button><button id="b3">按钮3</button> <br/>
<button id="b4">按钮4</button><br/><button id="b5">按钮5</button>
<script>
b1.onclick=function(){$('p').wrap('<div></div>')} //内部将<div></div>转化为jQuery对象放到第一个匹配元素<p>你好</p>之前,再将匹配元素移动到该DOM节点内部 b2.onclick=function(){$('p').wrapAll('<div></div>')} //内部将<div></div>转化为jQuery对象放到第一个匹配元素<p>你好</p>之前,再将匹配元素移动到该DOM节点内部
b3.onclick=function(){$('p').wrapAll('<div><p></p></div>')} //如果含有子节点,则会将匹配元素移动到子节点里面 b4.onclick=function(){$('p').wrapInner('<div></div>')} //在每个匹配元素的内容前后添加一层DOM节点(包裹层) b5.onclick=function(){$('span').unwrap() } //移除每个匹配元素的父元素,并让匹配元素占有该节点位置
</script>
</body>
</html>
渲染如下:

对应的DOM树如下:

点击按钮1会在所有的P标签上加一个div父节点,如下:

点击按钮2将在第一个p标签前添加一个div,然后把所有p标签放到div之下,如下:

点击按钮3将在第一个p标签前添加一个div>p双层DOM,然后把所有p标签放到div之下,如下:

点击按钮4将在p标签内最外层嵌套一层div标签,如下:

点击按钮5将会去除 span的上一层DOM节点,如下:

如果再次点击,会将span的上一层DOM继续移除,直到遇到body节点为止
源码分析
wrapInner和wrap都是基于wrapAll实现的,wrapAll实现如下:
jQuery.fn.extend({
wrapAll: function( html ) { //在匹配的元素外面放置html元素。html参数可以是html片段、选择器表达式、jQuery对象、DOM元素或函数。
if ( jQuery.isFunction( html ) ) { //如果html是函数
return this.each(function(i) {
jQuery(this).wrapAll( html.call(this, i) ); //遍历匹配元素,在每个匹配元素上执行html函数,并用该函数的返回值作为参数迭代调用.wrapAll()函数。
});
}
if ( this[0] ) { //如果当前有匹配元素
// The elements to wrap the target around
var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); //将html转化为一个jQuery对象
if ( this[0].parentNode ) { //如果当前第一个匹配元素有父元素,
wrap.insertBefore( this[0] ); //则把创建的包裹元素插入第一个匹配元素之前。
}
wrap.map(function() { //遍历wrap元素
var elem = this; //elem是创建的包裹元素的引用
while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { //如果html里含有一个子节点
elem = elem.firstChild; //则重置elem为html的子节点,上面的按钮3会执行到这里
}
return elem;
}).append( this ); //这一行的this是当前匹配的jQuery对象,把每个匹配元素移动到插入的元素之后
}
return this;
},
})
wrapAll首先会把参数转化为一个jQuery对象,然后插入到当前第一个匹配元素的前面,最后以生成的jQuery对象为主句,调用append()将当前匹配匹配的所有元素添加到新生成的jQuery对象对应的DOM节点内部。对应上面的按钮2
wrap()实现如下:
jQuery.fn.extend({
wrap: function( html ) { //在每个匹配元素的外层添加一层DOM元素
var isFunction = jQuery.isFunction( html ); //在每个匹配元素前后包裹一段HTML结构,该方法会遍历匹配元素集合,在每个元素上调用.wrapAll()方法。
return this.each(function(i) {
jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); //依次调用wrapALl()函数
});
},
})
wrapInner的实现如下:
jQuery.fn.extend({
wrapInner: function( html ) { //用于在匹配元素集合中每个元素的内容前后包裹一段HTML结构,该方法会遍历匹配元素集合
if ( jQuery.isFunction( html ) ) { //如果html是函数
return this.each(function(i) {
jQuery(this).wrapInner( html.call(this, i) ); //遍历匹配元素,在每个匹配元素上执行html函数,并用该函数的返回值作为参数迭代调用.wrapInner()函数。
});
}
return this.each(function() { //遍历匹配元素集合
var self = jQuery( this ),
contents = self.contents(); //先获取所有子节点
if ( contents.length ) { //如果有子节点
contents.wrapAll( html ); //调用wrapAll(html)为当前元素的所有内容包裹一段HTML代码。
} else {
self.append( html ); //如果当前元素没有内容,则直接将参数html插入当前内容。
}
});
},
})
unwrap的实现如下:
Query.fn.extend({
unwrap: function() { //移除匹配元素集合中每个元素的父标签,并把匹配元素留在父元素的位置上
return this.parent().each(function() { //先遍历父节点
if ( !jQuery.nodeName( this, "body" ) ) { //如果不是body元素
jQuery( this ).replaceWith( this.childNodes ); //则调用replaceWith将this.childNodes替换为this,注意,这里的this上下文是父节点
}
}).end();
}
})
jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解的更多相关文章
- jQuery 源码解析(二十五) DOM操作模块 html和text方法的区别
html和text都可以获取和修改DOM节点里的内容,方法如下: html(value) ;获取匹配元素集合中的一个元素的innerHTML内容,或者设置每个元素的innerHTML内容, ...
- jQuery 源码解析(二十八) 样式操作模块 scrollLeft和scrollTop详解
scrollLeft和scrollTop用于获取/设置滚动条的,如下: scrollLeft(val) ;读取或设置整个页面的水平滚动条距离 scrollTop(val) ;读取或设置整个页面的垂直滚 ...
- jQuery 源码解析(二十六) 样式操作模块 样式详解
样式操作模块可用于管理DOM元素的样式.坐标和尺寸,本节讲解一下样式相关,样式操作通过jQuery实例的css方法来实现,该方法有很多的执行方法,如下: css(obj) ;参数 ...
- jQuery 源码解析(二十九) 样式操作模块 尺寸详解
样式操作模块可用于管理DOM元素的样式.坐标和尺寸,本节讲解一下尺寸这一块 jQuery通过样式操作模块里的尺寸相关的API可以很方便的获取一个元素的宽度.高度,而且可以很方便的区分padding.b ...
- jQuery 源码解析(二十二) DOM操作模块 复制元素 详解
本节说一下DOM操作模块里的复制元素子模块,该模块可以复制一个DOM节点,并且可选择的设置是否复制其数据缓存对象(包含事件信息)和是否深度复制(子孙节点等),API如下: $.clone(elem, ...
- jQuery 源码分析(二十) DOM操作模块 插入元素 详解
jQuery的DOM操作模块封装了DOM模型的insertBefore().appendChild().removeChild().cloneNode().replaceChild()等原生方法.分为 ...
- jQuery 源码解析(二十三) DOM操作模块 替换元素 详解
本节说一下DOM操作模块里的替换元素模块,该模块可将当前匹配的元素替换指定的DOM元素,有两个方法,如下: replaceWith(value) ;使用提供的新内容来替换匹配元素集合中的每个元 ...
- jQuery 源码分析(二十一) DOM操作模块 删除元素 详解
本节说一下DOM操作模块里的删除元素模块,该模块用于删除DOM里的某个节点,也可以理解为将该节点从DOM树中卸载掉,如果该节点有绑定事件,我们可以选择保留或删除这些事件,删除元素的接口有如下三个: e ...
- jquery源码解析:proxy,access,swap,isArraylike详解
jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的. jQuery.extend({ ...... guid: 1, //唯一标识符 ...
随机推荐
- 在MySQL中group by 是什么意思
mysql语法中group by是什么意思? 在百度中搜索半天,最后找到一篇解释比较好的(不是博文,是百度知道,很郁闷那么多网友怎么就没人解释的清楚),链接如下: http://zhidao.baid ...
- C#8.0中新特性之一:结构readonly成员
结构struct成员支持readonly,用来限制被其修饰的成员不会改变结构的内部状态.加上7.2版本添加的readonly struct和ref readonly方法返回以及之前的字段声明修饰作用, ...
- canves做的时钟目前已经开源
canves做的时钟目前已经开源 git地址: https://github.com/jidanji/canves-clock/tree/1.0.1 项目截图 时流过的时间变得有颜色,其他的没有颜色.
- html和css的基本功
1.块级元素和行内元素和行内块元素的区别 块级元素:独占一行的,可以设置宽高和内外边距的(<div>/<h1>~<h6>/<p>/<ul>/ ...
- 基于STM32的无损压缩算法miniLZO移植,压缩率很高,20KB随机数压缩到638字节,耗时275us
说明: 1.miniLZO是采用C编写的无损压缩库. 2.提供了快速压缩和超快速解压缩能力. 3.比较耗内存,需要64KB内存用于压缩,对于H7这种大内存的,非常合适.或者有外置SRAM/SDRAM的 ...
- Python活力练习Day3
Day3:请输入星期几的第一个字母来判断是星期几,如果第一个字母一样,则继续判断第二个字母. #这是一道典型的题,一次输入一个字母,首字母匹配一个list里的内容.如果匹配到多个,再输入并匹配第二个字 ...
- IT兄弟连 HTML5教程 CSS3属性特效 自定义文字
字体使用是网页设计中不可或缺的一部分.经常地,我们希望在网页中使用某一特定字体,但是该字体并非主流操作系统的内置字体,这样用户在浏览页面的时候就有可能看不到真实的设计.美工设计师最常做的办法是把想要的 ...
- Css里的box-shadow的值分别代表什么
以下为例: box-shadow:1px 2px 3px 4px color inset; 1px:表示沿x轴的正方向的长度(如果是负数,则为沿x轴的负方向的长度); 2px:表示沿y轴的正方向的长度 ...
- UWP 在非UI线程中更新UI
大家都知道,不可以在 其他线程访问 UI 线程,访问 UI 线程包括给 依赖属性设置值.读取依赖属性.调用方法(如果方法里面修改了依赖属性)等.一旦访问UI线程,那么就会报错,为了解决这个问题,需要使 ...
- PLSQL设置查询快捷键
Tools-->Preferences-->User Interface-->Editor-->AutoReplace 新建文本文件shortcut.txt(名称和路径可以自定 ...