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, //唯一标识符 ...
随机推荐
- poj 3241 Object Clustering (曼哈顿最小生成树)
Object Clustering Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 2640 Accepted: 806 ...
- 从《彩色圆环》一题探讨一类环上dp的解法
清橙A1202 bzoj2201 bsoj4074 试题来源 2010中国国家集训队命题答辩 问题描述 小A喜欢收集宝物.一天他得到了一个圆环,圆环上有N颗彩色宝石,闪闪发光.小A很爱惜这个圆环,天天 ...
- B站上传字幕问题解决
博客:blog.shinelee.me | 博客园 | CSDN B站上传字幕时,如果srt文件中出现如下空行,则会报错,仅上传了空行前的部分 于是写了个python脚本,如下: import pys ...
- 剑指offer笔记面试题2----实现Singleton模式
题目:设计一个类,我们只能生成该类的一个实例. 解法一:单线程解法 //缺点:多线程情况下,每个线程可能创建出不同的的Singleton实例 #include <iostream> usi ...
- Javascript继承的问题
说到Javascript的继承,相信只要是前端开发者都有所了解或应用,因为这是太基础的知识了.但不知各位有没有深入去理解其中的玄机与奥秘.今本人不才,但也想用自己的理解来说一说这其中的玄机和奥秘. 一 ...
- 利用keras自带路透社数据集进行多分类训练
import numpy as np from keras.datasets import reuters from keras import layers from keras import mod ...
- ubuntu 18.04 安装并配置adb
获取最新的adb包 wget https://dl.google.com/android/repository/platform-tools-latest-linux.zip 将软件包解压到指定位置 ...
- xms新版发布
基于.net core 3.0.101 github地址: https://github.com/migomiddle/xms 码云地址: https://gitee.com/migomiddle/x ...
- 耐人寻味的CSS属性font-family
font-family是一个网站用户体验的第一入口,非常有必要花功夫来研究一下.我们首先需要了解衬线字体和无衬线字体,接着了解中英文的常用字体及其适用性. 衬线字体 衬线(serif)的笔画有粗有细的 ...
- How to: Recompile the Business Class Library 如何:重新编译业务类库
The eXpressApp Framework supplies the Business Class Library that consists of three assemblies. eXpr ...